当前位置: 首页 > 知识库问答 >
问题:

来自ZoneDateTime UTC实例的Java日期和时间戳

戚侯林
2023-03-14

我有一个java应用程序,我希望时间以UTC为单位。目前,该代码混合使用了java。util。日期java。sql。时间戳。为了获得UTC时间,我之前的程序员使用:

截止日期:

 Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

对于时间戳:

 Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());

然而,我自己用这段代码运行了多个测试,这两行都返回当前日期/时间(在我当前的时区)。从我读到的所有信息来看,日期/时间戳似乎没有区域偏移值,但我找不到具体的说明。

无论如何,是否有将timeZone(UTC)保留在Date或Timestamp对象中,或者我是否需要进行一些重构并在整个应用程序中使用实际的ZonedDateTime对象?此外,此ZonedDateTime对象是否与SQL的当前Timestamp对象兼容?

例子:

public static void main (String args[])
{
    ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
    Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    System.out.println("ZonedDateTime: " + zonedDateTime);
    System.out.println("Timestamp: " + timestamp);
    System.out.println("Date: " + date);
}

输出:

 ZonedDateTime: 2017-04-06T15:46:33.099Z
 Timestamp: 2017-04-06 10:46:33.109
 Date: Thu Apr 06 10:46:33 CDT 2017

共有2个答案

水昊阳
2023-03-14

在Java中,Date代表一个时间点。它与时间戳无关。当您调用日期对象的toString()方法时,它会将该时间转换为平台的默认时间戳,例如,下面将以UTC打印日期/时间(因为它将默认时区设置为UTC):

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
System.out.println("ZonedDateTime: " + zonedDateTime);
System.out.println("Timestamp: " + timestamp);
System.out.println("Date: " + date);
邓深
2023-03-14
Instant.now()  // Capture the current moment in UTC with a resolution up to nanoseconds.

只使用java。时间课。避免在Java8之前添加麻烦的旧遗留日期时间类。

您之前的程序员正在利用新的现代java.time类,这些类现在取代了臭名昭著的麻烦的旧遗留日期时间类,例如DateCalendarTimestamp

Instant类以UTC表示时间线上的一个时刻,分辨率为纳秒(最多九(9)位小数)。用UTC获取当前时刻非常简单:Instant。现在

Instant instant = Instant.now();

您应该坚持使用java.time类,并避免使用遗留类。但是如果绝对必要,例如与java.time尚未更新的旧代码接口,您可以在旧类上转换为/从java.time.查找新方法。遗留类java.util.Date等效项是Instant

java.util.Date d = java.util.Date.from( myInstant); // To legacy from modern.
Instant instant = myJavaUtilDate.toInstant();  // To modern from legacy.

避免遗留的日期时间类。使用java。改为上时间课。

兼容JDBC 4.2的驱动程序可能能够直接解决java问题。通过调用PreparedStatement::setObjectResultSet::getObject来进行时间类型。

myPreparedStatement.setObject( … , instant ) ;

…还有…

Instant instant = myResultSet.getObject( … , Instant.class ) ;

如果没有,就退回到使用java。sql类型,但尽可能简短。使用添加到旧类中的新转换方法。

myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;

…还有…

Instant instant = myResultSet.getTimestamp( … ).toInstant() ;

请注意,我们不需要您提到的ZonedDateTime,因为您说您只对UTC感兴趣。Instant对象始终在UTC中。这意味着您引用的原始代码:

Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

...可以简单地缩短为:

Date.from( Instant.now() ) ;

注意java。util。日期也总是以UTC为单位。然而,不幸的是,它的toString在生成字符串时隐式地应用了JVM当前的默认时区。通过搜索堆栈溢出,您可以看到,这个反功能带来了无尽的混乱。

如果你想通过一个地区的挂钟时间来查看你的即时对象的UTC值,请指定一个时区ZoneId,以获得ZoneDateTime

大陆/地区的格式指定适当的时区名称,例如美国/蒙特利尔非洲/卡萨布兰卡,或太平洋/奥克兰。切勿使用3-4个字母的缩写,例如CDTESTIST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdt = instant.atZone( z );

java.time框架内置在Java8及更高版本中。这些类取代了麻烦的旧的遗留日期-时间类,例如java.util.DateCalendar

Joda Time项目现在处于维护模式,建议迁移到java。时间课。

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

你可以交换java。时间对象直接与数据库连接。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java。sql* 类。

从哪里获得java.time课程?

  • JavaSE 8、JavaSE 9、JavaSE 10、JavaSE 11及更高版本-标准JavaAPI的一部分,具有捆绑实现。
    • Java9增加了一些小功能和修复。
    • java的大部分内容。时间功能被重新移植到Java 6
    • 更高版本的Android捆绑包实现了java。时间课
    • 对于早期的Android系统(

    额外的Three Ten项目扩展了java。有额外课程的时间。这个项目是java未来可能增加的一个试验场。时间你可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,等等。

 类似资料:
  • 本文向大家介绍JAVA时间日期处理类实例,包括了JAVA时间日期处理类实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JAVA时间日期处理类,主要用来遍历两个日期之间的每一天。分享给大家供大家参考。具体如下: 希望本文所述对大家的java程序设计有所帮助。

  • 问题内容: 我需要在Mysql中进行日期比较而不考虑时间成分,即我需要将“ 2008-11-05 14:30:00”转换为“ 2008-11-05” 目前我正在这样做: 有适当的方法吗? 问题答案: 是的,使用日期功能:

  • 我目前正在构建一个应用程序使用JavaFx与一个额外的功能,显示当前的日期和时间在顶角的场景。由于我是JavaFX新手,我不知道如何实现这个。 我试图使用swing中的旧代码,但我得到了一个IllegalStateException错误。 这是我的密码。 MainMenuController.java Main.java 正如您所注意到的,我测试了它在控制台中打印实时时间。是的,它起作用了,但标签

  • 本文向大家介绍mysql日期和时间的间隔计算实例分析,包括了mysql日期和时间的间隔计算实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了mysql日期和时间的间隔计算。分享给大家供大家参考,具体如下: 我们首先得明确一点,mysql间隔值主要用于日期和时间计算,如果我们要要创建间隔值,可以使用以下表达式: 然后嘞,我们得了解,INTERVAL关键字是确定间隔值的expr,以及指定

  • 然后将变量持久化到MySQL表列中。 然而,虽然通过调试,我看到对象显示在正确的时区GMT+1,但在数据库上持久化时,它是一个GMT时区,所以要追溯一个小时。 使用函数返回一个GMT+1日期。 连接字符串为,没有任何参数。 编辑:找到这段代码

  • 让我一起学习一个新的内建对象:日期(Date)。该对象存储日期和时间,并提供了日期/时间的管理方法。 例如,我们可以使用它来存储创建/修改时间,或者用来测量时间,再或者仅用来打印当前时间。 创建 创建一个新的 Date 对象,只需要调用 new Date(),在调用时可以带有下面这些参数之一: new Date() 不带参数 —— 创建一个表示当前日期和时间的 Date 对象: let now =