【问题标题】:Two different result about DateTimeZone.forID关于 DateTimeZone.forID 的两个不同结果
【发布时间】:2020-05-19 01:02:35
【问题描述】:

我有这部分代码用于获取 DateTimeZone 的联合国 ID

String timeZoneId = Calendar.getInstance().getTimeZone().getID();
DateTimeZone desTimeZone = DateTimeZone.forID(timeZoneId);

在war文件中执行这部分代码时,得到timeZoneId = "GMT+01:00"

但是当我在 main 方法中运行这部分代码时,我得到了 timeZoneId = "Europe/Paris"

第一个在第二行引发异常: 无法识别日期时区 id 'GMT+01:00'

我不知道为什么我有两个不同的结果!!!

如何在war文件和main方法(欧洲/巴黎)中得到相同的结果?

谢谢

编辑:添加方法的完整代码:

public static DateTime toLocalDateTime(String gmtDate) {

if (StringUtils.isBlank(gmtDate)) {
    return null;
}

DateTime gmt = new DateTime(gmtDate, DateTimeZone.UTC);

String timeZoneId =  Calendar.getInstance().getTimeZone().getID();
DateTimeZone desTimeZone = DateTimeZone.forID(timeZoneId);
DateTimeZone.setDefault(desTimeZone);
LocalDateTime locDateTime = gmt.withZone(DateTimeZone.getDefault()).toLocalDateTime();

return locDateTime.toDateTime();

}

【问题讨论】:

  • 我想您不想在代码中只硬编码时区 ID?那你想要什么?
  • 我想当我打电话给 DateTimeZone.forID(timeZoneId) 我得到“欧洲/巴黎”或其他 id 取决于城市
  • 所以你想要系统默认时区?
  • 我添加了完整的方法以更清晰
  • gmtDate 到底是什么?

标签: java datetime jodatime


【解决方案1】:

tl;博士

使用现代的 java.time 类来替换您在代码中混合的两个框架。

java.time.Instant
.parse( "2020-02-03T10:09:21.154Z" ) 
.atZone(
    ZoneId.of( "Europe/Paris" )
)

详情

您没有提供足够的详细信息来做出明确的诊断。你需要准确描述你是如何运行的,具体是什么代码。

我不确定是否值得努力解决这个问题,原因有两个:

  • 您正在使用Calendar,这是一个糟糕的类,它是多年前被 JSR 310 中定义的现代 java.time 类取代的原始日期-日期时间类的一部分。李>
  • 您正在使用来自 Joda-TimeDateTimeZone,它是那些 java.time 类的前身。此项目现在处于维护模式。

java.time

所以改为使用 java.time

获取 JVM 当前的默认时区。

ZoneId z = ZoneId.systemDefault() ;

如果您想知道该区域当前使用的偏移量,请使用ZoneRules

ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;

明确区域与偏移。偏移量只是本初子午线之前或之后的小时-分钟-秒数。偏移量看起来像+05:30。时区更多。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。时区名称的格式为Continent/Region

ISO 8601 字符串

如果以标准 ISO 8601 格式给出文本,例如 2020-02-03T10:09:21.154Z,请理解这代表 UTC 的时刻,即与 UTC 的偏移量为零时分秒。末尾的Z 表示UTC,发音为“Zulu”。

将此类输入解析为java.time.Instant。本课程介绍 UTC 时间。

Instant instant = Instant.parse( "2020-02-03T10:09:21.154Z" ) ;

要通过时区的挂钟时间查看这一时刻,请应用ZoneId 以获取ZonedDateTime

ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

instantzdt 对象都代表同一时刻,时间轴上的同一点。

时刻

在跟踪时刻、时间轴上的特定点时,切勿使用LocalDateTime。在 Joda-Time 和 java.time 框架中,该类表示具有时间的日期,但缺少任何区域或偏移量的概念。缺乏这种背景,那个类不能代表一个时刻。

【讨论】:

  • 我在帖子中添加了更多详细信息以及方法的完整代码
  • 感谢 Basil,我通过用 ZoneId 替换 Calendar.getInstance().getTimeZone().getID() 解决了这个问题
猜你喜欢
  • 1970-01-01
  • 2010-09-26
  • 2019-02-12
  • 2013-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多