String
转换为dateformat,然后解析为
LocalDateTime
我的代码是我的代码
DateTimeFormatter f = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
String text = "2020-01-01T01:01:11.123Z"
LocalDateTime date = LocalDateTime.parse(text, f)
但爪哇扔
文本无法解析,在索引19
上找到了无与伦比的文本
如果我更改为
ofPattern
,我的代码将执行而没有任何错误。 但是我不想使用毫秒和时区。
yyyy-MM-dd'T'HH:mm:ss.SSSX
做这个:
String text = "2020-01-01T01:01:11.123Z";
LocalDateTime date = ZonedDateTime.parse(text)
.toLocalDateTime();
要摆脱毫秒信息,请做:LocalDateTime date = ZonedDateTime.parse(text)
.truncatedTo(ChronoUnit.SECONDS)
.toLocalDateTime();
您也可以用
OffsetDateTime
代替ZonedDateTime
。
更灵活的解决方案IMO将是通过dateTimeFormatterBuilder创建一个
DateTimeFormatter
private static final DateTimeFormatter DATE_TIME = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd'T'HH:mm:ss")
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.optionalEnd()
.optionalStart()
.appendPattern("XXX")
.optionalEnd()
.optionalStart()
.appendPattern("Z")
.optionalEnd()
.toFormatter();
然后可以用来将各种时间格式从开箱即用:
OffsetDateTime odt = OffsetDateTime.parse(timestamp, DATE_TIME);
LocalDateTime ldt = LocalDateTime.parse(timestamp, DATE_TIME);
这里建造者的美丽是,您可以声明诸如Milli,Micro或Nano-Seconds后缀或区域相关的输入(如可选的)和带有时间格式的诸如包含该信息或没有信息的构建器的库。
我用来审理的现实世界情景接收到json的对象,即看起来像这样:
/**
* Custom offset and date time deserializer.
*/
@Slf4j
public class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
// offset or local date time format
private static final DateTimeFormatter DATE_TIME = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd'T'HH:mm:ss")
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
.optionalEnd()
.optionalStart()
.appendPattern("XXX")
.optionalEnd()
.optionalStart()
.appendPattern("Z")
.optionalEnd()
.toFormatter();
// local date format
private static final DateTimeFormatter LOCAL_DATE = DateTimeFormatter.ofPattern(
"yyyy-MM-dd"
);
@Override
public OffsetDateTime deserialize(
JsonParser jsonParser,
DeserializationContext deserializationContext
) throws IOException {
log.trace("Deserializing the value: {}", jsonParser.getText());
final String dateAsString = jsonParser.getText();
if (dateAsString == null) {
throw new IOException("OffsetDateTime argument is null.");
}
final Optional<OffsetDateTime> result = parseOffsetDateTime(dateAsString)
.or(() -> parseLocalDateTime(dateAsString))
.or(() -> parseLocalDate(dateAsString));
if (result.isPresent()) {
return result.get();
}
throw new IOException("Could not parse '" + dateAsString
+ "' timestamp to any supported time formats");
}
@Nonnull
private Optional<OffsetDateTime> parseOffsetDateTime(
@Nonnull final String dateAsString) {
try {
return Optional.of(OffsetDateTime.parse(dateAsString, DATE_TIME));
} catch (DateTimeParseException ex) {
return Optional.empty();
}
}
@Nonnull
private Optional<OffsetDateTime> parseLocalDateTime(
@Nonnull final String dateAsString) {
try {
final LocalDateTime localDateTime = LocalDateTime.parse(dateAsString, DATE_TIME);
return Optional.of(localDateTime.atOffset(ZoneOffset.UTC));
} catch (DateTimeParseException ex) {
return Optional.empty();
}
}
@Nonnull
private Optional<OffsetDateTime> parseLocalDate(@Nonnull final String dateAsString) {
try {
var date = LocalDate.parse(dateAsString, LOCAL_DATE);
return Optional.of(OffsetDateTime.of(date, LocalTime.NOON, ZoneOffset.UTC));
} catch (DateTimeParseException ex) {
return Optional.empty();
}
}
}