Java 时间解析 "Jun 26th 2021, 04:30:15 pm NY"
Java time parse "Jun 26th 2021, 04:30:15 pm NY"
我有一个如下所示的字符串:
String str = "Jun 26th 2021, 04:30:15 pm NY";
我想将其转换为 ZonedDateTime
,为此我使用 DateTimeFormatterBuilder
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd'th' uuuu, h:mm:ss a z")
.toFormatter(Locale.US);
ZonedDateTime result = ZonedDateTime.parse(str, formatter);
但是解析器对这种格式不满意我得到了这个错误:
java.time.format.DateTimeParseException: Text 'Jun 26th 2021, 04:30:15 pm NY' could not be parsed at index 27
似乎 NY
没有被 z
覆盖,请问关于这个错误的任何想法,还有什么技巧可以避免在解析器中 'th'
吗?
正如 Sweeper 强调的那样,纽约不是 Java 认可的时区。为了最大限度地减少对代码的更改,您可以使用 DateTimeFormatter
格式化程序的 DateTimeFormatter#withZone
方法返回格式化程序的副本,其中包含如下新的覆盖区域:
String str = "Jun 26th 2021, 04:30:15 pm"; //<-- erased NY
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd'th' uuuu, h:mm:ss a")
.toFormatter(Locale.US);
ZonedDateTime result = ZonedDateTime.parse(str, formatter.withZone(ZoneId.of("America/New_York")));
System.out.println(result); //<-- 2021-06-26T16:30:15-04:00[America/New_York]
DateTimeFormatter#parse(CharSequence, ParsePosition)
任您支配。
请注意 NY
不是时区的名称。时区的命名约定是 Region/City 例如Europe/Paris
。您可以使用 ZoneId#getAvailableZoneIds
.
获取时区名称列表
此外,对于带有序号的日期,例如26th,可以构建一个Map
,如下代码所示
演示:
import java.text.ParsePosition;
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.HashMap;
import java.util.Locale;
import java.util.Map;
public class Main {
public static void main(String[] args) {
String strDateTime ="Jun 26th 2021, 04:30:15 pm NY";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("[MMMM][MMM] ") // caters for both full name and 3-letter abbv.
.appendText(ChronoField.DAY_OF_MONTH, ordinalMap())
.appendPattern(" u, h:m:s a")
.toFormatter(Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.from(dtf.parse(strDateTime, new ParsePosition(0)));
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));
System.out.println(zdt);
}
static Map<Long, String> ordinalMap() {
String[] suffix = { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
Map<Long, String> map = new HashMap<>();
for (int i = 1; i <= 31; i++)
map.put((long)i, String.valueOf(i) + suffix[(i > 3 && i < 21) ? 0 : (i % 10)]);
return map;
}
}
输出:
2021-06-26T16:30:15-04:00[America/New_York]
了解有关现代日期时间 API 的更多信息
礼貌: 构建 Map
的逻辑基于 this excellent answer.
我有一个如下所示的字符串:
String str = "Jun 26th 2021, 04:30:15 pm NY";
我想将其转换为 ZonedDateTime
,为此我使用 DateTimeFormatterBuilder
:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd'th' uuuu, h:mm:ss a z")
.toFormatter(Locale.US);
ZonedDateTime result = ZonedDateTime.parse(str, formatter);
但是解析器对这种格式不满意我得到了这个错误:
java.time.format.DateTimeParseException: Text 'Jun 26th 2021, 04:30:15 pm NY' could not be parsed at index 27
似乎 NY
没有被 z
覆盖,请问关于这个错误的任何想法,还有什么技巧可以避免在解析器中 'th'
吗?
正如 Sweeper 强调的那样,纽约不是 Java 认可的时区。为了最大限度地减少对代码的更改,您可以使用 DateTimeFormatter
格式化程序的 DateTimeFormatter#withZone
方法返回格式化程序的副本,其中包含如下新的覆盖区域:
String str = "Jun 26th 2021, 04:30:15 pm"; //<-- erased NY
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd'th' uuuu, h:mm:ss a")
.toFormatter(Locale.US);
ZonedDateTime result = ZonedDateTime.parse(str, formatter.withZone(ZoneId.of("America/New_York")));
System.out.println(result); //<-- 2021-06-26T16:30:15-04:00[America/New_York]
DateTimeFormatter#parse(CharSequence, ParsePosition)
任您支配。
请注意 NY
不是时区的名称。时区的命名约定是 Region/City 例如Europe/Paris
。您可以使用 ZoneId#getAvailableZoneIds
.
此外,对于带有序号的日期,例如26th,可以构建一个Map
,如下代码所示
演示:
import java.text.ParsePosition;
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.HashMap;
import java.util.Locale;
import java.util.Map;
public class Main {
public static void main(String[] args) {
String strDateTime ="Jun 26th 2021, 04:30:15 pm NY";
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("[MMMM][MMM] ") // caters for both full name and 3-letter abbv.
.appendText(ChronoField.DAY_OF_MONTH, ordinalMap())
.appendPattern(" u, h:m:s a")
.toFormatter(Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.from(dtf.parse(strDateTime, new ParsePosition(0)));
ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));
System.out.println(zdt);
}
static Map<Long, String> ordinalMap() {
String[] suffix = { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" };
Map<Long, String> map = new HashMap<>();
for (int i = 1; i <= 31; i++)
map.put((long)i, String.valueOf(i) + suffix[(i > 3 && i < 21) ? 0 : (i % 10)]);
return map;
}
}
输出:
2021-06-26T16:30:15-04:00[America/New_York]
了解有关现代日期时间 API 的更多信息
礼貌: 构建 Map
的逻辑基于 this excellent answer.