The following is my sample code:

String month = "09";

String year = "2014";

String monthYear = "092014";

The monthYear format is MMyyyy, I wish to format it to become MMyy. Thus, I am doing it as follows:

Method 1:

final SimpleDateFormat oriMonthYear = new SimpleDateFormat( "MMyyyy" );
final SimpleDateFormat changeMonthYear = new SimpleDateFormat( "MMyy" );

String newMonthYear = changeMonthYear.format( oriMonthYear.parse( month + year) );

This give me correct output, but I am not sure am I doing it by stupid way or not. I believe it should be another best practice and smart to way to do it.

  • \$\begingroup\$ That's pretty much it as far as using Java's libraries. Though, that month + year is suspect... You're better off using Joda. \$\endgroup\$ – Jeff Mercado Jan 26 '15 at 4:33
  • \$\begingroup\$ [All information for datatime you have. ](docs.oracle.com/javase/7/docs/api/java/text/…) \$\endgroup\$ – Ibrahim Jan 26 '15 at 15:45

Use Java's THreadLocal type to wrap your SimpleDateFormat objects.

ThreadLocal<SimpleDateFormat> oriFormatHolder = new ThreadLocal<SimpleDateFormat>() {

    protected SimpleDateFormat initialValue() {
        return new SimpleDateFormat("MMyyyy");

final SimpleDateFormat oriMonthYear = oriFormatHolder.get();

The reason for this is because SimpleDateFormat is not thread safe.

Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

Read more here

I actually ran into this problem. In a multi threaded env we were sharing a SimpleDateFormat object across many threads and started getting bad results. By wrapping it with ThreadLocal the problem went away.

  • 1
    \$\begingroup\$ An explanation why do this would be nice! \$\endgroup\$ – janos Jan 26 '15 at 6:31
  • \$\begingroup\$ Rather, do not use ThreadLocal. It's a wonderful way to shoot yourself in the knee if you don't know what you're doing. \$\endgroup\$ – Jeor Mattan Jan 26 '15 at 14:19
  • \$\begingroup\$ @janos, I updated my answer with the reason why. \$\endgroup\$ – Jose Martinez Jan 26 '15 at 14:24

If you are assured that the Strings you get form a valid date then you can just remove the first and second characters from the year string.

String newMonthYear = month + year.substring(2);

Do you want to change your date format in the future?

Do you always receive correct input?

Do you reformat dates in a performance-sensitive context?

If it is "No", "Yes" and "Yes" you're better off with String.format and substring to do what you want. Otherwise, SimpleDataFormat is the way to go (don't forget synchronization).

The way you use SimpleDataFormat is perfectly correct (sans the string concatenation part), it's just more expensive resource-wise (to pay off for it being much more powerful tool).


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.