【问题标题】:Joda Time: Parse string and override time zone, if time zone is omittedJoda Time:如果省略时区,则解析字符串并覆盖时区
【发布时间】:2014-05-19 22:46:27
【问题描述】:

这是我的场景:我想解析用户给我的时间戳。如果时间戳没有时区信息,我想假设时间戳在用户的时区中,如果时间戳确实定义了它的时区,请使用它。

以下是让它变得困难的部分:

  • 我无法设置 DateTimeZone.setDefault(UserTimeZone) 因为这会影响服务器上的所有用户,如下所示:Switch Timezone for calculation
  • 我不能使用 withOffsetParsed(),因为它没有告诉我用户是否明确设置了时区,或者它回退到默认值。
  • 我不能使用 withZone(),因为它会覆盖字符串中的任何时区信息。

我想要的是这样的:

DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser()
DateTimeZone userTimeZone = getUserTimeZone(); //assume -04:00

//returns 2014-05-17T15:36:14+02:00
parser.parseDateTime("2014-05-17T15:36:14+02:00", userTimeZone); 

//returns 2014-05-17T15:36:14-04:00
parser.hasTimeZone("2014-05-17T15:36:14", userTimeZone);

有什么简单的方法吗?

【问题讨论】:

  • 不,与TZ打交道是A的痛苦

标签: java time timezone jodatime


【解决方案1】:

我会将这个问题分为两部分。第一部分是确定字符串中是否包含时区信息。第二种是按照你想要的方式解析字符串。

我相信以下内容适用于第一部分。首先,创建两个具有不同时区的 DateTimeFormatter 对象。现在,用两个对象解析字符串。现在对两个结果调用 getDate()。如果两个日期相同,则字符串中包含一个时区,并指定了一个即时时间,这两个 DateTimeFormatter 对象都对其进行了适当的调整。如果日期不同,则字符串中没有时区,并指定一个本地日期和时间,每个 DateTimeFormatter 都将其假定为自己的时区。

现在您可以执行第二部分,根据字符串是否具有时区,选择是在用户的时区中使用 DateTimeFormatter withOffsetParsed() 还是 withZone()。

这需要四个不同的 DateTimeFormatter 对象,但即使不简单也很简单。可以将其优化为仅使用三个不同的 DateTimeFormatter 对象,方法是使用用户时区作为解决方案第一部分中使用的两个对象之一 - 在这种情况下,您必须在解决方案的第二部分重新解析仅当字符串中包含时区时。

【讨论】:

  • 无需致电getDate。 DateTime 对象包含一个isEqual 方法。
  • 感谢@warren,但是如果两个日期对象根据时间戳中是否存在时区信息进行不同的解析,那么它们已经在做我想做的事,而我没有需要比较值。
【解决方案2】:

事实证明我对 withZone() 的工作方式是错误的。如果时间戳中指定了时区信息,它只会调整年表,但从纪元开始的底层毫秒数仍然相同,但如果时间戳中没有设置时区,则会偏移毫秒数从 epoch 开始,使给定时区的时间正确。

我想自从 Joda Time 文档说,

解析时,该区域将设置在解析的日期时间。

它会覆盖时区,但我错了。 withZone() 正是我所需要的。

这是我最终使用的代码:

DateTimeZone timeZone = user.getTimeZone();
DateTime dateTime = ColumnTypeUtil.DATE_FORMATTER.withZone(timeZone).parseDateTime(formattedValue);
String dbTimeStamp = ISODateTimeFormat.dateTime().withZone(DateTimeZone.UTC).print( dateTime );

【讨论】:

    猜你喜欢
    • 2013-10-07
    • 2013-05-23
    • 1970-01-01
    • 2020-06-24
    • 2012-07-22
    • 1970-01-01
    • 2010-11-22
    • 2014-08-20
    • 1970-01-01
    相关资源
    最近更新 更多