Java 如何从日历中获取UTC时间戳?

Java 如何从日历中获取UTC时间戳?,java,localization,calendar,timezone,timestamp,Java,Localization,Calendar,Timezone,Timestamp,在Java中使用Calendar.getInstance()时我得到当前时区的日历对象。但是java.sql.Timestamp通常存储在UTC时间,而不是本地时间。那么如何从日历实例中获取UTC时间呢 DateFormat df = DateFormat.getTimeInstance(); Calendar cal = Calendar.getInstance(); Timestamp time = new Timestamp(cal.getTimeInMillis(

在Java中使用
Calendar.getInstance()时
我得到当前时区的
日历
对象。但是
java.sql.Timestamp
通常存储在UTC时间,而不是本地时间。那么如何从日历实例中获取UTC时间呢

    DateFormat df = DateFormat.getTimeInstance();
    Calendar cal = Calendar.getInstance();
    Timestamp time = new Timestamp(cal.getTimeInMillis());

    // Prints local time
    System.out.println(df.format(new Date(time.getTime())));

    // Printe local time, but I want UTT Time
    System.out.println("timestamp: " + time);

当您调用
Calendar.getTime()
时,这将为您提供一个没有相关时区的值,或者您可以将其视为UTC格式的值,以表示日历所代表的时刻。因此,如果是(比如)日历时区的上午9点,那么可能是UTC的下午5点

现在,
java.util.Date
(我可以想象,
Timestamp
)将在调用
toString()
(隐式或显式)时在系统默认时区中进行格式化,但不要因此而误以为时区是对象本身中数据的一部分


您需要非常清楚您想要实现的目标,然后您可能会发现,与内置库相比,它可以让您在代码中更清楚地表达这些目标。

您的代码已经完全实现了您想要的目标<代码>时间戳(以及
日期
)没有时区信息,并且应该始终包含GMT时间戳(它是
Calendar.getTimeInMillis()返回的内容)


您看到打印本地时间的原因是
DateFormat
工厂方法以及
Timestamp.toString()
隐式使用系统时区。

以下代码片段应满足您的要求:

df.setTimeZone(TimeZone.getTimeZone("UTC"));
tl;博士 避免遗留日期时间类 您使用的是麻烦的旧日期时间类,现在已被java.time类取代。无需使用
日期格式
日历
时间戳

如果必须与尚未更新为java.time的旧代码进行互操作,请使用添加到旧类中的新方法进行转换。提取一个过时的
java.util.Date
,并转换为
Instant

Instant instant = myCal.getTime().toInstant() ;
使用java.time 以
瞬间
的形式获取当前时刻。该类表示时间线上的一个时刻,分辨率为(小数点的九(9)位)

2017-02-17T03:29:15.725Z

数据库 使用JDBC4.2及更高版本,您可以直接与数据库交换
Instant
对象。因此不需要过时的
java.sql.Timestamp

myPreparedStatement.setObject( … , instant ) ;
和检索:

Instant instant = myResultSet.getObject( … , Instant.class ) ;
纪元 显然,您需要从
1970-01-01T00:00:00Z
开始的毫秒数。您可以从
即时
中提取该数字。但是要小心数据丢失,因为
瞬间的
分辨率为纳秒,您将把它截断为毫秒

long millis = instant.toEpochMilli() ;
1487302155725


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • 后来
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门为Android采用了ThreeTen Backport(如上所述)

该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如、、和。

我实际上从API中获取了一个
日历
实例,然后我必须从中获取UTC时间戳。我喜欢Joda时间,但我不能在这里使用它。@Jonas:好的,在这种情况下,你只需要使用
getTime()
-这会给你一个UTC时间戳。好的,有没有办法让
DateFormat
在GMT时间显示它?@Jonas:DateFormat有一个setTimeZone()方法我刚刚格式化了你的答案,没有否决。
Instant instant = myResultSet.getObject( … , Instant.class ) ;
long millis = instant.toEpochMilli() ;