我有一个表示UTC时间的Date对象。当我使用getTime()方法获取此对象的long值时,返回的值对应于我们的本地时间(美国中部)。获取与原始UTC时间相对应的值的正确方法是什么?
由于
答案 0 :(得分:22)
DateFormat
班级有a method for setting your preferred time zone,而且时区类有a setting for UTC time。
所以,例如,
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setTimeZone(new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC"));
Date yourUtcDate = sdf.parse(yourOriginalDate);
答案 1 :(得分:22)
java.util.Date
没有时区概念。它只保留相对于纪元的时间,即1970年1月1日00:00:00 UTC。日期是一个模型,与视图分开。显示日期时,将应用时区的概念。 Date的toString()在默认时区中显示人类可读日期。您可以使用DateFormat
以不同的时区(例如UTC)显示日期,也可以更改JVM的默认时区。
答案 2 :(得分:20)
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类。
Instant
Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 3 :(得分:7)
getTime()
返回“自1970年1月1日,格林威治标准时间00:00:00以来的毫秒数”,仅此而已,显然,你必须正确地创建它。您可以根据需要对其进行格式化,例如从GregorianCalendar(TimeZone)
构造函数。
答案 4 :(得分:0)
大多数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等。此处documentation列出所有这些信息请注意,该月份为0。 1月是第0个月。
答案 5 :(得分:-1)
LocalDateTime now = LocalDateTime.now(Clock.systemUTC());
Instant instant = now.atZone(ZoneId.systemDefault()).toInstant();
Date formattedDate = Date.from(instant);
return formattedDate;