时区转换-CST到UTC

时间:2019-01-23 22:16:13

标签: java-8

我在中央时间有一个日期值

字符串cstDate =“ 02-JAN-19 03.34.33.540260000 AM”;

我必须将上述字符串值转换为UTC格式。我正在使用Java 1.8,并使用了ZonedDateTime。

请找到以下代码。

String DATE_FORMAT = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a";      
String cstDate =  "02-JAN-19 03.34.33.540260000 AM";
LocalDateTime ldt = LocalDateTime.parse(cstDate,DateTimeFormatter.ofPattern(DATE_FORMAT));
ZonedDateTime utcDateTime = ldt.atZone(ZoneId.of("UTC"));        //CST+6
System.out.println("cst : " + cstDate);
System.out.println("utc : " + utcDateTime);

但出现异常:无法在索引3处解析文本'02 -JAN-19 03.34.33.540260000 AM'

不理解为什么我会收到此异常。

谢谢

1 个答案:

答案 0 :(得分:1)

tl; dr

您的JAN值未正确本地化为英语,因此我们必须使用DateTimeFormatter类通过builder pattern使用DateTimeFormatterBuilder类生成的更具定制性的LocalDateTime对象进行解析,区分大小写。

UTC

UTC不是“格式”。 UTC是我们衡量全球时区的基准。所有时区都比UTC早或晚一些小时-分钟-秒。在Royal Observatory, Greenwich处分界点以东的时区在UTC之前,而在西部的时区在后面。零偏移是UTC本身。

LocalDateTime

您的输入字符串缺少时区或UTC偏移量的指示符。这是不好的做法,因为该值是模棱两可的。没有区域或偏移量,我们必须将其解析为DateTimeFormatterBuilder对象。

我们指定了一种格式设置以匹配您的输入。顺便说一句,您选择的输入字符串格式不是最佳选择。尽可能使用标准ISO 8601格式。

JAN

您输入的String input = "02-JAN-19 03.34.33.540260000 AM" ; DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder() .parseCaseInsensitive() .appendPattern( "dd-MMM-uu hh.mm.ss.SSSSSSSSS a" ) ; DateTimeFormatter f = builder.toFormatter( Locale.US ) ; LocalDateTime ldt = LocalDateTime.parse( input , f ) ; 对美国和英国以及其他可能的国家/地区来说是错误的本地化。因此,我们不能依赖通常的解析。我们必须指出不区分大小写的解析。为此,我们必须使用build up类来DateTimeFormatter一个DateTimeFormatterBuilder对象。

LocalDateTime
  

ldt.toString():2019-01-02T03:34:33.540260

缺少任何时区或与UTC的偏移量的概念,这意味着我们的ZonedDateTime现在不是时间点,不是时间点上的时间点。它表示26-27小时(全球时区范围)内的潜在时刻。要确定时刻,我们必须分配一个偏移量或区域。

CST

您声称知道此输入字符串旨在表示CST中的时刻。不幸的是,Continent/Region不是实时区域。切勿使用这些2-4个字符的伪区域,因为它们不是标准化的-它们甚至都不是唯一的!您是说中国标准时间吗?也许中部标准时间在美洲?

Real time zones的名称为America/Chicago。我猜您指的是一个时区,例如+6。您有评论提到偏移-06:00…是指America/Chicago在冬天使用ZoneId z = ZoneId.of( "America/Chicago" ) ; 吗?

LocalDateTime

将此时区应用于我们的ZonedDateTime以获得代表实际时刻的ZonedDateTime zdt = ldt.atZone( z ) ;

Instant
  

zdt.toString():2019-01-02T03:34:33.540260-06:00 [美国/芝加哥]

要看到与UTC相同的时刻,请提取InstantInstant instant = zdt.toInstant() ; 代表UTC中的时刻,始终代表UTC。

OffsetDateTime
  

instant.toString():2019-01-02T09:34:33.540260Z

请参阅此code run live at IdeOne.com

OffsetDateTime

您的问题不清楚。如果您知道输入字符串以UTC表示时刻,则解析为OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;

America/Chicago

调整到ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; 时区。相同的时刻,不同的时钟时间。

java.sql.*

关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要{{1}}类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore