完全摆脱这种错误模式(以及DateTimeFormatter),使用OffsetDateTime 而不是LocalDateTime,后者无法存储有关偏移量的信息。
这是您代码的转换(稍作调整和注释):
public static void main(String[] args) {
String date = "2021-04-23T12:09:56.123-07:00";
/*
* no DateTimeFormatter needed due to default format of the String
*/
// use an OffsetDateTime to parse a String with an offset
OffsetDateTime odtParsed = OffsetDateTime.parse(date);
// print it
System.out.println("Parsed OffsetDateTime is " + odtParsed);
// take the current instant as an OffsetDateTime at an offset of -7 hours
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.ofHours(-7));
// run your check and get a success
if (odtParsed.isBefore(now) && odtParsed.isAfter(now.plusDays(DAYS))) {
System.out.println("Date is incorrect");
} else {
System.out.println("Success");
}
}
打印出来
Parsed OffsetDateTime is 2021-04-23T12:09:56.123-07:00
Success
提示:这对于不同格式的Strings 将失败。如果格式仅略有不同,您也许可以创建一个DateTimeFormatter(通过DateTimeFormatterBuilder)来处理可选部分等。
编辑
如果只有一天的毫秒是可选的,并且偏移量的格式总是由加号或减号组成,后跟两位数表示小时,冒号和两位数表示分钟,则以下示例可能显示了一种足够的方法它通用:
public static void main(String[] args) {
String date = "2021-04-23T12:09:56.123-07:00";
String date1 = "2021-04-23T12:09:56.123+02:00";
String date2 = "2021-04-23T12:09:56.123+00:00";
String date3 = "2021-04-23T12:09:56-07:00";
String date4 = "2021-04-23T12:09:56+02:00";
String date5 = "2021-04-23T12:09:56+00:00";
// DateTimeFormatter using optional millis of second
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[.SSS]xxx");
// use an OffsetDateTime to parse a String with an offset
OffsetDateTime odtParsed = OffsetDateTime.parse(date, dtf);
OffsetDateTime odtParsed1 = OffsetDateTime.parse(date1, dtf);
OffsetDateTime odtParsed2 = OffsetDateTime.parse(date2, dtf);
OffsetDateTime odtParsed3 = OffsetDateTime.parse(date3, dtf);
OffsetDateTime odtParsed4 = OffsetDateTime.parse(date4, dtf);
OffsetDateTime odtParsed5 = OffsetDateTime.parse(date5, dtf);
// print it
System.out.println("Parsed OffsetDateTime is " + odtParsed);
System.out.println("Parsed OffsetDateTime is " + odtParsed1);
System.out.println("Parsed OffsetDateTime is " + odtParsed2);
System.out.println("Parsed OffsetDateTime is " + odtParsed3);
System.out.println("Parsed OffsetDateTime is " + odtParsed4);
System.out.println("Parsed OffsetDateTime is " + odtParsed5);
}
输出:
Parsed OffsetDateTime is 2021-04-23T12:09:56.123-07:00
Parsed OffsetDateTime is 2021-04-23T12:09:56.123+02:00
Parsed OffsetDateTime is 2021-04-23T12:09:56.123Z
Parsed OffsetDateTime is 2021-04-23T12:09:56-07:00
Parsed OffsetDateTime is 2021-04-23T12:09:56+02:00
Parsed OffsetDateTime is 2021-04-23T12:09:56Z
如果您不希望将零小时和零分钟的偏移量输出为Z,则使用DateTimeFormatter 进行如下输出:
OffsetDateTime odtParsed5 = OffsetDateTime.parse(date5, dtf);
这使得输出看起来像这样:
Parsed OffsetDateTime is 2021-04-23T12:09:56.000+00:00
即使它们都是零,也会打印一天中的毫秒。
另一个编辑:
要检查日期是否在过去 30 天到 未来 30 天范围内,最好只使用日期部分:
public static void main(String[] args) {
// the first part is already known from the examples above...
String date = "2021-04-23T12:09:56.123-07:00";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss[.SSS]xxx");
OffsetDateTime odtParsed = OffsetDateTime.parse(date, dtf);
// get the current instant as an OffsetDateTime (in UTC == +00:00)
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC);
/*
* might be smart to keep time of day out of the calculation, so...
*/
// get the date only out of the OffsetDateTime
LocalDate today = now.toLocalDate();
// create one for 30 days before
LocalDate thirtyDaysBeforeToday = today.minusDays(30);
// and one 30 days in the future
LocalDate thirtyDaysInTheFuture = today.plusDays(30);
// finally extract the date part from the parsed date time
LocalDate d = odtParsed.toLocalDate();
// make your checks using the LocalDates, maybe separate the two cases of an invalid date
if (d.isBefore(thirtyDaysBeforeToday)) {
System.err.println("Invalid date: too far in the past");
} else if (d.isAfter(thirtyDaysInTheFuture)) {
System.err.println("Invalid date: too far in the future");
} else {
System.out.println("Valid date");
}
}
尝试一些不同的有效和无效日期...