joe*_*der 7 java date java-8 java-time
使用Java 8的新日期时间库,将字符串解析为日期的方法是使用DateTimeFormatter.LocalDate,LocalTime并且LocalDateTime都有一个静态解析方法,它接受一个String和一个格式化程序.一个潜在的问题是,如果你的DateTimeFormat不包含时间部分(或者对于DateTime,一个日期部分),即使你的模式匹配,你最终也会得到一个解析错误.
例
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-DD");
LocalDateTime dt = LocalDateTime.parse("2016-01-11", formatter);
Run Code Online (Sandbox Code Playgroud)
这将引发DateTimeParseException(如讨论这里与消息)
java.time.format.DateTimeParseException:
Text '2016-01-11' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor
Run Code Online (Sandbox Code Playgroud)
这是一个有点无用的错误消息,因为文本可以解析,因为它匹配模式.相反,错误与它无法创建LocalDateTime的时间部分这一事实有关.将代码重构为以下代码:
LocalDateTime ldt = LocalDate.parse("2016-01-11", formatter).atStartOfDay());
Run Code Online (Sandbox Code Playgroud)
我的问题是,你说你有这样的通用方法
public static LocalDateTime getDate(String s, DateTimeFormatter format) {
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法确定需要调用哪个静态解析方法,通过应用一些默认逻辑将字符串强制转换为LocalDateTime?例如,如果日期仅使用午夜,如果时间仅使用今天,等等.
使用其他人创建的格式化程序进行解析比解析一个你可以控制的格式化程序更棘手(Tunaki的parseDefaulting()答案是正确的.)但是可以这样做:
public static LocalDateTime getDate(String s, DateTimeFormatter format) {
TemporalAccessor dt = parser.parseBest(
str, LocalDateTime::from, LocalDate::from, LocalTime::from, YearMonth::from);
if (dt instanceof LocalDate) {
return ((LocalDate) dt).atStartOfDay();
} else if (dt instanceof LocalTime) {
return ((LocalTime) dt).atDate(LocalDate.now());
} else if (dt instanceof YearMonth) {
return ((YearMonth) dt).atDay(1).atStartOfDay();
} else {
return LocalDateTime.from(dt);
}
}
Run Code Online (Sandbox Code Playgroud)
我没有测试上面的代码,但它是parseBest()设计的方法.
我认为你有相反的问题.您不想确定格式化程序是仅使用日期还是日期/时间.您可以根据应解析的内容以及要将结果存储到的内容创建格式化程序.显然,如果你创建一个不处理时间部分的格式化程序,用它来解析成一个LocalDateTime是一种误解.
如果您需要解析可以使用两种格式("yyyy-MM-dd"或"yyyy-MM-dd HH:mm:ss"带有时间部分)到达的日期,则无法通过解析来确定它应该做什么,而是由格式化程序提供,以便在没有时间的情况下提供默认值.
使用Java Time,可以使用可选部分和默认值完成此操作.例如,模式"yyyy-MM-dd[ HH:mm:ss]"将能够解析日期字符串(如"2016-01-11")和日期/时间字符串(如"2016-01-11 20:10:10").如果您将其存储到a中LocalDateTime,则需要提供默认值以防没有时间组件.这样做parseDefaulting(field, value):这将告诉格式化程序返回该chrono字段的给定默认值(如果尚未设置).
以下代码创建了这样的格式化程序,并将时间部分默认为午夜.
public static void main(String[] args) {
DateTimeFormatter formatter =
new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd[ HH:mm:ss]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter();
LocalDateTime dt1 = LocalDateTime.parse("2016-01-11", formatter);
LocalDateTime dt2 = LocalDateTime.parse("2016-01-11 20:10:10", formatter);
}
Run Code Online (Sandbox Code Playgroud)
这个逻辑当然可以扩展到仅解析时间String并将日期组件默认为当前日期.
| 归档时间: |
|
| 查看次数: |
5497 次 |
| 最近记录: |