在 Java 如何检查字符串(保存日期时间值)是否符合日期时间格式 YYYYMMDDTHHMMSSZ
In Java how to check if a string(holding datetime value) is according to datetime format YYYYMMDDTHHMMSSZ
我有一个字符串 billedDate,它存储来自输入的日期时间值。我需要检查它是否有效,并根据日期时间格式 YYYYMMDDTHHMMSSZ 是否有任何我可以使用的功能?对于十进制字段,我使用的是 NumberUtils.isParsable,它为该字段返回 true 或 false。
解决方案似乎是使用 java 的 SimpleDateFormat
。
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
Date parsed = format.parse("11111111T111111Z");
我还建议改用 ISO 日期格式。它就像您建议的格式,但有一些额外的间隔符以使其更适合未来和人类可读。
Yours: yyyyMMdd'T'HHmmss'Z'
ISO: yyyy-MM-dd'T'HH:mm'Z'
参考:
使用java.time.format.DateTimeFormatter解析字符串。捕获解析异常并将其作为否定响应处理。
P.S。当 java.time.* 存在时,没有充分的理由使用 SimpleDateFormat、java.util.Date 或 java.util.Calendar,所以请不要使用。
java.time
我推荐 java.time,现代 Java 日期和时间 API,用于您的日期和时间工作。我建议:
private static final DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmssX")
.withResolverStyle(ResolverStyle.STRICT);
public static boolean isParseableBasicIso8601(String str) {
try {
OffsetDateTime odt = OffsetDateTime.parse(str, formatter);
return odt.getOffset().equals(ZoneOffset.UTC);
} catch (DateTimeParseException dtpe) {
return false;
}
}
尝试一下:
String[] testStrings = {
"20210223T234556Z",
"Cannot be parsed",
"20210229T234556Z",
"20210223T234556+08",
"20210223T234556+00",
};
for (String s : testStrings) {
System.out.format("%-18s? %s%n", s, isParseableBasicIso8601(s));
}
输出为:
20210223T234556Z ? true
Cannot be parsed ? false
20210229T234556Z ? false
20210223T234556+08? false
20210223T234556+00? true
第三个例子表明Java知道2021年不是闰年。 ResolverStyle.STRICT
导致它拒绝 2 月 29 日。在第四个示例中,UTC 偏移量是错误的。接受最后一个例子不是你要求的。在 ISO 8601 格式(您的格式是)中,UTC 的零偏移量通常表示为 Z
,但也接受 +00
。如果你想拒绝这个,解决方案在 Mad Programmer 的评论中:使用相同的格式化程序格式化日期时间,并且仅在两个字符串相等时才接受。
考虑添加范围检查并拒绝过去或未来过远的日期和时间。使用OffsetDateTime.isBefore()
或isAfter()
进行比较。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
我有一个字符串 billedDate,它存储来自输入的日期时间值。我需要检查它是否有效,并根据日期时间格式 YYYYMMDDTHHMMSSZ 是否有任何我可以使用的功能?对于十进制字段,我使用的是 NumberUtils.isParsable,它为该字段返回 true 或 false。
解决方案似乎是使用 java 的 SimpleDateFormat
。
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
Date parsed = format.parse("11111111T111111Z");
我还建议改用 ISO 日期格式。它就像您建议的格式,但有一些额外的间隔符以使其更适合未来和人类可读。
Yours: yyyyMMdd'T'HHmmss'Z'
ISO: yyyy-MM-dd'T'HH:mm'Z'
参考:
使用java.time.format.DateTimeFormatter解析字符串。捕获解析异常并将其作为否定响应处理。
P.S。当 java.time.* 存在时,没有充分的理由使用 SimpleDateFormat、java.util.Date 或 java.util.Calendar,所以请不要使用。
java.time
我推荐 java.time,现代 Java 日期和时间 API,用于您的日期和时间工作。我建议:
private static final DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmssX")
.withResolverStyle(ResolverStyle.STRICT);
public static boolean isParseableBasicIso8601(String str) {
try {
OffsetDateTime odt = OffsetDateTime.parse(str, formatter);
return odt.getOffset().equals(ZoneOffset.UTC);
} catch (DateTimeParseException dtpe) {
return false;
}
}
尝试一下:
String[] testStrings = {
"20210223T234556Z",
"Cannot be parsed",
"20210229T234556Z",
"20210223T234556+08",
"20210223T234556+00",
};
for (String s : testStrings) {
System.out.format("%-18s? %s%n", s, isParseableBasicIso8601(s));
}
输出为:
20210223T234556Z ? true Cannot be parsed ? false 20210229T234556Z ? false 20210223T234556+08? false 20210223T234556+00? true
第三个例子表明Java知道2021年不是闰年。 ResolverStyle.STRICT
导致它拒绝 2 月 29 日。在第四个示例中,UTC 偏移量是错误的。接受最后一个例子不是你要求的。在 ISO 8601 格式(您的格式是)中,UTC 的零偏移量通常表示为 Z
,但也接受 +00
。如果你想拒绝这个,解决方案在 Mad Programmer 的评论中:使用相同的格式化程序格式化日期时间,并且仅在两个字符串相等时才接受。
考虑添加范围检查并拒绝过去或未来过远的日期和时间。使用OffsetDateTime.isBefore()
或isAfter()
进行比较。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601