gpt4 book ai didi

SimpleDateFormat 在解析过程中返回错误的时区

转载 作者:行者123 更新时间:2023-12-01 02:26:19 28 4
gpt4 key购买 nike

在创建 Date 对象期间,我遇到了一个奇怪的问题。我有以下代码将日期的时区设置为 UTC。在解析语句之前,我看到 sdfDate 的时区为 UTC,但在解析语句之后,我看到 PunchDate 具有值:Sat Mar 30 01:00:00 CET 2013,我相信这来自我的系统。但是我如何确保即使在解析后时区也保持不变。

Date punchDate = null;
Date punchTime = null;

SimpleDateFormat sdfDate = new SimpleDateFormat("dd.MM.yyyy");
SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");

try
{
sdfDate.setTimeZone(TimeZone.getTimeZone("UTC"));
sdfTime.setTimeZone(TimeZone.getTimeZone("UTC"));
punchDate = sdfDate.parse(arg1);
punchTime = sdfTime.parse(arg2);
}
catch (ParseException pe)
{
System.out.println("Parse exception " +pe.getMessage());
}

我的要求基本上是我需要从字符串输入创建一个日期对象,但时区应保持为 UTC。

最佳答案

tl;博士

i need to make a Date Object from String input but the time zone should remain UTC.


LocalDate.parse( 
"23.01.2017" ,
DateTimeFormatter.ofPattern( "dd.MM.uuuu" )
)

…和…
LocalTime.parse( "12:34:56" ) 

…结合…
OffsetDateTime.of( datePart , timePart , ZoneOffset.UTC )

细节

您正在使用令人困惑的旧日期时间类,这些类现在已被 java.time 类取代。
OffsetDateTime
你说你确定你的输入是为 UTC 而设计的,尽管没有这样的指标。因此,我们将解析日期部分,解析时间部分,然后在为 offset-from-UTC 分配 UTC 为零的同时进行组合。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd.MM.uuuu" ) ;
LocalDate ld = LocalDate.parse( "23.01.2017" , f ) ;

时间输入恰好符合 java.time 类中默认使用的标准 ISO 8601 格式。所以不需要指定格式模式。
LocalTime lt = LocalTime.parse( "12:34:56" ) ;

结合。
OffsetDateTime odt = OffsetDateTime.of( ld , lt , ZoneOffset.UTC ) ;

时区

如果您想看到与特定区域的挂钟时间相同的时刻,请应用 ZoneId 以获取 ZonedDateTime

continent/region 的格式指定 proper time zone name ,例如 America/Montreal Africa/Casablanca Pacific/Auckland 。永远不要使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; // Same simultaneous moment, same point on the timeline.

ISO 8601

提示:要将此类数据作为文本交换,请专门使用标准的 ISO 8601 格式。这些格式被巧妙地设计为明确的,易于机器处理,并且易于人们在多种文化中阅读。

java.time 类在解析和生成字符串时默认使用标准格式。
String output = Instant.now().toString() ;  

2017-01-23T12:34:56.123456789Z



转变

避免使用遗留的 java.util.Date 类。但如果你必须,你可以转换。寻找添加到旧类中的新方法。

Instant 类表示 UTC 中时间轴上的一个时刻,分辨率为 nanoseconds(最多九 (9) 位小数)。

通过调用 InstantOffsetDateTime 中提取 toString 对象。
Instant instant = odt.toInstant() ;
java.util.Date date = Date.fromInstant( instant ) ;

……反其道而行之……
Instant instant = myJavaUtilDate.toInstant() ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

关于 java.time

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

Joda-Time 项目,现在在 maintenance mode 中,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle Tutorial 。并在 Stack Overflow 上搜索许多示例和解释。规范是 JSR 310

从哪里获得 java.time 类?
  • Java SE 8Java SE 9 和更高版本
  • 内置。
  • 具有捆绑实现的标准 Java API 的一部分。
  • Java 9 添加了一些小功能和修复。
  • Java SE 6Java SE 7
  • java.time 的大部分功能在 ThreeTen-Backport 中向后移植到 Java 6 和 7。
  • Android
  • ThreeTenABP 项目专门为 Android 适配了 ThreeTen-Backport(上面提到的)。
  • 参见 How to use ThreeTenABP…

  • ThreeTen-Extra 项目使用附加类扩展了 java.time。该项目是 future 可能添加到 java.time 的试验场。您可能会在这里找到一些有用的类,例如 Interval YearWeek YearQuarter more

    关于SimpleDateFormat 在解析过程中返回错误的时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16107898/

    28 4 0
    文章推荐: angularjs - 使用异步数据设置默认