开发者

Calling `new Date(long)` results in "Jan 01 01:00:00 CET 1970"? [duplicate]

This question already has answers here: Epoch is not epoch if do a new Dat开发者_开发技巧e(0L). Why? (4 answers) Closed 4 years ago.

The Java doc describe that the constructor Date(long date) constructs a Date object using the given milliseconds time value since January 1, 1970, 00:00:00 GMT

When I did new Date(0), the date is Jan 01 01:00:00 CET 1970

I don't know why it begin with 01h


It's show 1AM because you're an hour ahead of GMT. A date instance is simply a counter of the number of milliseconds since 00:00:00 1970 GMT. Since your an hour ahead, when the epoch occurred it was actually 1AM your time.

The Date instance simply formats its toString() method to use your system's timezone. If you want to print out a date using a different zone, use a DateFormat instance.


This is because you are showing the date in the European timezone (CET) the unix time (the milliseconds you are giving the Date object) use GMT.


tl;dr

Instant.now()  // Current moment in UTC.

Details

The Answer by Nichols is correct but outdated.

  • Your own time zone was an hour ahead of UTC on that date, so midnight in UTC is 1 AM in your zone.
  • Nowadays you should be using java.time classes such as Instant instead of Date.

Avoid legacy classes

Avoid the troublesome old date-time classes now supplanted by the java.time classes.

Among the many problems of the legacy classes was the poor design choice to have the toString method dynamically apply the JVM’s current default time zone while generating the string representing the object’s value. A Date actually represents a moment in UTC. Avoid awkward class entirely. If necessary, convert between the legacy and modern classes via new methods added to the old classes.

Instant for UTC

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).

Instant instant = Instant.now() ;  // Current moment in UTC.

instant.toString(): 2018-02-11T21:07:02.315283Z

If you want the epoch reference moment used by the java.time classes, the first moment of 1970 in UTC, use the predefined constant: Instant.EPOCH.

Instant.EPOCH.toString(): 1970-01-01T00:00:00Z

OffsetDateTime

If you need more flexibility, such as generating strings in other formatting, convert the Instant object to a OffsetDateTime using the constant ZoneOffset.UTC.

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

ISO 8601

When exchanging date-time values as text, use the standard ISO 8601 formats. They were designed to be easy to parse by machine while also being easy to read by humans across various cultures.

The java.time classes use the standard ISO 8601 formats by default when generating/parsing strings. So no need to specify a formatting pattern.

Time zone, ZonedDateTime

If you want to see the same simultaneous moment through the lens of the wall-clock time used by the people of another region, apply a time zone (ZoneId) to get a ZonedDateTime object.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST or CET as they are not true time zones, not standardized, and not even unique(!).

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

zdt.toString(): 2018-02-11T22:07:02.315283+01:00[Europe/Paris]

Let's look at the java.time epoch reference moment through the same time zone.

ZonedDateTime zdtEpochParis = Instant.EPOCH.atZone( z ) ;

zdtEpochParis.toString(): 1970-01-01T01:00+01:00[Europe/Paris]

Again, for another time zone.

ZonedDateTime zdtEpochMontreal = Instant.EPOCH.atZone( ZoneId.of( "America/Montreal" ) ) ;

zdtEpochMontreal.toString(): 1969-12-31T19:00-05:00[America/Montreal]


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.

With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜