import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.format.SignStyle;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main
(String[] args
) { DateTimeFormatter dtf =
new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR, 1, 4, SignStyle.NORMAL)
.appendLiteral('-')
.appendValue(ChronoField.MONTH_OF_YEAR, 1, 2, SignStyle.NORMAL)
.appendLiteral('-')
.appendValue(ChronoField.DAY_OF_MONTH, 1, 2, SignStyle.NORMAL)
.appendLiteral(' ')
.appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NORMAL)
.appendLiteral(':')
.appendValue(ChronoField.MINUTE_OF_HOUR, 1, 2, SignStyle.NORMAL)
.appendLiteral(':')
.appendValue(ChronoField.SECOND_OF_MINUTE, 1, 2, SignStyle.NORMAL)
.optionalStart()
.appendLiteral('.')
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 3, false)
.optionalEnd()
.withResolverStyle(ResolverStyle.STRICT);
// Test
Stream.of(
"2008-06-31 23:59:59.000",
"2008-06-30 23:59:59.000",
"2008-6-30 23:59:59.000",
"2008-6-8 23:59:59.000",
"2008-6-8 2:59:59.000",
"2008-6-8 23:5:59.000",
"2008-6-8 23:59:9.000",
"2008-06-30 23:59:59"
).forEach (s -> {
try {
LocalDateTime ldt = LocalDateTime.parse(s, dtf);
}catch(DateTimeParseException e) {
System.
out.
printf("%s is an invalid date-time string.%n", s
); // ...
}
});
}
}
aW1wb3J0IGphdmEudGltZS5Mb2NhbERhdGVUaW1lOwppbXBvcnQgamF2YS50aW1lLmZvcm1hdC5EYXRlVGltZUZvcm1hdHRlcjsKaW1wb3J0IGphdmEudGltZS5mb3JtYXQuRGF0ZVRpbWVGb3JtYXR0ZXJCdWlsZGVyOwppbXBvcnQgamF2YS50aW1lLmZvcm1hdC5EYXRlVGltZVBhcnNlRXhjZXB0aW9uOwppbXBvcnQgamF2YS50aW1lLmZvcm1hdC5SZXNvbHZlclN0eWxlOwppbXBvcnQgamF2YS50aW1lLmZvcm1hdC5TaWduU3R5bGU7CmltcG9ydCBqYXZhLnRpbWUudGVtcG9yYWwuQ2hyb25vRmllbGQ7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLnN0cmVhbS5TdHJlYW07CgpwdWJsaWMgY2xhc3MgTWFpbiB7CglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CgkJRGF0ZVRpbWVGb3JtYXR0ZXIgZHRmID0gCgkJCQluZXcgRGF0ZVRpbWVGb3JtYXR0ZXJCdWlsZGVyKCkKCQkJCS5hcHBlbmRWYWx1ZShDaHJvbm9GaWVsZC5ZRUFSLCAxLCA0LCBTaWduU3R5bGUuTk9STUFMKQoJCQkJLmFwcGVuZExpdGVyYWwoJy0nKQoJCQkJLmFwcGVuZFZhbHVlKENocm9ub0ZpZWxkLk1PTlRIX09GX1lFQVIsIDEsIDIsIFNpZ25TdHlsZS5OT1JNQUwpCgkJCQkuYXBwZW5kTGl0ZXJhbCgnLScpCgkJCQkuYXBwZW5kVmFsdWUoQ2hyb25vRmllbGQuREFZX09GX01PTlRILCAxLCAyLCBTaWduU3R5bGUuTk9STUFMKQoJCQkJLmFwcGVuZExpdGVyYWwoJyAnKQoJCQkJLmFwcGVuZFZhbHVlKENocm9ub0ZpZWxkLkhPVVJfT0ZfREFZLCAxLCAyLCBTaWduU3R5bGUuTk9STUFMKQoJCQkJLmFwcGVuZExpdGVyYWwoJzonKQoJCQkJLmFwcGVuZFZhbHVlKENocm9ub0ZpZWxkLk1JTlVURV9PRl9IT1VSLCAxLCAyLCBTaWduU3R5bGUuTk9STUFMKQoJCQkJLmFwcGVuZExpdGVyYWwoJzonKQoJCQkJLmFwcGVuZFZhbHVlKENocm9ub0ZpZWxkLlNFQ09ORF9PRl9NSU5VVEUsIDEsIDIsIFNpZ25TdHlsZS5OT1JNQUwpCgkJCQkub3B0aW9uYWxTdGFydCgpCgkJCQkuYXBwZW5kTGl0ZXJhbCgnLicpCgkJCQkuYXBwZW5kRnJhY3Rpb24oQ2hyb25vRmllbGQuTkFOT19PRl9TRUNPTkQsIDAsIDMsIGZhbHNlKQoJCQkJLm9wdGlvbmFsRW5kKCkKCQkJCS50b0Zvcm1hdHRlcihMb2NhbGUuRU5HTElTSCkKCQkJCS53aXRoUmVzb2x2ZXJTdHlsZShSZXNvbHZlclN0eWxlLlNUUklDVCk7CgkJCgkJLy8gVGVzdAoJCVN0cmVhbS5vZigKCQkJCSIyMDA4LTA2LTMxIDIzOjU5OjU5LjAwMCIsCgkJCQkiMjAwOC0wNi0zMCAyMzo1OTo1OS4wMDAiLAoJCQkJIjIwMDgtNi0zMCAyMzo1OTo1OS4wMDAiLAoJCQkJIjIwMDgtNi04IDIzOjU5OjU5LjAwMCIsCgkJCQkiMjAwOC02LTggMjo1OTo1OS4wMDAiLAoJCQkJIjIwMDgtNi04IDIzOjU6NTkuMDAwIiwKCQkJCSIyMDA4LTYtOCAyMzo1OTo5LjAwMCIsCgkJCQkiMjAwOC0wNi0zMCAyMzo1OTo1OSIKCQkJCQoJCSkuZm9yRWFjaCAocyAtPiB7CgkJCXRyeSB7CgkJCQlMb2NhbERhdGVUaW1lIGxkdCA9IExvY2FsRGF0ZVRpbWUucGFyc2UocywgZHRmKTsKCQkJCVN5c3RlbS5vdXQucHJpbnRsbihsZHQpOwoJCQl9Y2F0Y2goRGF0ZVRpbWVQYXJzZUV4Y2VwdGlvbiBlKSB7CgkJCQlTeXN0ZW0ub3V0LnByaW50ZigiJXMgaXMgYW4gaW52YWxpZCBkYXRlLXRpbWUgc3RyaW5nLiVuIiwgcyk7CgkJCQkvLyAuLi4KCQkJfQoJCX0pOwkJCgl9Cn0=