There's a difference on how Joda-Time and java.time
interprets the pattern e
.
In Joda-Time, the e
pattern designates the numeric value of day-of-week:
Symbol Meaning Presentation Examples
------ ----------- ------------ -------
e day of week number 2
So, using e
is equivalent to getting the day of the week from a date object:
// 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
Note that both the formatter and getDayOfWeek()
return 3
. The getDayOfWeek()
method returns a value defined in DateTimeConstants
class, and Wednesday's value is 3
(the third day of the week according to ISO's definition).
In java.time
API, the pattern e
has a different meaning:
Pattern Count Equivalent builder methods
------- ----- --------------------------
e 1 append special localized WeekFields element for numeric day-of-week
It uses the localized WeekFields
element, and this can vary according to the locale. The behaviour might be different when compared to the getDayOfWeek()
method:
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
Note that the formatter uses the localized day of week for English locale, and the value is 4
, while calling getDayOfWeek().getValue()
returns 3
.
That's because e
with English locale is equivalent to using a java.time.temporal.WeekFields
:
// using localized fields
WeekFields wf = WeekFields.of(Locale.ENGLISH);
System.out.println(z.get(wf.dayOfWeek())); // 4
While getDayOfWeek()
is equivalent to using ISO's definition:
// same as getDayOfWeek()
System.out.println(z.get(WeekFields.ISO.dayOfWeek())); // 3
That's because ISO's definition uses Monday as the first day of the week, while WeekFields
with English locale uses Sunday:
// comparing the first day of week
System.out.println(WeekFields.ISO.getFirstDayOfWeek()); // MONDAY
System.out.println(wf.getFirstDayOfWeek()); // SUNDAY
So the e
pattern might behave differently or not to getDayOfWeek()
, according to the locale set in the formatter (or the JVM default locale, if none is set). In French locale, for example, it behaves just like ISO, while in some arabic locales, the first day of the week is Saturday:
WeekFields.of(Locale.FRENCH).getFirstDayOfWeek(); // MONDAY
WeekFields.of(new Locale("ar", "AE")).getFirstDayOfWeek(); // SATURDAY
According to javadoc, the only patterns that return a numeric value for the day of week seem to be the localized ones. So, to parse the input 2016-12-21 20:50:25 Wednesday December +0000 3
, you can use a java.time.format.DateTimeFormatterBuilder
and join the date/time pattern with a java.time.temporal.ChronoField
to indicate the numeric value of the day of week (the ISO non-locale sensitive field):
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);
Also note that you don't need to quote the -
, :
and space characters, so the pattern becomes more clear and readable (IMO).
I also set the English locale, because if you don't set, it'll use the JVM default locale, and it's not guaranteed to always be English. And it can also be changed without notice, even at runtime, so it's better to specify one, specially if you already know in what language the input is.
Update: probably the ccccc
pattern should work, as it's equivalent to appendText(ChronoField.DAY_OF_WEEK, TextStyle.NARROW_STANDALONE)
and in my tests (JDK 1.8.0_144) it returns (and also parses) 3
:
DateTimeFormatter parser = DateTimeFormatter
.ofPattern("yyyy-MM-dd HH:mm:ss EEEE MMMM ZZ ccccc", Locale.ENGLISH);
ZonedDateTime date = ZonedDateTime.parse(input, parser);