Одна проблема заключается в том, что короткие имена часовых поясов, такие как CEST
и CET
, двусмысленны и нестандартны. а>. В идеале следует использовать названия часовых поясов IANA (всегда в формате Continent/City
, например America/Sao_Paulo
или Europe/Berlin
). .
Я предполагаю, что CEST
– это летнее время Центральной Европы, то есть используется во многих странах (вот почему это двусмысленно: вы не можете знать какая это страна или регион, потому что это слишком широкий диапазон).
Хотя большинство сокращений не распознаются (из-за их двусмысленности), некоторые «значения по умолчанию» предполагаются по соображениям совместимости с предыдущими версиями. В используемой мной версии (JDK 1.8.0_131) по умолчанию используется Europe/Paris
, но не уверен, что это то, что вам нужно. И не гарантируется, что он будет работать для всех сокращений. В этом случае вы можете определить предпочтительный часовой пояс для использования (и это будет произвольный выбор, но другого пути нет, поскольку CEST
неоднозначен).
Другая проблема заключается в том, что месяц и день недели указаны на английском языке (Aug
и Mon
), а вы не указали java.util.Locale
. В этом случае DateTimeFormatter
принимает языковой стандарт системы по умолчанию (и, вероятно, это не английский язык — проверьте значение Locale.getDefault()
). В любом случае, локаль по умолчанию может быть изменена без предварительного уведомления даже во время выполнения, поэтому лучше указать ее при работе с локализованными данными (такими как месяц и день недели). имена).
Таким образом, вы должны указать локаль и определить произвольный часовой пояс в качестве предпочтительного для использования при обнаружении неоднозначного имени, такого как CEST
. Для этого вы можете использовать java.time.format.DateTimeFormatterBuilder
, набор предпочтительных часовых поясов и java.time.format.TextStyle
:
// create set of preferred timezones
Set<ZoneId> zones = new HashSet<>();
// my arbitrary choice for CEST
zones.add(ZoneId.of("Europe/Brussels"));
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// date and time
.appendPattern("EEE dd MMM yyyy hh:mm a ")
// timezone short name with custom set of preferred zones
.appendZoneText(TextStyle.SHORT, zones)
// create formatter (use English locale for month and day of week)
.toFormatter(Locale.ENGLISH);
String input = "Mon 14 Aug 2017 02:00 AM CEST";
System.out.println(ZonedDateTime.parse(input, formatter));
Вывод будет:
2017-08-14T02:00+02:00[Европа/Брюссель]
Обратите внимание, что я использовал Europe/Brussels
в качестве предпочтительного часового пояса. Вы можете проверить все доступные имена зон (и выбрать соответственно) с помощью ZoneId.getAvailableZoneIds()
.
Я использую hh
для часов, что соответствует hour-clock-of-am-pm field (значения от 1 до 12). Но в своем коде вы использовали KK
, то есть поле часы-утра-послеполуденного (значения от 0 до 11). Проверьте, какой из них лучше всего подходит для вашего случая.
Часовой пояс — это набор всех различных смещений, которые регион имел, имеет и будет иметь во время своего существования. история, а также даты начала и окончания перехода на летнее время и т. д. Если 2 региона имеют некоторую разницу в этой истории, они будут иметь разные часовые пояса (даже если сегодня они используют одни и те же правила).
Тот факт, что Париж и Брюссель используют одни и те же правила сегодня (CET
и CEST
), не означает, что так будет всегда (поскольку правила часовых поясов определяются правительствами и законами, и нет никакой гарантии, что они не будут изменены в ближайшее время). любое время в будущем).
Вот почему вы должны определить какой-то конкретный часовой пояс, а не полагаться на двусмысленные короткие имена (хотя их использование является обычным и широко распространенным).
person
Community
schedule
17.08.2017