如何检查ISO日期字符串中是否存在偏移量

时间:2016-07-13 19:56:04

标签: java date datetime jodatime iso8601

给出像这样的ISO字符串

let facebookLogin =  FBSDKLoginManager()

@IBAction func fbBtnPressed(sender: UIButton!) {

    facebookLogin.logIn(withReadPermissions: [ "email" ], from: self) { (facebookResult: FBSDKLoginManagerLoginResult?, facebookError:NSError?) in

        // ...    
    }
}

有没有办法在特定字符串中找到偏移量或不使用joda?

这就是我到目前为止所做的代码,如果存在一个偏移量,那么

String dateTime = "2016-07-11T16:50:22.00+05:00";

上面的代码给出了以下输出

  

2016-07-11T16:50:22 +05:00

但是当我有一个没有偏移的字符串时,如下面的

  

2016-07-11T16:50:22

相同的代码采用默认时区并打印如下

  

2016-07-11T16:50:22 America / Chicago

无论如何我可以检查字符串中是否存在偏移量,如果没有抛出异常?

3 个答案:

答案 0 :(得分:4)

java.time

Joda-Time开发团队建议迁移到java.time类:

  

Joda-Time是Java SE 8之前Java的事实标准日期和时间库。现在要求用户迁移到java.time(JSR-310)。

Java 8及更高版本中内置的java.time框架。这些类取代了旧的麻烦的日期时间类,如java.util.Date以及非常成功的第三方Joda-Time库。见Oracle Tutorial。许多java.time功能都被反向移植到Java 6& ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。

OffsetDateTime

OffsetDateTime类代表时间轴上的一个时刻,并指定了offset-from-UTC。偏移量由ZoneOffset类表示。

LocalDateTime

如果您的输入字符串缺少任何偏移或时区信息,则会将其视为“本地”日期时间。这意味着它是时间轴上的特定时刻,而是对可能时刻的粗略想法。在应用偏移或时区之前没有实际意义。

LocalDateTime类处理这种值。

ISO 8601

您的输入字符串恰好符合日期时间文本格式的ISO 8601标准。

在解析/生成表示日期时间值的字符串时,java.time类默认使用这些标准格式。因此,您可以直接解析输入字符串而无需定义格式化模式。

示例代码

此处的策略是尝试解析,就好像输入字符串包含偏移量一样。如果不是,则抛出异常(DateTimeParseException)。在这种情况下,我们再次尝试解析,但作为LocalDateTime值。如果第二次尝试抛出解析异常,则输入完全是意外的。

一些编码原教旨主义者会抗议使用嵌套异常测试。虽然我理解他们的担忧,因为这种方法可能被滥用,但在这种特殊情况下,我维护嵌套异常测试是可接受的,合乎逻辑的,清晰的。

String input = "2016-07-11T16:50:22.00"; // "2016-07-11T16:50:22.00+05:00";
Boolean hasOffset = null;
try {
    OffsetDateTime odt = OffsetDateTime.parse ( input );
    hasOffset = Boolean.TRUE;
    ZoneOffset offset = odt.getOffset ();
    System.out.println ( "input: " + input + " | hasOffset: " + hasOffset + " | odt: " + odt + " | offset: " + offset );
} catch ( java.time.format.DateTimeParseException e1 ) {
    // Perhaps input lacks offset-from-UTC. Try parsing as a local date-time.
    try {
        LocalDateTime ldt = LocalDateTime.parse ( input );
        hasOffset = Boolean.FALSE;
        System.out.println ( "input: " + input + " | hasOffset: " + hasOffset + " | ldt: " + ldt );
    } catch ( java.time.format.DateTimeParseException e2 ) {
        System.out.println ( "ERROR - Unexpected format in the input string" ); // FIXME: Handle format exception.
    }
}

使用2016-07-11T16:50:22.00+05:00运行时。

  

输入:2016-07-11T16:50:22.00 + 05:00 | hasOffset:true | odt:2016-07-11T16:50:22 + 05:00 |偏移量:+05:00

使用2016-07-11T16:50:22.00运行时。

  

输入:2016-07-11T16:50:22.00 | hasOffset:false | ldt:2016-07-11T16:50:22

长度测试

当然,你总是可以测试输入字符串的长度。根据您的示例输入,具有偏移的那些将比没有偏移的那些更长。如果您有多种输入,这种长度测试可能很脆弱或容易出错。

答案 1 :(得分:1)

试试这个:

String dateWithoutMillis = dateFormatterWithoutMillis.print(nDt) + SPACE + nDt.getZone();
if (dateWithoutMillis.contains("/") {
  throw new InvalidDateStringException("NO OFFSET");
} else {
  return dateWithoutMillis
}

不要忘记添加例外:

public static class InvalidDateStringException extends Exception {

    public InvalidDateStringException(String message){
        super(message);
    }

}

答案 2 :(得分:1)

您可以这样做:

if(dateTimeString.matches(".*(\\+|-)\\d{2}(:?\\d{2})?$")){
    // has offset.
}

HERE就是一个例子。