-1

I have a requirement to parse the date into milliseconds. Here is how I am doing it.

 private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

      public void setTime(String date) {
      try {
            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
            this.time = sdf.parse(date).getTime();
        } catch (ParseException e) {
                e.printStackTrace();
        }

Here is the problem in my server.

For example, for the given input date "2015-06-20T01:57:13Z", I get output value as 1592618233000 ms, however, the expected value should be 1434765433000.

Analyzing the issue I found that difference of 157852800000 ms which when converted gives to "Thu Jan 01 1975 05:30:00 GMT+0530 (IST)" Date.

I see that 157852800000 ms is getting added to few of the dates in my server. There is no code issue here. I am using the code as shown above. When I run the same in my local machine it is working absolutely fine. Also, this scenario in my server do not occur all the times.

Please advise on this.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
Skanda
  • 835
  • 1
  • 15
  • 32

4 Answers4

1

It might or might not be causing your problem here, but in general you shouldn't make SimpleDateFormat a static field. This is because this class is stateful and therefore not thread safe; when multiple threads access the same instance, unexpected results might ensue.

Adriaan Koster
  • 15,870
  • 5
  • 45
  • 60
  • Understand. But why is it adding only jan 01 1975 everytime. From where is it picking this value and on what scenarios it will add this date to the input date. – Skanda Jun 23 '15 at 12:22
0

Maybe it is concurrency issue. SimpleDateFormat is not threadsafe. So create it every time it is used or synchronize access to it and check if that resolves your problem.

  • But why is it adding only jan 01 1975 everytime. From where is it picking this value and on what scenarios it will add this date to the input date. Please advise – Skanda Jun 23 '15 at 17:11
0

SimpleDateFormat is not thread safe. It might be a possibility that multiple threads are accessing the same simpledateformat instance. Generally it is not advised to make it static. Every instance should have each its own simpledateformat instance.

Srijan Mehrotra
  • 222
  • 2
  • 10
0

Apparently something is going wrong on your end.

Here is my version of your code. Using Java 8 Update 45.

try {
    String input = "2015-06-20T01:57:13Z";
    SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss'Z'" );

    sdf.setTimeZone( TimeZone.getTimeZone( "GMT" ) );
    java.util.Date date = sdf.parse( input );
    long millisSinceEpoch = date.getTime();

    System.out.println( "millis: " + millisSinceEpoch );

} catch ( ParseException ex ) {
    // Handle exception
}

When run.

millis: 1434765433000

I get your expected results.

Perhaps the problem is related to your incorrect use of a SimpleDateFormat instance as static, as other pointed out in comments and Answers.

By the way, the java.util.Date/.Calendar classes are notoriously troublesome. They are now supplanted by either:

Both of these frameworks support your input string’s ISO 8601 format by default.

And both of these frameworks assign a time zone to their respective date-time objects.

Joda-Time

Here is code in Joda-Time 2.8.1. Search StackOverflow for many more examples and discussions.

String input = "2015-06-20T01:57:13Z";
DateTimeZone zone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeKolkata = new DateTime( input , zone );
DateTime dateTimeUtc = dateTimeKolkata.withZone( DateTimeZone.UTC );
long millisSinceEpoch = dateTimeKolkata.getMillis();

Dump to console.

System.out.println( "dateTimeKolkata: " + dateTimeKolkata );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "millisSinceEpoch: " + millisSinceEpoch );

When run.

dateTimeKolkata: 2015-06-20T07:27:13.000+05:30
dateTimeUtc: 2015-06-20T01:57:13.000Z
millisSinceEpoch: 1434765433000

java.time

Code for java.time will be similar in concept to the Joda-Time code seen above, except that java.time use Factory methods rather than "new" constructors.

See this Question, Parse ISO timestamp using Java 8 java.time api (standard edition only) for code examples.

Avoid Count-Since-Epoch

I suggest avoiding working directly with a count-from-epoch (milliseconds in your case) whenever possible. Use a decent date-time framework and stick with its intelligent objects. Do you handle text as raw byte arrays instead of String instances? Same logic applies to date-time values.

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154