我工作的支持日期作为查询参数一个REST API。 既然是查询参数将是字符串。 现在,日期可以在QueryParams以下格式发送:
yyyy-mm-dd[(T| )HH:MM:SS[.fff]][(+|-)NNNN]
这意味着以下是有效日期:
2017-05-05 00:00:00.000+0000
2017-05-05 00:00:00.000
2017-05-05T00:00:00
2017-05-05+0000
2017-05-05
现在来分析所有这些不同的日期时间我使用Java8 datetime
API。 该代码是,如下所示:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("yyyy-MM-dd[[ ][['T'][ ]HH:mm:ss[.SSS]][Z]"))
.toFormatter();
LocalDateTime localDateTime = null;
LocalDate localDate = null;
ZoneId zoneId = ZoneId.of(ZoneOffset.UTC.getId());
Date date = null;
try {
localDateTime = LocalDateTime.parse(datetime, formatter);
date = Date.from(localDateTime.atZone(zoneId).toInstant());
} catch (Exception exception) {
System.out.println("Inside Excpetion");
localDate = LocalDate.parse(datetime, formatter);
date = Date.from(localDate.atStartOfDay(zoneId).toInstant());
}
由于可以从代码中作用似乎我使用DateTimeFormatter
和附加的模式。 现在我第一次试图解析日期LocalDateTime
在try-block
,如果它抛出了样病例异常2017-05-05
,因为没有时间已过,我使用的是LocalDate
在catch block
。
上述方法是给我,我在寻找解决办法,但我的问题是,这是对付发送日期为字符串,是我的做法是符合这些标准的标准呢?
此外,如果可能的话有什么其他的方式我可以分析不同类型的日期(见上有效日期),除了像使用一个数组列表,并把所有可能的格式,然后把其他一些简单的解决方案,使用循环试图解析日期?
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
// time is optional
.optionalStart()
.parseCaseInsensitive()
.appendPattern("[ ]['T']")
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.optionalEnd()
// offset is optional
.appendPattern("[xx]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
for (String queryParam : new String[] {
"2017-05-05 00:00:00.000+0000",
"2017-05-05 00:00:00.000",
"2017-05-05T00:00:00",
"2017-05-05+0000",
"2017-05-05",
"2017-05-05T11:20:30.643+0000",
"2017-05-05 16:25:09.897+0000",
"2017-05-05 22:13:55.996",
"2017-05-05t02:24:01"
}) {
Instant inst = OffsetDateTime.parse(queryParam, formatter).toInstant();
System.out.println(inst);
}
从这段代码的输出是:
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T00:00:00Z
2017-05-05T11:20:30.643Z
2017-05-05T16:25:09.897Z
2017-05-05T22:13:55.996Z
2017-05-05T02:24:01Z
我使用的技巧包括:
- 可选部分可以被包括在任一
optionalStart
/ optionalEnd
或在[]
中的图案。 我同时使用,每个地方我觉得更容易阅读,你可能更喜欢不同。 - 目前已经有日期和时间预定义的格式化,所以我重用这些。 特别是我拿的,事实的优点
DateTimeFormatter.ISO_LOCAL_TIME
已经处理了可选秒,秒的小数。 - 解析成
OffsetDateTime
工作,我们需要对可能的查询参数缺少的部分提供缺省值。 parseDefaulting
做到这一点。
在你的代码被转换为一个Date
。 该java.util.Date
类是早已过时,并拥有多项设计上的问题,所以如果你能避免它。 Instant
会做得很好。 如果你确实需要一个Date
为传统的API,你不能改变或不想刚才改变,转换以同样的方式,你在做的问题。
编辑:现在违约HOUR_OF_DAY
,不MILLI_OF_DAY
。 后者导致当只有米利斯失踪冲突,但似乎格式是高兴的一天的只是默认小时的时间丢失时。
我通常使用的DateUtils.parseDate属于公共琅 。
这种方法看起来是这样的:
public static Date parseDate(String str,
String... parsePatterns)
throws ParseException
下面是说明:
解析代表通过尝试各种不同的解析器的日期的字符串。
解析将依次尝试每个解析模式。 解析只认为是成功的,如果它解析整个输入字符串。 如果没有解析模式匹配,一个ParseException被抛出。
解析器将向着解析日期宽松。
文章来源: What is the Standard way to Parse different Dates passed as Query-Params to the REST API?