如何检查 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
如果您输入的字符串缺少任何偏移量或时区信息,则它被认为是“本地”日期时间。这意味着它不是时间轴上的一个特定时刻,而是一个关于可能时刻的粗略想法。在您应用偏移量或时区之前没有实际意义。
LocalDateTime
class处理这种值。
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就是一个例子。
给定一个像这样的 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
如果您输入的字符串缺少任何偏移量或时区信息,则它被认为是“本地”日期时间。这意味着它不是时间轴上的一个特定时刻,而是一个关于可能时刻的粗略想法。在您应用偏移量或时区之前没有实际意义。
LocalDateTime
class处理这种值。
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就是一个例子。