简体   繁体   中英

What is the correct way to create a timestamp in Java?

Given a year, month, day, hour, minute and second, what is the correct way to create a Java UTC (GMT) timestamp?

Options I've considered, but remain to be convinced by:

1 - use deprecated Date constructors

java.util.Date date = new java.util.Date(year - 1900, month, dayOfMonth, hour, minute, second);
long timestamp = date.getTime();

2 - use a calendar with TimeZone set to GMT

Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, second);
c.set(Calendar.MILLISECOND, 0);
long timestamp = c.getTimeInMillis();

One of my issues with this is that I'm finding it very hard to test without getting mixed up in more TimeZone issues.

Is there a definitive right way to do this with the standard APIs?

Update: would like to get an answer to this using standard JavaSE. I know Joda-Time is wonderful, but it's not an option in this case.

没有,没有(除非你可以使用乔达时间 ),正确的方法是使用日历和日历API 丑陋的,任何人都无法在此刻做的。

Standard Java APIs for dates are pretty inconvenient. Consider using Joda-Time :

long timestamp = new LocalDateTime(year, month, day, hour, minute, second)
    .getLocalMillis();

I think this would work pretty good

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
Date date = sdf.parse("2011-12-21 12:00:00+0000");

You would have to build the date string on your own but it's short and should work fine. And create the SimpleDateFormat to your liking, the important part is the Z that corresponds to "+0000".

Here is another alternative way on the same lines

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2011-12-21 12:00:00");

It's with an explicit time zone and the Z is removed.

tl;dr

OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC )

java.time

The modern approach uses the java.time classes.

Unlike the troublesome legacy date-time classes, the java.time classes use sane numbering:

  • 2018 means the year 2018. (No crazy math with 1900.)
  • 1-12 for months January-December. (Not silly 0-11.)
  • 1-7 for Monday-Sunday per ISO 8601 standard definition of week . (No varying by locale.)

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

You a one-liner if you wish, if parsing a string.

Instant instant = Instant.parse( "2018-01-23T12:34:56Z" ) ;

While Instant is a basic building-block class for java.time , the OffsetDateTime class is more flexible. The offset-from-UTC of UTC itself is defined as a constant for your convenience.

OffsetDateTime odt = OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC ) ;

Personally, I prefer using pieces.

In place of a mere integer for month, you may specify a Month enum object.

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;  // Date-only, without time-of-day.
LocalTime lt = LocalTime.of( 12 , 34 , 56 ) ;  // Time-of-day, without date.
ZoneOffset offset = ZoneOffset.UTC ;
OffsetDateTime odt = OffsetDateTime.of( ld , lt , offset ) ;

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 .

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM