在Java中创建时间戳的正确方法是什么?

时间:2011-12-21 12:08:36

标签: java date

给定年,月,日,小时,分钟和秒,创建Java UTC(GMT)时间戳的正确方法是什么?

我考虑过的选项,但仍有待说服:

1 - 使用已弃用的日期构造函数

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

2 - 使用TimeZone设置为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();

我的一个问题是,我发现很难在没有混淆更多TimeZone问题的情况下进行测试。

使用标准API是否有明确的正确方法?

更新:希望使用标准JavaSE得到答案。我知道Joda-Time很精彩,但在这种情况下它不是一个选择。

4 个答案:

答案 0 :(得分:2)

不,没有(除非您可以使用Joda-Time),正确的方法是使用日历,日历API 丑陋,没有任何人都可以做到这一点。

答案 1 :(得分:1)

日期的标准Java API非常不方便。考虑使用Joda-Time

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

答案 2 :(得分:1)

我认为这会很好用

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

您必须自己构建日期字符串,但它很短,应该可以正常工作。并根据自己的喜好创建SimpleDateFormat,重要的部分是对应的Z. “+0000”。

以下是同一行的另一种替代方式

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");

这是一个明确的时区,Z被删除。

答案 3 :(得分:0)

TL;博士

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

java.time

现代方法使用 java.time 类。

与麻烦的遗留日期时间类不同, java.time 类使用合理的编号:

  • 2018表示2018年。(1900年没有疯狂数学。)
  • 1-12月1月至12月。 (不是傻0-11。)
  • 1-7表示周一至周日每ISO 8601 standard definition of week。 (不因地区而异。)

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

如果你愿意的话,你可以解析一个字符串。

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

虽然Instant java.time 的基本构建块类,但OffsetDateTime类更灵活。为方便起见,UTC本身的UTC偏移量为defined as a constant

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

就个人而言,我更喜欢使用碎片。

您可以指定Month枚举对象来代替月份的纯整数。

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

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

使用符合JDBC driver或更高版本的JDBC 4.2,您可以直接与数据库交换 java.time 对象。不需要字符串也不需要java.sql。* classes。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

相关问题