当前位置: 首页 > 知识库问答 >
问题:

TimeZoneConversion-CST到UTC

孟凯泽
2023-03-14

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

String cstDate="02-JAN-1903.34.33.540260000 AM";

我必须将上述字符串值转换为UTC格式。我使用的是Java 1.8和ZoneDateTime。

请查找以下代码。

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个答案

史弘致
2023-03-14

您的JAN值未正确本地化为英语,因此我们必须使用DateTimeFormatterBuilder类通过构建器模式生成的更自定义的DateTimeFormatterBuilder对象进行解析,以不区分大小写。

世界协调时不是一种“格式”。世界协调时是我们衡量全球时区的基准。所有时区都比世界协调时早或晚一些小时-分钟-秒。格林威治皇家天文台分界点以东的时区领先于世界协调时,西边的时区落后于世界协调时。零偏移量是世界协调时本身。

您的输入字符串缺少时区指示符或UTC偏移量。这是不好的做法,因为值不明确。如果没有区域或偏移量,我们必须解析为LocalDateTime对象。

我们指定了一种格式模式来匹配您的输入。顺便说一句,您对输入字符串格式的选择并不理想。尽可能使用标准ISO 8601格式。

您输入的1月本地化值不正确,适用于美国和英国以及其他国家。因此,我们不能依赖于通常的解析。我们必须以不区分大小写的方式指示解析。为此,我们必须使用DateTimeFormatterBuilder类来构建DateTimeFormatter对象。

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 ) ;

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

缺少任何时区或UTC偏移的概念意味着我们的LocalDateTime不是一个时刻,也不是时间线上的一个点。它表示26-27小时(全球时区范围)内的潜在时刻。要确定力矩,必须指定偏移或分区。

您声称知道此输入字符串表示CST中的一个时刻。遗憾的是,CST不是实时时区。千万不要使用这些2-4个字符的伪区域,因为它们不是标准化的,甚至不是唯一的!你是说中国标准时间吗?也许是美洲的中央标准时间?

实时时区的名称为大陆/地区格式。我猜你指的是像美国/芝加哥这样的时区。您的评论提到偏移量为6……您是指美国/芝加哥在冬季使用的06:00吗?

ZoneId z = ZoneId.of( "America/Chicago" ) ;

将此时区应用于我们的LocalDateTime,以获取表示实际时刻的ZoneDateTime。

ZonedDateTime zdt = ldt.atZone( z ) ;

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

要查看与UTC相同的时刻,请提取一个瞬间。瞬间表示UTC中的一个时刻,始终为UTC。

Instant instant = zdt.toInstant() ;

瞬间toString():2019-01-02T09:34:33.540260Z

查看此代码在IdeOne上实时运行。通用域名格式。

你的问题不清楚。如果您的意思是输入字符串表示UTC中的某个时刻,请将其解析为OffsetDateTime。

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;

调整到美国/芝加哥时区。相同的时刻,不同的挂钟时间。

ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

java.time框架内置于Java8及更高版本中,这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendar

现在处于维护模式的Joda Time项目建议迁移到java。时间类。

要了解更多信息,请参阅Oracle教程。并在Stack Overflow中搜索许多示例和说明。规范是JSR 310。

您可以交换java。直接使用数据库创建时间对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,也不需要java。sql* 类。

从何处获取java。时间课程?

  • Java SE 8、Java SE 9、Java SE 10、Java SE 11及更高版本—标准Java API的一部分,带有捆绑实现。
    • Java 9添加了一些次要功能和修复
    • 大部分java。时间功能后移植到Java 6
    • java.time类的Android捆绑包实现的最新版本。
    • 对于早期的Android(

    ThreeTen额外项目扩展了java。额外上课的时间。该项目是java未来可能添加内容的试验场。时间您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter等。

 类似资料: