2

This question is rather complicated and I don't know if it's been asked before because I don't know how to phrase the problem in the search box.

Here's the code:

public class SomeClass 
{
  private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

  public static String toUTCDateString(Date date)
  {
    df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
    return df.format(date);
  }

  /* more static methods */
}

The static member df will be re-used again in more static methods, but I need to have its time zone set to "UTC" first. Is there a way to call .setTimeZone("UTC") just once and for all? Or do I have to call .setTimeZone("UTC") in each static method?

user207421
  • 305,947
  • 44
  • 307
  • 483
kerafill
  • 274
  • 1
  • 4
  • 14
  • 2
    Note that `SimpleDateFormat` is not thread-safe. If multiple threads use the same static `SimpleDateFormat` object concurrently, you will get unexpected results. – Robby Cornelissen Jun 07 '14 at 08:37

2 Answers2

7

Use Static Initialization Blocks

A static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:

static {
    // whatever code is needed for initialization goes here
}

A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

Sample code:

public class SomeClass 
{
      private static final DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

      //Static Initialization Blocks
      static{
           df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
      }

      public static String toUTCDateString(Date date)
      {     
          return df.format(date);
      }

     /* more static methods */
}
Braj
  • 46,415
  • 5
  • 60
  • 76
  • Wow, it's that simple? I never knew of static initialization blocks in java. >_<;; – kerafill Jun 07 '14 at 08:34
  • 1
    Yes, I read up on the link. Alternatively, I can also use private static initialize-methods to initialize my static member. Thanks! I'll accept the answer when 5 minutes is up! – kerafill Jun 07 '14 at 08:39
  • By using the code above you have to synchronize the access to the SimpleDateFormat as it is not threadsafe and will likely lead to unexpected results if called simultaneously – mschenk74 Jun 07 '14 at 08:55
  • As an alternative, use the [Joda-Time](http://www.joda.org/joda-time/) library for thread-safety. – Basil Bourque Jun 07 '14 at 14:44
  • OP is not talking about Thread safe at all. Might be OP is not using the code in a multi-threaded environment. – Braj Jun 07 '14 at 17:08
3

Unfortunately! SimpleDateFormat is not trread-safe: it keeps an internal state, and used at the same time havoc arises.

This "solves" your problem as you have to change the API.

public static DateFormat df()
{
    DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    df.setTimeZone(java.util.TimeZone.getTimeZone("UTC"));
    return df;
}

In Java 8 using other, nicer classes this issue is solved.

By the way yyyy-MM-dd is the ISO standard.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138