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