Есть разница в том, как Joda-Time и java.time
интерпретируют шаблон e
.
В Joda-Time шаблон e
обозначает числовое значение дня недели:
Symbol Meaning Presentation Examples
------ ----------- ------------ -------
e day of week number 2
Таким образом, использование e
эквивалентно получению дня недели из объекта даты:
// using org.joda.time.DateTime and org.joda.time.format.DateTimeFormat
DateTime d = new DateTime(2016, 12, 21, 20, 50, 25, 0, DateTimeZone.UTC);
DateTimeFormatter fmt = DateTimeFormat.forPattern("e").withLocale(Locale.ENGLISH);
System.out.println(d.toString(fmt)); // 3
System.out.println(d.getDayOfWeek()); // 3
System.out.println(d.dayOfWeek().getAsText(Locale.ENGLISH)); // Wednesday
Обратите внимание, что форматтер и getDayOfWeek()
возвращают 3
. Метод getDayOfWeek()
возвращает значение, определенное в DateTimeConstants
class, и Среда – 3
(третий день недели согласно определение ISO).
В java.time
API шаблон e
имеет другое значение:
Pattern Count Equivalent builder methods
------- ----- --------------------------
e 1 append special localized WeekFields element for numeric day-of-week
Он использует локализованный элемент WeekFields
, и это может варьироваться в зависимости от региона. Поведение может отличаться от метода getDayOfWeek()
:
ZonedDateTime z = ZonedDateTime.of(2016, 12, 21, 20, 50, 25, 0, ZoneOffset.UTC);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("e", Locale.ENGLISH);
System.out.println(z.format(fmt)); // 4
System.out.println(z.getDayOfWeek()); // WEDNESDAY
System.out.println(z.getDayOfWeek().getValue()); // 3
Обратите внимание, что средство форматирования использует локализованный день недели для английской локали и значение равно 4
, а вызов getDayOfWeek().getValue()
возвращает 3
.
Это потому, что e
с английской локалью эквивалентно использованию java.time.temporal.WeekFields
:
// using localized fields
WeekFields wf = WeekFields.of(Locale.ENGLISH);
System.out.println(z.get(wf.dayOfWeek())); // 4
Хотя getDayOfWeek()
эквивалентно использованию определения ISO:
// same as getDayOfWeek()
System.out.println(z.get(WeekFields.ISO.dayOfWeek())); // 3
Это связано с тем, что определение ISO использует понедельник в качестве первого дня недели, а WeekFields
с английской локалью использует воскресенье:
// comparing the first day of week
System.out.println(WeekFields.ISO.getFirstDayOfWeek()); // MONDAY
System.out.println(wf.getFirstDayOfWeek()); // SUNDAY
Таким образом, шаблон e
может вести себя по-разному или не вести себя по отношению к getDayOfWeek()
в зависимости от языкового стандарта, установленного в средстве форматирования (или языкового стандарта JVM по умолчанию, если он не установлен). Например, во французской локали он ведет себя так же, как ISO, а в некоторых арабских локалях первый день недели — суббота:
WeekFields.of(Locale.FRENCH).getFirstDayOfWeek(); // MONDAY
WeekFields.of(new Locale("ar", "AE")).getFirstDayOfWeek(); // SATURDAY
Согласно javadoc, единственные шаблоны, которые возвращают числовое значение дня недели, по-видимому, являются локализованными. Таким образом, для анализа ввода 2016-12-21 20:50:25 Wednesday December +0000 3
вы можете использовать java.time.format.DateTimeFormatterBuilder
и соединить шаблон даты/времени с java.time.temporal.ChronoField
, чтобы указать числовое значение дня недели (поле ISO, не зависящее от локали):
String input = "2016-12-21 20:50:25 Wednesday December +0000 3";
DateTimeFormatter parser = new DateTimeFormatterBuilder()
// date/time pattern
.appendPattern("yyyy-MM-dd HH:mm:ss EEEE MMMM ZZ ")
// numeric day of week
.appendValue(ChronoField.DAY_OF_WEEK)
// create formatter with English locale
.toFormatter(Locale.ENGLISH);
ZonedDateTime date = ZonedDateTime.parse(input, parser);
Также обратите внимание, что вам не нужно заключать в кавычки -
, :
и символы пробела, чтобы шаблон стал более четким и читаемым (IMO).
Я также установил английскую локаль, потому что, если вы ее не установите, будет использоваться локаль JVM по умолчанию, и не всегда гарантируется, что она будет английской. И его также можно изменить без предварительного уведомления, даже во время выполнения, поэтому лучше указать его, особенно если вы уже знаете, на каком языке ввод.
Обновление: возможно, шаблон ccccc
должен работать, так как он эквивалентен appendText(ChronoField.DAY_OF_WEEK, TextStyle.NARROW_STANDALONE)
и в моих тестах (JDK 1.8.0_144) возвращает (а также анализирует) 3
:
DateTimeFormatter parser = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss EEEE MMMM ZZ ccccc", Locale.ENGLISH);
ZonedDateTime date = ZonedDateTime.parse(input, parser);
person
Community
schedule
21.09.2017