Calling `new Date(long)` results in "Jan 01 01:00:00 CET 1970"? [duplicate]
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 ofDate
.
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.
精彩评论