如何在 Java8+ 中将 UTC 转换为 EST java.util.date?
How to convert UTC to EST java.util.date in Java8+?
下面是我的代码,可将 UTC 转换为 EST。但是,如何将 ZonedDateTime 从下面的代码连同这种格式 (yyyy-MM-dd'T'HH:mm:ss) 转换为 java.util.Date?
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
String f = "yyyy-MM-dd'T'HH:mm:ss";
String timestamp = "2022-03-01T16:29:03"; //sample input
TemporalAccessor temporalAccessor = formatter.parse(timestamp);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
ZonedDateTime nyTime = result.atZone(ZoneId.of("Canada/Eastern"));
DateTimeFormatter format = DateTimeFormatter.ofPattern(f);
System.out.println("Date EST : " + format.format(nyTime));
一旦 ZonedDateTime
处于正确的时区,将其转换为 Instant,然后使用 class 日期的方法 public static Date from(Instant instant)。
Instant instant = Instant.from(zonedDateTime);
Date date = Date.from(instant);
但是,如果可以,请避免使用已过时(双关语意)包 java.time
的日期 class 以及 class 等 ZonedDateTime
、Instant
和其他人应该使用
您发表评论:
I need to populate this in DB column. So I need to convert a string which is in UTC to EST then converting ZonedDateTime back to java.util.Date in this format (yyyy-MM-dd'T'HH:mm:ss)
永远不要使用 Date
class。仅使用 java.time classes。 JDBC 4.2 及更高版本支持 java.time 与数据库交换 date-time 值。
- 对于类似于 SQL-standard 类型
TIMESTAMP WITHOUT TIME ZONE
的列,使用 java.time.LocalDateTime
.
- 对于类似于 SQL-standard 类型
TIMESTAMP WITH TIME ZONE
的列,使用 java.time.OffsetDateTime
.
您输入的字符串:
String timestamp = "2022-03-01T16:29:03";
... 命名错误。该值缺少时区指示符或 offset-from-UTC。所以它不能代表一个时刻。我们无法知道 hat 是否在日本东京、法国图卢兹或美国俄亥俄州托莱多 4:30 PM 左右——所有这些时间都相隔几个小时。所以称其为“时间戳”具有误导性。
将该输入字符串解析为 LocalDateTime
。无需指定格式化模式。该字符串符合 ISO 8691,在 java.time classses when parsing/generating 文本中默认使用。
LocalDateTime ldt = LocalDateTime.parse( "2022-03-01T16:29:03" ) ;
此时您的代码似乎很复杂。您为此 date-with-time 分配默认时区。但这似乎不太可能说得通。我猜你的意图是让这个特定的 date-with-time 代表在特定时区看到的特定时刻。
显然您需要加拿大东部时区。 proper name for that zone 是 America/Toronto
.
ZoneId z = ZoneId.of( "America/Toronto" ) ;
分配该区域以生成 ZonedDateTime
对象。
ZonedDateTime zdt = ldt.atZone( z ) ;
现在我们有一个时刻,时间轴上的一个特定点。
但要写入类似于 SQL-standard TIMESTAMP WITH TIME ZONE
类型的数据库列,我们需要使用 OffsetDateTime
.
OffsetDateTime odt = zdt.toOffsetDateTime() ;
稍后您评论说输入字符串旨在表示 UTC 中的时刻。所以分配一个ZoneOffset
对象,常量UTC
,得到一个OffsetDateTime
.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
发送到数据库。
myPreparedStatement.setObject( … , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
如果必须使用java.util.Date
与尚未更新为java.time的旧代码进行互操作,可以来回转换。查看添加到旧 classes 的新 to…
和 from…
方法。
java.util.Date d = Date.from( odt.toInstant() ) ;
java.util.Date d = Date.from( zdt.toInstant() ) ;
走向另一个方向。
Instant instant = myJavaUtilDate.toInstant() ;
所有这些主题都已在 Stack Overflow 上多次提及。搜索以了解更多信息。
下面是我的代码,可将 UTC 转换为 EST。但是,如何将 ZonedDateTime 从下面的代码连同这种格式 (yyyy-MM-dd'T'HH:mm:ss) 转换为 java.util.Date?
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
String f = "yyyy-MM-dd'T'HH:mm:ss";
String timestamp = "2022-03-01T16:29:03"; //sample input
TemporalAccessor temporalAccessor = formatter.parse(timestamp);
LocalDateTime localDateTime = LocalDateTime.from(temporalAccessor);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
Instant result = Instant.from(zonedDateTime);
ZonedDateTime nyTime = result.atZone(ZoneId.of("Canada/Eastern"));
DateTimeFormatter format = DateTimeFormatter.ofPattern(f);
System.out.println("Date EST : " + format.format(nyTime));
一旦 ZonedDateTime
处于正确的时区,将其转换为 Instant,然后使用 class 日期的方法 public static Date from(Instant instant)。
Instant instant = Instant.from(zonedDateTime);
Date date = Date.from(instant);
但是,如果可以,请避免使用已过时(双关语意)包 java.time
的日期 class 以及 class 等 ZonedDateTime
、Instant
和其他人应该使用
您发表评论:
I need to populate this in DB column. So I need to convert a string which is in UTC to EST then converting ZonedDateTime back to java.util.Date in this format (yyyy-MM-dd'T'HH:mm:ss)
永远不要使用 Date
class。仅使用 java.time classes。 JDBC 4.2 及更高版本支持 java.time 与数据库交换 date-time 值。
- 对于类似于 SQL-standard 类型
TIMESTAMP WITHOUT TIME ZONE
的列,使用java.time.LocalDateTime
. - 对于类似于 SQL-standard 类型
TIMESTAMP WITH TIME ZONE
的列,使用java.time.OffsetDateTime
.
您输入的字符串:
String timestamp = "2022-03-01T16:29:03";
... 命名错误。该值缺少时区指示符或 offset-from-UTC。所以它不能代表一个时刻。我们无法知道 hat 是否在日本东京、法国图卢兹或美国俄亥俄州托莱多 4:30 PM 左右——所有这些时间都相隔几个小时。所以称其为“时间戳”具有误导性。
将该输入字符串解析为 LocalDateTime
。无需指定格式化模式。该字符串符合 ISO 8691,在 java.time classses when parsing/generating 文本中默认使用。
LocalDateTime ldt = LocalDateTime.parse( "2022-03-01T16:29:03" ) ;
此时您的代码似乎很复杂。您为此 date-with-time 分配默认时区。但这似乎不太可能说得通。我猜你的意图是让这个特定的 date-with-time 代表在特定时区看到的特定时刻。
显然您需要加拿大东部时区。 proper name for that zone 是 America/Toronto
.
ZoneId z = ZoneId.of( "America/Toronto" ) ;
分配该区域以生成 ZonedDateTime
对象。
ZonedDateTime zdt = ldt.atZone( z ) ;
现在我们有一个时刻,时间轴上的一个特定点。
但要写入类似于 SQL-standard TIMESTAMP WITH TIME ZONE
类型的数据库列,我们需要使用 OffsetDateTime
.
OffsetDateTime odt = zdt.toOffsetDateTime() ;
稍后您评论说输入字符串旨在表示 UTC 中的时刻。所以分配一个ZoneOffset
对象,常量UTC
,得到一个OffsetDateTime
.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
发送到数据库。
myPreparedStatement.setObject( … , odt ) ;
检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
如果必须使用java.util.Date
与尚未更新为java.time的旧代码进行互操作,可以来回转换。查看添加到旧 classes 的新 to…
和 from…
方法。
java.util.Date d = Date.from( odt.toInstant() ) ;
java.util.Date d = Date.from( zdt.toInstant() ) ;
走向另一个方向。
Instant instant = myJavaUtilDate.toInstant() ;
所有这些主题都已在 Stack Overflow 上多次提及。搜索以了解更多信息。