Joda Time:如果省略了时区,则解析字符串并覆盖时区



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

这是让它变得困难的部分:

  • 我不能设置DateTimeZone.setDefault(UserTimeZone),因为这会影响服务器上的所有用户,正如这里所证明的:
  • 我不能使用withthoffsetparsed(),因为它没有告诉我用户是否显式设置时区或它回落到默认值。
  • 我不能使用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);

有什么简单的方法吗?

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

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

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

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

事实证明,我对withZone()的工作方式是错误的。如果在时间戳中指定了时区信息,它将只调整时间顺序,但由于epoch的基础毫秒数仍将相同,但如果在时间戳中未设置时区,它将偏移自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 );

相关内容

  • 没有找到相关文章

最新更新