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

时间:2014-05-19 22:46:28

标签: java time timezone jodatime

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

以下是使其变得困难的部分:

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

我想要的是:

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

有没有简单的方法可以做到这一点?

2 个答案:

答案 0 :(得分:1)

我会将这个问题分成两部分。第一部分是弄清楚字符串中是否有时区信息。第二种是按照你想要的方式解析字符串。

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

现在你可以做第二部分,选择是否在用户的时区使用DateTimeFormatter withOffsetParsed()或withZone(),具体取决于字符串是否具有时区。

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

答案 1 :(得分:0)

事实证明我对withZone()的工作方式错了。如果在时间戳中指定了时区信息,它将仅调整时间轴,但是自纪元以来的基础毫秒仍将是相同的,但如果时间戳中未设置时区,则它将抵消毫秒因为时间使得给定时区的时间正确。

我认为自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 );