Calendar.getInstance 使用 TimeZone 与 new Date()
Calendar.getInstance with TimeZone vs new Date()
我在我的应用程序中编写了一个实用程序,它接受一个时区和 returns 我一个日期 (java.util.Date),如下 -
// Inside MyDateHelper.java
public static java.util.Date getTimeForTimeZone(String timeZoneId)
{
final Date currentDate = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId)).getTime();
return currentDate;
}
我在互联网上进行了研究,发现 Date 中没有任何时区信息。相反,它是从 1970 年开始的一个 long 值的包装器。所以,我的问题是,如果我必须获取当前的日期时间即时发生事务以存储在日期字段(类型 java.util.Date ), 这个实用程序有用吗?
为了所有实际目的,这两行代码是否实现了相同的目的?
transactionEntry.setTime(MyDateHelper.getTimeForTimeZone("UTC+7:00"));
或
transactionEntry.setTime(new Date());
我也查看了新的 Java 8 Time API,但就我的目的而言,我认为这样做也是一种矫枉过正,没有更多的收获 new Date()
-
Date date4 = new Date();
LocalDateTime localDate = date4.toInstant().atZone(ZoneId.of("UTC+07:00")).toLocalDateTime();
final ZonedDateTime dateWithZone = localDate.atZone(ZoneId.of("UTC+07:00"));
Date dateOutput = Date.from(dateWithZone.toInstant());
transactionEntry.setTime(dateOutput);
整个目的是用时区捕获交易发生的时间,但我只能将时间存储为java.util.Date。无论交易发生在哪个时区,Date 都能正确捕捉到时间的瞬间,对吧?有人可以确认这种理解是正确的吗?
但我只能将时间存储为 java.util.Date。
那么时区就无所谓了,
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
Date america = calendar.getTime();
calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
Date shanghai = calendar.getTime();
System.out.println(america.equals(shanghai)); // true
您可以只使用:
transactionEntry.setTime(new Date());
这篇将帮助您理解Instant/Date
、LocalDateTime
、ZonedDateTime
。
我想你可能会重新考虑设计。为什么只允许 java.util.Date
?
从描述来看,您似乎很关心交易发生的时区。而java.util.Date
就是不支持。这意味着您可以将准确的值(自纪元以来的毫秒数)存储到 java.util.Date
,但由于时区已丢失,因此该值无法用准确的日期时间表示。
您可能需要使用 java.time.ZonedDateTime
来实现它。
第一个建议:
Instant transactionTime = Instant.now();
你是对的,在你的时区,无论是 ZonedDateTime
还是 Calendar
,都没有意义,因为你需要的是时间戳,片刻及时。 java.time.Instant
就是一个没有时区的时间点(因此是 Date
的最直接替代)。您可能应该尽可能使用 java.time、现代 Java 日期和时间 API。 Date
、Calendar
和 TimeZone
不仅早已过时,而且还存在一系列设计问题。现代 classes 更好用。
如果您的交易条目 class 内部使用 java.util.Date
并且您现在不想升级其内部逻辑,您仍然可以添加一个重载的 setTime
方法来接受一个Instant
.
public void setTime(Instant time) {
// Delegate to the old method that accepts a java.util.Date
setTime(Date.from(time));
}
下一步可能是将接受 Date
的方法标记为弃用。
第二个建议,如果你坚持Date
我还是更喜欢:
Date transactionTime = Date.from(Instant.now());
它与 new Date()
的作用相同,但更直接地告诉 reader 您获得了当前时刻。我看不出这怎么可能不是优势。
顺便说一句,如果你确实想使用你的时区,你应该使用像 Antarctica/Davis
这样的正确时区 ID 而不是偏移量。它再次告诉您 reader 更多关于您的意图的信息,并且在夏令时 (DST) 引入或由于其他原因偏移量发生变化的情况下是面向未来的。
是正确的。我将添加一些讨论。
地球上的每个人同时经历的只有一条时间线(忽略爱因斯坦等人)。按照惯例,我们以 UTC 跟踪该时间。
学习将 UTC 视为 唯一真实时间。所有其他偏移量和区域都只是 UTC 的变体。当作为程序员或系统管理员工作时,忘掉你自己狭隘的时区吧。再次点击您的桌面或墙上的 UTC 跟踪时间。在 UTC 中执行所有日志记录、跟踪、数据存储和数据交换。
在 UTC 中跟踪时刻的基本 class 是 java.time.Instant
。 class 的对象根据定义始终采用 UTC。这个 class 取代了 java.util.Date
,它也代表了 UTC 中的一个时刻,但有很多设计缺陷,不应该被使用。 Instant
的分辨率为纳秒级,比 Date
的毫秒级更精细。
要获得更大的灵活性,请使用 OffsetDateTime
class。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
又回来了。
Instant instant = odt.toInstant() ;
与 UTC 的偏移量仅仅是小时-分钟-秒的数字。时区要多得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。
要使用时区,请应用 ZoneId
以获得 ZonedDateTime
。这个 class 取代了可怕的 Calendar
和 GregorianCalendar
classes。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZoneId( z ) ;
又要回去了。
Instant instant = zdt.toInstant() ;
这个zdt
、odt
和instant
都代表同一时刻,时间轴上的同一点。
最后,停止使用 Date
和 Calendar
。 Sun、Oracle 和 JCP 社区在采用 JSR 310 时都放弃了那些 classes,您也应该这样做。那些遗留的 classes 真的是一团糟。
我在我的应用程序中编写了一个实用程序,它接受一个时区和 returns 我一个日期 (java.util.Date),如下 -
// Inside MyDateHelper.java
public static java.util.Date getTimeForTimeZone(String timeZoneId)
{
final Date currentDate = Calendar.getInstance(TimeZone.getTimeZone(timeZoneId)).getTime();
return currentDate;
}
我在互联网上进行了研究,发现 Date 中没有任何时区信息。相反,它是从 1970 年开始的一个 long 值的包装器。所以,我的问题是,如果我必须获取当前的日期时间即时发生事务以存储在日期字段(类型 java.util.Date ), 这个实用程序有用吗?
为了所有实际目的,这两行代码是否实现了相同的目的?
transactionEntry.setTime(MyDateHelper.getTimeForTimeZone("UTC+7:00"));
或
transactionEntry.setTime(new Date());
我也查看了新的 Java 8 Time API,但就我的目的而言,我认为这样做也是一种矫枉过正,没有更多的收获 new Date()
-
Date date4 = new Date();
LocalDateTime localDate = date4.toInstant().atZone(ZoneId.of("UTC+07:00")).toLocalDateTime();
final ZonedDateTime dateWithZone = localDate.atZone(ZoneId.of("UTC+07:00"));
Date dateOutput = Date.from(dateWithZone.toInstant());
transactionEntry.setTime(dateOutput);
整个目的是用时区捕获交易发生的时间,但我只能将时间存储为java.util.Date。无论交易发生在哪个时区,Date 都能正确捕捉到时间的瞬间,对吧?有人可以确认这种理解是正确的吗?
但我只能将时间存储为 java.util.Date。
那么时区就无所谓了,
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
Date america = calendar.getTime();
calendar.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
Date shanghai = calendar.getTime();
System.out.println(america.equals(shanghai)); // true
您可以只使用:
transactionEntry.setTime(new Date());
这篇Instant/Date
、LocalDateTime
、ZonedDateTime
。
我想你可能会重新考虑设计。为什么只允许 java.util.Date
?
从描述来看,您似乎很关心交易发生的时区。而java.util.Date
就是不支持。这意味着您可以将准确的值(自纪元以来的毫秒数)存储到 java.util.Date
,但由于时区已丢失,因此该值无法用准确的日期时间表示。
您可能需要使用 java.time.ZonedDateTime
来实现它。
第一个建议:
Instant transactionTime = Instant.now();
你是对的,在你的时区,无论是 ZonedDateTime
还是 Calendar
,都没有意义,因为你需要的是时间戳,片刻及时。 java.time.Instant
就是一个没有时区的时间点(因此是 Date
的最直接替代)。您可能应该尽可能使用 java.time、现代 Java 日期和时间 API。 Date
、Calendar
和 TimeZone
不仅早已过时,而且还存在一系列设计问题。现代 classes 更好用。
如果您的交易条目 class 内部使用 java.util.Date
并且您现在不想升级其内部逻辑,您仍然可以添加一个重载的 setTime
方法来接受一个Instant
.
public void setTime(Instant time) {
// Delegate to the old method that accepts a java.util.Date
setTime(Date.from(time));
}
下一步可能是将接受 Date
的方法标记为弃用。
第二个建议,如果你坚持Date
我还是更喜欢:
Date transactionTime = Date.from(Instant.now());
它与 new Date()
的作用相同,但更直接地告诉 reader 您获得了当前时刻。我看不出这怎么可能不是优势。
顺便说一句,如果你确实想使用你的时区,你应该使用像 Antarctica/Davis
这样的正确时区 ID 而不是偏移量。它再次告诉您 reader 更多关于您的意图的信息,并且在夏令时 (DST) 引入或由于其他原因偏移量发生变化的情况下是面向未来的。
地球上的每个人同时经历的只有一条时间线(忽略爱因斯坦等人)。按照惯例,我们以 UTC 跟踪该时间。
学习将 UTC 视为 唯一真实时间。所有其他偏移量和区域都只是 UTC 的变体。当作为程序员或系统管理员工作时,忘掉你自己狭隘的时区吧。再次点击您的桌面或墙上的 UTC 跟踪时间。在 UTC 中执行所有日志记录、跟踪、数据存储和数据交换。
在 UTC 中跟踪时刻的基本 class 是 java.time.Instant
。 class 的对象根据定义始终采用 UTC。这个 class 取代了 java.util.Date
,它也代表了 UTC 中的一个时刻,但有很多设计缺陷,不应该被使用。 Instant
的分辨率为纳秒级,比 Date
的毫秒级更精细。
要获得更大的灵活性,请使用 OffsetDateTime
class。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
又回来了。
Instant instant = odt.toInstant() ;
与 UTC 的偏移量仅仅是小时-分钟-秒的数字。时区要多得多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。
要使用时区,请应用 ZoneId
以获得 ZonedDateTime
。这个 class 取代了可怕的 Calendar
和 GregorianCalendar
classes。
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZoneId( z ) ;
又要回去了。
Instant instant = zdt.toInstant() ;
这个zdt
、odt
和instant
都代表同一时刻,时间轴上的同一点。
最后,停止使用 Date
和 Calendar
。 Sun、Oracle 和 JCP 社区在采用 JSR 310 时都放弃了那些 classes,您也应该这样做。那些遗留的 classes 真的是一团糟。