当我运行这个时,我得到异常:线程"main"中的异常java.time.format.DateTimeParseException: Text '2020-12-15 13:48:52' could not be parsed: Invalid value for ClockHourOfAmPm (valid values
)我写信给控制台:2020-12-15 13:48:52
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Podaj datę:");
String input = scanner.nextLine();
if (input.matches("\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}")) {
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(input, dateTimeFormatter1);
printDateTime(localDateTime);
} else if (input.matches("\d{2}.\d{2}.\d{4} \d{2}:\d{2}:\d{2}")) {
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("dd.MM.yyyy hh:mm:ss");
LocalDateTime localDateTime2 = LocalDateTime.parse(input, dateTimeFormatter2);
printDateTime(localDateTime2);
} else if (input.matches("\d{4}-\d{2}-\d{2}")) {
DateTimeFormatter dateTimeFormatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime localDateTime3 = LocalDateTime.parse(input, dateTimeFormatter3);
printDateTime(localDateTime3);
} else {
System.out.println("Zły format");
}
}
private static void printDateTime(LocalDateTime localDateTime) {
System.out.println("Czas lokalny: " + ZonedDateTime.now());
System.out.println("UTC: " + ZonedDateTime.of(localDateTime, ZoneId.of("UTC")));
System.out.println("Londyn: " + ZonedDateTime.of(localDateTime, ZoneId.of("London")));
System.out.println("Los Angeles: " + ZonedDateTime.of(localDateTime, ZoneId.of("Los Angeles")));
System.out.println("Sydney: " + ZonedDateTime.of(localDateTime, ZoneId.of("Sydney")));
}
}
对于这个需求,不要使用regex,因为它会使您的程序不必要地复杂并且容易出错。您可以使用DateTimeFormatter
方括号中的可选模式。除此之外,
- 使用
DateTimeFormatterBuilder#parseDefaulting
将字段(例如HOUR_OF_DAY
)的默认值附加到格式化程序中以用于解析。 - 使用
ZonedDateTime#withZoneSameInstant
返回该日期时间的副本,使用不同的时区,保留瞬间。 - 使用时区的标准命名约定(地区/城市),例如
Europe/London
。 - 用
HH
代替hh
代替HOUR_OF_DAY
(即24小时格式的时间)。符号hh
与指定am/pm
(即12小时格式的时间)的a
一起使用。
演示:
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("[uuuu-MM-dd HH:mm:ss][dd.MM.uuuu HH:mm:ss][uuuu-MM-dd]")
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
.parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.ENGLISH);
System.out.print("Podaj datę:");
String input = scanner.nextLine();
LocalDateTime localDateTime = LocalDateTime.parse(input, dtf);
System.out.println(localDateTime);
printDateTime(LocalDateTime.parse(input, dtf));
}
private static void printDateTime(LocalDateTime localDateTime) {
// Default timezone
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zdtDefaultTimeZone = localDateTime.atZone(zoneId);
System.out
.println("Date-time at " + zoneId + ": " + zdtDefaultTimeZone);
System.out.println("At UTC: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Etc/UTC")));
System.out.println("In London: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Europe/London")));
System.out
.println("In Los Angeles: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("America/Los_Angeles")));
System.out.println("In Sydney: " + zdtDefaultTimeZone.withZoneSameInstant(ZoneId.of("Australia/Sydney")));
}
}
示例运行:
Podaj datę:2020-02-23 10:15:20
2020-02-23T10:15:20
Date-time at Europe/London: 2020-02-23T10:15:20Z[Europe/London]
At UTC: 2020-02-23T10:15:20Z[Etc/UTC]
In London: 2020-02-23T10:15:20Z[Europe/London]
In Los Angeles: 2020-02-23T02:15:20-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T21:15:20+11:00[Australia/Sydney]
另一个示例运行:
Podaj datę:23.02.2020 10:15:20
2020-02-23T10:15:20
Date-time at Europe/London: 2020-02-23T10:15:20Z[Europe/London]
At UTC: 2020-02-23T10:15:20Z[Etc/UTC]
In London: 2020-02-23T10:15:20Z[Europe/London]
In Los Angeles: 2020-02-23T02:15:20-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T21:15:20+11:00[Australia/Sydney]
另一个示例运行:
Podaj datę:2020-02-23
2020-02-23T00:00
Date-time at Europe/London: 2020-02-23T00:00Z[Europe/London]
At UTC: 2020-02-23T00:00Z[Etc/UTC]
In London: 2020-02-23T00:00Z[Europe/London]
In Los Angeles: 2020-02-22T16:00-08:00[America/Los_Angeles]
In Sydney: 2020-02-23T11:00+11:00[Australia/Sydney]
了解更多关于现代日期时间API从Trail: Date Time.
DateTimeFormatter中的DateTime模式导致了您在这里看到的问题。你需要使用HH
而不是hh
hh
:这是一个使用12小时时钟的小时模式,带有AM/PM指示。HH
:这是一个使用24小时时钟的小时模式。输入范围0-23
旁注,您使用的区域似乎无效。对应的区域为
Europe/London
America/Los_Angeles
Australia/Sydney