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

How to check if an offset is there in an ISO date string

给定一个像这样的 ISO 字符串

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

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

这是我到目前为止所做的代码,如果存在偏移量则获取偏移量

public static String getDateTimeWithTimeZoneOffset(String dateTimeString)
    {
        DateTimeFormatter df = ISODateTimeFormat.dateTimeParser().withOffsetParsed();
        DateTime nDt = df.parseDateTime(dateTimeString);
        DateTimeFormatter dateFormatterWithoutMillis = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss");
        return dateFormatterWithoutMillis.print(nDt) + SPACE + nDt.getZone();
    }

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

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

但是当我有一个没有偏移量的字符串时,如下图所示

2016-07-11T16:50:22

相同的代码采用默认时区并像这样打印

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

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

试试这个:

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

}

java.time

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

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

java.time 框架内置于 Java 8 及更高版本中。这些 classes 取代了旧的麻烦的日期时间 classes,例如 java.util.Date 以及非常成功的第 3 方 Joda-Time 库。请参阅 Oracle 教程。 java.time 的大部分功能在 ThreeTen-Backport 中被反向移植到 Java 6 和 7,并进一步适应 中的 Android ]ThreeTenABP.

OffsetDateTime

OffsetDateTime class represents a moment on the timeline with an assigned offset-from-UTC. The offset is represented by the ZoneOffset class.

LocalDateTime

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

LocalDateTimeclass处理这种值。

ISO 8601

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

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

示例代码

这里的策略是尝试像输入字符串包含偏移量一样进行解析。如果不是,则抛出异常 (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.

input: 2016-07-11T16:50:22.00+05:00 | hasOffset: true | odt: 2016-07-11T16:50:22+05:00 | offset: +05:00

当 运行 与 2016-07-11T16:50:22.00.

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

长度测试

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

你可以这样做:

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

HERE就是一个例子。