如何使date.getTime()返回UTC时间?
我有一个表示UTC时间的Date对象。 当我使用方法getTime()来获取此对象的long值时,返回的值对应于我们的本地时间(美国中部)。 获取与原始UTC时间相对应的值的正确方法是什么?
谢谢
DateFormat
类有一个设置首选时区的方法 ,并且有一个时区类,它具有UTC时间的设置 。
所以,例如,
SimpleDateFormat sdf = new SimpleDateFormat(); sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC")); Date yourUtcDate = sdf.parse(yourOriginalDate);
java.util.Date
没有时区概念。 它只保留相对于纪元的时间,即1970年1月1日00:00:00 UTC。 日期是一个模型,与视图分开。 显示日期时,将应用时区的概念。 Date的toString()在默认时区中显示人类可读日期。 您可以使用DateFormat
以不同的时区(例如UTC)显示日期,也可以更改JVM的默认时区。
TL;博士
Instant.now()
…和…
Instant.ofEpochMilli( n )
…和…
instant.toEpochMilli()
Date
始终为UTC
当我使用方法getTime()来获取此对象的long值时,返回的值对应于我们的本地时间(美国中部)。
不,从Date::getTime()
返回的值始终对应于UTC (在此上下文中几乎与GMT相同)。 引用课程文档:
返回自此Date对象表示的1970年1月1日00:00:00 GMT以来的毫秒数。
因此,您的问题是荒谬的,因为Date
已经是UTC。 无需“获取与原始UTC时间相对应的值”,
您可能会将getTime
的行为与toString
方法的行为混淆。 toString
方法令人烦恼且容易混淆地在生成String的过程中应用当前的默认时区。 因此字符串输出显示时区,而实际上没有时区可以从Date
本身设置或获取。 (实际上在Date
有一个区域,但这与这里的讨论无关。这个类是一个混乱的混乱!)
java.time
现代的方法是使用java.time类。
Instant
Instant
类表示UTC时间轴上的一个时刻,分辨率为纳秒 (最多九(9)位小数)。
获取当前时刻。
Instant instant = Instant.now();
您可以通过调用添加到旧日期时间类的新转换方法之一将Date
转换为其现代替换。 只需打电话给toInstant
,很容易。
Instant instant = myJavaUtilDate.toInstant();
我完全不建议使用从纪元开始的数字作为跟踪时间的方法。 坚持使用java.time对象。 在Java之外,序列化为文本使用ISO 8601格式。
但如果必须,您可以提取自1970-01-01T00:00:00Z纪元以来的毫秒数。 请注意,这可能涉及数据丢失! Instant
具有更精细的纳秒分辨率。 因此,毫秒可能会减少一小部分时间。
long millisecondsSinceEpoch = instant.toEpochMilli(); // Caution: Possible data-loss in going from nanoseconds to milliseconds.
走向另一个方向,从计数到Instant
。
Instant instant = Instant.ofEpochMilli( millisecondsSinceEpoch ) ;
关于java.time
java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.Date
, Calendar
和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle教程 。 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310 。
从哪里获取java.time类?
- Java SE 8和SE 9及更高版本
- 内置。
- 带有捆绑实现的标准Java API的一部分。
- Java 9增加了一些小function和修复。
- Java SE 6和SE 7
- 许多java.timefunction都被反向移植到ThreeTen-Backport中的 Java 6和7。
- Android的
- ThreeTenABP项目特别适用于Android的ThreeTen-Backport (如上所述)。
- 请参阅如何使用….
ThreeTen-Extra项目使用其他类扩展了java.time。 该项目是未来可能添加到java.time的试验场。 您可以在这里找到一些有用的课程,如Interval
, YearWeek
, YearQuarter
等。
getTime()
返回“自1970年1月1日,格林威治标准时间00:00:00以来的毫秒数”,仅此而已,没有更少(显然,您必须正确创建它)。 您可以根据需要对其进行格式化,例如GregorianCalendar(TimeZone)
构造函数。
大多数Date类函数都已弃用,因为它们现在已在Calendar类中移位。
以下是从日历获取UTC时间的代码。
Date date = new Date(timeStamp); Calendar calendar = Calendar.getInstance(); calendar.setTimeZone(TimeZone.getTimeZone("UTC")); calendar.setTime(date);
以下是获取年,月等的示例代码。
System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH));
日历还支持许多其他有用的信息,如TIME,DAY_OF_MONTH等。此处列出所有这些信息的文档请注意,月份为0。 1月是第0个月。
LocalDateTime now = LocalDateTime.now(Clock.systemUTC()); Instant instant = now.atZone(ZoneId.systemDefault()).toInstant(); Date formattedDate = Date.from(instant); return formattedDate;