8

Yes, another question about Date in Java and Javascript.

The timezone is GMT+4 (Moscow) both in Java and Browser (Chrome).

<script language="javascript">
  var d = new Date(170798400000);
  document.write(d);
</script>

Gives: Sun Jun 01 1975 00:00:00 GMT+0400 (Russian Standard Time)

public class Test {
    public static void main(String[] args) {
        java.util.Date d = new java.util.Date(170798400000L); // the same epoch value!
        System.out.println(d);
    }
}

Gives: Sat May 31 23:00:00 MSK 1975

If I change the epoch value to something like 2011-2012 year (after daylight saving was canceled in Russia) the output is OK. Timezone updater tool ran OK.

Is this a bug or documented feature? Is there any way to handle this except formatting and re-parsing like YYYY-MM-dd HH:mm:SS or so?

from javadoc:

Date(long date)

Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.

from javascript reference:

new Date(milliseconds)

milliseconds - Integer value representing the number of milliseconds since 1 January 1970 00:00:00 UTC (Unix Epoch).

7
  • Maybe this has something to do with "Time zone changes": en.wikipedia.org/wiki/Moscow_Time Commented Jan 18, 2012 at 15:53
  • It definetely is. Is that means Date constructor cannot be used in javascript anymore? Commented Jan 18, 2012 at 15:56
  • Well, if one of them is giving the right answer, but not the other one, then I'd say the other one has a bug :-) Is Java correct or is JavaScript? I'd sort-of expect the Java version to give the right answer, but that's just a suspicion. Commented Jan 18, 2012 at 15:56
  • Yes, Java is correct, but javascript is not Commented Jan 18, 2012 at 15:57
  • 2
    both tzdata and jdk (using timezone updater tool) were updated so Java knows that before 2011 it was GMT+3 but GMT+4 after 2011. It seems Javascript is missing this information and thinks that it was always GMT+4. I can hack JSON serializer to insert a condition and adjust the time zone but wondering is there a better way? Commented Jan 19, 2012 at 2:55

3 Answers 3

1

Is this a bug or documented feature?

This is not a bug with Javascript. At least, I see no way I could claim that.

The browser's Javascript engine is returning the time converted to "GMT+4". What you are wanting, apparently, is MSK which is different from GMT+4 (as noted in your comment). Javascript not knowing about MSK doesn't count as a bug, but a lack of a feature. Perhaps js is "wrong" for not having that detailed knowledge of timezones, but it's not a bug.

Is there any way to handle this except formatting and re-parsing like YYYY-MM-dd HH:mm:SS or so?

Keeping track of all the arbitrary details of timezones requires a lot of work. I know of no such codebase which has all that work available for javascript. Therefore, I believe that, yes, you would have to manually code that conversion yourself if you want to use true MSK.

Sign up to request clarification or add additional context in comments.

Comments

1

String representation of time (like "Sun Jun 01 1975 00:00:00 GMT+0400") are used for human. Time value (milliseconds since 1 January, 1970 UTC) are used for storage and calculation.

There is no bug there. In JavaScript, according to the specification, the contente of string representation is implementation-dependant. In Java, according to the documentation, the daylight saving time may be reflected.

From JavaScript specification:

15.9.5.2 Date.prototype.toString ( )

This function returns a String value. The contents of the String are implementation->dependent, but are intended to represent the Date in the current time zone in a convenient, human-readable form.

From Java documentation:

java.util.Date, public String toString()

Converts this Date object to a String of the form: dow mon dd hh:mm:ss zzz yyyy

where:
...
zzz is the time zone (and may reflect daylight saving time).`

Comments

0

tl;dr

Instant.ofEpochMilli( 170_798_400_000L )

1975-05-31T20:00:00Z

…and…

Instant.ofEpochMilli( 170_798_400_000L )
       .atZone( ZoneId.of( "Europe/Moscow" ) )

1975-05-31T23:00+03:00[Europe/Moscow]

See live code.

Using java.time

The modern approach uses the java.time classes in Java 8 and later.

You are using troublesome old date-time classes in Java that are now legacy. Among the many problems on those classes was the well-intentioned but confusing feature of the Date::toString method applying the current default time zone while generating the string. The internal value is actually always in UTC, but toString creates the illusion that Date has a time zone when in fact it does not. That explains your MSK mystery.

[Even more confusing, there actually is a time zone buried deep in Date but is irrelevant to this discussion. Those old Date/Calendar classes are an awful mess. Fortunately Java now has the best-in-class date-time framework on any platform: java.time.]

Apparently your input represents the number of milliseconds since the Unix epoch of 1970-01-01T00:00:00Z.

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class can directly parse your input number.

Instant instant = Instant.ofEpochMilli( 170_798_400_000L ) ;

instant.toString(): 1975-05-31T20:00:00Z

If you want to see that same moment through the lens of a particular region’s wall-clock time, apply a time zone. Apply a ZoneId to get a ZonedDateTime object.

ZoneId z = ZoneId.of( "Europe/Moscow" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

1975-05-31T23:00+03:00[Europe/Moscow]

JavaScript library is incorrect

The results of your call to the JavaScript library is incorrect with its offset of +04:00. According to Wikipedia, Moscow time from 1930 to 1981 was three hours ahead, +03:00. The java.time framework yields correct results of +03:00 throughout the year of 1975. See Time in Russia for more info. Caveat: I am not expert in Russia/Soviet time.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.