【问题标题】:How to parse a date with timezone only, in Joda-Time?如何在 Joda-Time 中仅解析带有时区的日期?
【发布时间】:2014-08-20 19:29:19
【问题描述】:

我想使用Joda-Time 来解析带有可选时区的日期:2014-08-08+02:00

我尝试了ISODateTimeFormat.dateTimeParser().parseDateTime(date);,但这给了我以下错误:

java.lang.IllegalArgumentException: Invalid format: "2014-08-08+02:00" is malformed at "+02:00"

【问题讨论】:

  • 我认为您在日期和偏移量之间缺少T
  • 肯定不是我想解析这个字符串(我自己不生成字符串,否则我可以直接创建joda date)
  • 好的,将我的评论解释为“如果你打算使用该解析器,你需要一个T”。我怀疑您必须自己定义 - 尝试查看此内容以获得灵感:How can I parse a date including timezone with Joda Time
  • 哦,好吧,我认为 joda 能够检测到 self 格式。
  • 我不是 Joda 专家 - 也许有人可以帮助您找到自动完成的东西。但是ISODateTimeFormat.dateTimeParser() 的 Javadocs 对接受的内容非常清楚,而您的字符串不是。

标签: java jodatime


【解决方案1】:

我不知道有比拥有多个模式并依次解析它们更好的方法来处理可选数据。请参阅下面的代码示例:

public static void main(String[] args) throws Exception {
  System.out.println(parseWithOptionalTZ("2014-08-08+02:00"));
  System.out.println(parseWithOptionalTZ("2014-08-08"));
}

private static DateTime parseWithOptionalTZ(String date) {
  DateTimeFormatter[] formatters = { 
      DateTimeFormat.forPattern("YYYY-MM-dd"),
      DateTimeFormat.forPattern("YYYY-MM-ddZ") 
  };

  for (DateTimeFormatter dateTimeFormatter : formatters) {
    try {
      return dateTimeFormatter.parseDateTime(date);
    } catch (IllegalArgumentException e) {
      // ignore
    }
  }

  throw new IllegalArgumentException("Could not parse: " + date);
}

输出:

2014-08-07T23:00:00.000+01:00 2014-08-08T00:00:00.000+01:00

【讨论】:

    【解决方案2】:

    时区至关重要

    不要忽略时区或偏移量,如 cmets 中所述。

    忽略日期时间的时区就像忽略温度读数的 C/F(摄氏度/华氏度)或忽略文本的字符集编码。你会误解你的数据。

    时区解析

    在解析期间指定时区可以在 Joda-Time 中产生两种不同的效果。仔细考虑一下,您会发现这是合乎逻辑的,并且做的是正确的事情。

    解析后

    如果您在解析输入包含偏移量或时区的格式化程序上指定时区,那么 Joda-Time 会在解析过程中注意包含的偏移量。 之后确定日期时间(它落在宇宙时间线上的位置,定义为自 1970 年初以来在 UTC 时区的毫秒数,即无时区),然后您指定时区分配给 DateTime 对象。在这种情况下,通过指定的时区不会影响解析。指定的时区会影响该日期时间值的字符串 representations 的生成。

    解析期间

    另一方面,如果您在解析输入缺少任何偏移量或时区信息的格式化程序上指定时间,那么 Joda-Time 会使用您指定的时区 /em> 输入字符串的解析。

    示例代码,Joda-Time

    这是使用Joda-Time 2.3 的示例代码。首先是正确的方法,在解析字符串时使用偏移量。其次是错误的方式,忽略了偏移量。请注意不同的结果、不同的日期时间值,甚至可能不同的日期(取决于用于创建字符串表示的时区)。

    带偏移

    String input = "2014-08-08+02:00";
    DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MM-ddZ" ).withZone( DateTimeZone.UTC );
    DateTime dateTimeUsingOffset = formatter.parseDateTime( input ); // Offset used to determine date-time during parsing. After parsing the UTC time zone is assigned.
    

    无偏移

    String inputTruncatedOffset = input.substring( 0, 10 );
    DateTime dateTimeIgnoringOffset = new DateTime( inputTruncatedOffset, DateTimeZone.UTC ); // In contrast to above, the UTC time zone is used *during* parsing to determine date-time as the input string contained no hint about offset or time zone.
    

    转储到控制台。

    System.out.println( "input: " + input );
    System.out.println( "dateTimeUsingOffset: " + dateTimeUsingOffset );
    
    System.out.println( "inputTruncatedOffset: " + inputTruncatedOffset );
    System.out.println( "dateTimeIgnoringOffset: " + dateTimeIgnoringOffset );
    

    运行时。

    input: 2014-08-08+02:00
    dateTimeUsingOffset: 2014-08-07T22:00:00.000Z
    
    inputTruncatedOffset: 2014-08-08
    dateTimeIgnoringOffset: 2014-08-08T00:00:00.000Z
    

    【讨论】:

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