Blog

Java 8 の DateTimeFormatter の曜日等のフォーマットについて

DateTimeFormatter を利用して曜日などのフォーマットを行おうとすると、実際どういうふうにフォーマットされるのかよくわからんということになる。

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html をちらっと見ると、以下のように書いてあって、各シンボルが何を表すのかよくわからない。

  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   G       era                         text              AD; Anno Domini; A
   u       year                        year              2004; 04
   y       year-of-era                 year              2004; 04
   D       day-of-year                 number            189
   M/L     month-of-year               number/text       7; 07; Jul; July; J
   d       day-of-month                number            10

   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
   Y       week-based-year             year              1996; 96
   w       week-of-week-based-year     number            27
   W       week-of-month               number            4
   E       day-of-week                 text              Tue; Tuesday; T
   e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
   F       week-of-month               number            3

   a       am-pm-of-day                text              PM
   h       clock-hour-of-am-pm (1-12)  number            12
   K       hour-of-am-pm (0-11)        number            0
   k       clock-hour-of-am-pm (1-24)  number            0

   H       hour-of-day (0-23)          number            0
   m       minute-of-hour              number            30
   s       second-of-minute            number            55
   S       fraction-of-second          fraction          978
   A       milli-of-day                number            1234
   n       nano-of-second              number            987654321
   N       nano-of-day                 number            1234000000

   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

   p       pad next                    pad modifier      1

   '       escape for text             delimiter
   ''      single quote                literal           '
   [       optional section start
   ]       optional section end
   #       reserved for future use
   {       reserved for future use
   }       reserved for future use

GGG などのように、同じ文字列を複数回続けることによって任意の形式で出力することができるのだが、この様式は以下のようになっている。

Date fields: Pattern letters to output a date.

  Pattern  Count  Equivalent builder methods
  -------  -----  --------------------------
    G       1      appendText(ChronoField.ERA, TextStyle.SHORT)
    GG      2      appendText(ChronoField.ERA, TextStyle.SHORT)
    GGG     3      appendText(ChronoField.ERA, TextStyle.SHORT)
    GGGG    4      appendText(ChronoField.ERA, TextStyle.FULL)
    GGGGG   5      appendText(ChronoField.ERA, TextStyle.NARROW)

    u       1      appendValue(ChronoField.YEAR, 1, 19, SignStyle.NORMAL);
    uu      2      appendValueReduced(ChronoField.YEAR, 2, 2000);
    uuu     3      appendValue(ChronoField.YEAR, 3, 19, SignStyle.NORMAL);
    u..u    4..n   appendValue(ChronoField.YEAR, n, 19, SignStyle.EXCEEDS_PAD);
    y       1      appendValue(ChronoField.YEAR_OF_ERA, 1, 19, SignStyle.NORMAL);
    yy      2      appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2000);
    yyy     3      appendValue(ChronoField.YEAR_OF_ERA, 3, 19, SignStyle.NORMAL);
    y..y    4..n   appendValue(ChronoField.YEAR_OF_ERA, n, 19, SignStyle.EXCEEDS_PAD);
    Y       1      append special localized WeekFields element for numeric week-based-year
    YY      2      append special localized WeekFields element for reduced numeric week-based-year 2 digits;
    YYY     3      append special localized WeekFields element for numeric week-based-year (3, 19, SignStyle.NORMAL);
    Y..Y    4..n   append special localized WeekFields element for numeric week-based-year (n, 19, SignStyle.EXCEEDS_PAD);

    Q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
    QQ      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
    QQQ     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT)
    QQQQ    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL)
    QQQQQ   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW)
    q       1      appendValue(IsoFields.QUARTER_OF_YEAR);
    qq      2      appendValue(IsoFields.QUARTER_OF_YEAR, 2);
    qqq     3      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.SHORT_STANDALONE)
    qqqq    4      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.FULL_STANDALONE)
    qqqqq   5      appendText(IsoFields.QUARTER_OF_YEAR, TextStyle.NARROW_STANDALONE)

    M       1      appendValue(ChronoField.MONTH_OF_YEAR);
    MM      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
    MMM     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT)
    MMMM    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL)
    MMMMM   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW)
    L       1      appendValue(ChronoField.MONTH_OF_YEAR);
    LL      2      appendValue(ChronoField.MONTH_OF_YEAR, 2);
    LLL     3      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.SHORT_STANDALONE)
    LLLL    4      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.FULL_STANDALONE)
    LLLLL   5      appendText(ChronoField.MONTH_OF_YEAR, TextStyle.NARROW_STANDALONE)

    w       1      append special localized WeekFields element for numeric week-of-year
    ww      1      append special localized WeekFields element for numeric week-of-year, zero-padded
    W       1      append special localized WeekFields element for numeric week-of-month
    d       1      appendValue(ChronoField.DAY_OF_MONTH)
    dd      2      appendValue(ChronoField.DAY_OF_MONTH, 2)
    D       1      appendValue(ChronoField.DAY_OF_YEAR)
    DD      2      appendValue(ChronoField.DAY_OF_YEAR, 2)
    DDD     3      appendValue(ChronoField.DAY_OF_YEAR, 3)
    F       1      appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
    E       1      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
    EE      2      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
    EEE     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
    EEEE    4      appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL)
    EEEEE   5      appendText(ChronoField.DAY_OF_WEEK, TextStyle.NARROW)
    e       1      append special localized WeekFields element for numeric day-of-week
    ee      2      append special localized WeekFields element for numeric day-of-week, zero-padded
    eee     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT)
    eeee    4      appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL)
    eeeee   5      appendText(ChronoField.DAY_OF_WEEK, TextStyle.NARROW)
    c       1      append special localized WeekFields element for numeric day-of-week
    ccc     3      appendText(ChronoField.DAY_OF_WEEK, TextStyle.SHORT_STANDALONE)
    cccc    4      appendText(ChronoField.DAY_OF_WEEK, TextStyle.FULL_STANDALONE)
    ccccc   5      appendText(ChronoField.DAY_OF_WEEK, TextStyle.NARROW_STANDALONE)
 
Time fields: Pattern letters to output a time.

  Pattern  Count  Equivalent builder methods
  -------  -----  --------------------------
    a       1      appendText(ChronoField.AMPM_OF_DAY, TextStyle.SHORT)
    h       1      appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)
    hh      2      appendValue(ChronoField.CLOCK_HOUR_OF_AMPM, 2)
    H       1      appendValue(ChronoField.HOUR_OF_DAY)
    HH      2      appendValue(ChronoField.HOUR_OF_DAY, 2)
    k       1      appendValue(ChronoField.CLOCK_HOUR_OF_DAY)
    kk      2      appendValue(ChronoField.CLOCK_HOUR_OF_DAY, 2)
    K       1      appendValue(ChronoField.HOUR_OF_AMPM)
    KK      2      appendValue(ChronoField.HOUR_OF_AMPM, 2)
    m       1      appendValue(ChronoField.MINUTE_OF_HOUR)
    mm      2      appendValue(ChronoField.MINUTE_OF_HOUR, 2)
    s       1      appendValue(ChronoField.SECOND_OF_MINUTE)
    ss      2      appendValue(ChronoField.SECOND_OF_MINUTE, 2)

    S..S    1..n   appendFraction(ChronoField.NANO_OF_SECOND, n, n, false)
    A       1      appendValue(ChronoField.MILLI_OF_DAY)
    A..A    2..n   appendValue(ChronoField.MILLI_OF_DAY, n)
    n       1      appendValue(ChronoField.NANO_OF_SECOND)
    n..n    2..n   appendValue(ChronoField.NANO_OF_SECOND, n)
    N       1      appendValue(ChronoField.NANO_OF_DAY)
    N..N    2..n   appendValue(ChronoField.NANO_OF_DAY, n)
 
Zone ID: Pattern letters to output ZoneId.

  Pattern  Count  Equivalent builder methods
  -------  -----  --------------------------
    VV      2      appendZoneId()
    z       1      appendZoneText(TextStyle.SHORT)
    zz      2      appendZoneText(TextStyle.SHORT)
    zzz     3      appendZoneText(TextStyle.SHORT)
    zzzz    4      appendZoneText(TextStyle.FULL)
 
Zone offset: Pattern letters to output ZoneOffset.

  Pattern  Count  Equivalent builder methods
  -------  -----  --------------------------
    O       1      appendLocalizedOffsetPrefixed(TextStyle.SHORT);
    OOOO    4      appendLocalizedOffsetPrefixed(TextStyle.FULL);
    X       1      appendOffset("+HHmm","Z")
    XX      2      appendOffset("+HHMM","Z")
    XXX     3      appendOffset("+HH:MM","Z")
    XXXX    4      appendOffset("+HHMMss","Z")
    XXXXX   5      appendOffset("+HH:MM:ss","Z")
    x       1      appendOffset("+HHmm","+00")
    xx      2      appendOffset("+HHMM","+0000")
    xxx     3      appendOffset("+HH:MM","+00:00")
    xxxx    4      appendOffset("+HHMMss","+0000")
    xxxxx   5      appendOffset("+HH:MM:ss","+00:00")
    Z       1      appendOffset("+HHMM","+0000")
    ZZ      2      appendOffset("+HHMM","+0000")
    ZZZ     3      appendOffset("+HHMM","+0000")
    ZZZZ    4      appendLocalizedOffset(TextStyle.FULL);
    ZZZZZ   5      appendOffset("+HH:MM:ss","Z")
 
Modifiers: Pattern letters that modify the rest of the pattern:

  Pattern  Count  Equivalent builder methods
  -------  -----  --------------------------
    [       1      optionalStart()
    ]       1      optionalEnd()
    p..p    1..n   padNext(n)

これは、 https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatterBuilder.html#appendPattern-java.lang.String- のコピペである。DateTimeFormatter のフォーマットの仕方が DateTimeFormatterBuilder の方にあるので、たどりつくのが難しい。

実際どのようにフォーマットされるのかを確認する

実際にどのようにフォーマットされるのかを確認しておけば、後々便利であろう。


package datetimeformattersample;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

/**
 *
 * @author tokuhirom
 */
public class DateTimeFormatterSample {

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
    String[][] patterns = new String[][]{
      new String[]{"G", "appendText(ChronoField.ERA,"},
      new String[]{"GG", "appendText(ChronoField.ERA,"},
      new String[]{"GGG", "appendText(ChronoField.ERA,"},
      new String[]{"GGGG", "appendText(ChronoField.ERA,"},
      new String[]{"GGGGG", "appendText(ChronoField.ERA,"},
      new String[]{"", ""},
      new String[]{"u", "appendValue(ChronoField.YEAR,"},
      new String[]{"uu", "appendValueReduced(ChronoField.YEAR,"},
      new String[]{"uuu", "appendValue(ChronoField.YEAR,"},
      new String[]{"uuuu", "appendValue(ChronoField.YEAR,"},
      new String[]{"y", "appendValue(ChronoField.YEAR_OF_ERA,"},
      new String[]{"yy", "appendValueReduced(ChronoField.YEAR_OF_ERA,"},
      new String[]{"yyy", "appendValue(ChronoField.YEAR_OF_ERA,"},
      new String[]{"yyyy", "appendValue(ChronoField.YEAR_OF_ERA,"},
      new String[]{"Y", "append"},
      new String[]{"YY", "append"},
      new String[]{"YYY", "append"},
      new String[]{"YYYY", "append"},
      new String[]{"", ""},
      new String[]{"Q", "appendValue(IsoFields.QUARTER_OF_YEAR);"},
      new String[]{"QQ", "appendValue(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"QQQ", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"QQQQ", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"QQQQQ", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"q", "appendValue(IsoFields.QUARTER_OF_YEAR);"},
      new String[]{"qq", "appendValue(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"qqq", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"qqqq", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"qqqqq", "appendText(IsoFields.QUARTER_OF_YEAR,"},
      new String[]{"", ""},
      new String[]{"M", "appendValue(ChronoField.MONTH_OF_YEAR);"},
      new String[]{"MM", "appendValue(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"MMM", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"MMMM", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"MMMMM", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"L", "appendValue(ChronoField.MONTH_OF_YEAR);"},
      new String[]{"LL", "appendValue(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"LLL", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"LLLL", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"LLLLL", "appendText(ChronoField.MONTH_OF_YEAR,"},
      new String[]{"", ""},
      new String[]{"w", "append"},
      new String[]{"ww", "append"},
      new String[]{"W", "append"},
      new String[]{"d", "appendValue(ChronoField.DAY_OF_MONTH)"},
      new String[]{"dd", "appendValue(ChronoField.DAY_OF_MONTH,"},
      new String[]{"D", "appendValue(ChronoField.DAY_OF_YEAR)"},
      new String[]{"DD", "appendValue(ChronoField.DAY_OF_YEAR,"},
      new String[]{"DDD", "appendValue(ChronoField.DAY_OF_YEAR,"},
      new String[]{"F", "appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)"},
      new String[]{"E", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"EE", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"EEE", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"EEEE", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"EEEEE", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"e", "append"},
      new String[]{"ee", "append"},
      new String[]{"eee", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"eeee", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"eeeee", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"c", "append"},
      new String[]{"ccc", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"cccc", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"ccccc", "appendText(ChronoField.DAY_OF_WEEK,"},
      new String[]{"a", "appendText(ChronoField.AMPM_OF_DAY,"},
      new String[]{"h", "appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)"},
      new String[]{"hh", "appendValue(ChronoField.CLOCK_HOUR_OF_AMPM,"},
      new String[]{"H", "appendValue(ChronoField.HOUR_OF_DAY)"},
      new String[]{"HH", "appendValue(ChronoField.HOUR_OF_DAY,"},
      new String[]{"k", "appendValue(ChronoField.CLOCK_HOUR_OF_DAY)"},
      new String[]{"kk", "appendValue(ChronoField.CLOCK_HOUR_OF_DAY,"},
      new String[]{"K", "appendValue(ChronoField.HOUR_OF_AMPM)"},
      new String[]{"KK", "appendValue(ChronoField.HOUR_OF_AMPM,"},
      new String[]{"m", "appendValue(ChronoField.MINUTE_OF_HOUR)"},
      new String[]{"mm", "appendValue(ChronoField.MINUTE_OF_HOUR,"},
      new String[]{"s", "appendValue(ChronoField.SECOND_OF_MINUTE)"},
      new String[]{"ss", "appendValue(ChronoField.SECOND_OF_MINUTE,"},
      new String[]{"", ""},
      new String[]{"SSSS", "appendFraction(ChronoField.NANO_OF_SECOND,"},
      new String[]{"A", "appendValue(ChronoField.MILLI_OF_DAY)"},
      new String[]{"AAAA", "appendValue(ChronoField.MILLI_OF_DAY,"},
      new String[]{"n", "appendValue(ChronoField.NANO_OF_SECOND)"},
      new String[]{"nnnn", "appendValue(ChronoField.NANO_OF_SECOND,"},
      new String[]{"N", "appendValue(ChronoField.NANO_OF_DAY)"},
      new String[]{"NNNN", "appendValue(ChronoField.NANO_OF_DAY,"},
      new String[]{"VV", "appendZoneId()"},
      new String[]{"z", "appendZoneText(TextStyle.SHORT)"},
      new String[]{"zz", "appendZoneText(TextStyle.SHORT)"},
      new String[]{"zzz", "appendZoneText(TextStyle.SHORT)"},
      new String[]{"zzzz", "appendZoneText(TextStyle.FULL)"},
      new String[]{"O", "appendLocalizedOffsetPrefixed(TextStyle.SHORT);"},
      new String[]{"OOOO", "appendLocalizedOffsetPrefixed(TextStyle.FULL);"},
      new String[]{"X", "appendOffset(\"+HHmm\",\"Z\")"},
      new String[]{"XX", "appendOffset(\"+HHMM\",\"Z\")"},
      new String[]{"XXX", "appendOffset(\"+HH:MM\",\"Z\")"},
      new String[]{"XXXX", "appendOffset(\"+HHMMss\",\"Z\")"},
      new String[]{"XXXXX", "appendOffset(\"+HH:MM:ss\",\"Z\")"},
      new String[]{"x", "appendOffset(\"+HHmm\",\"+00\")"},
      new String[]{"xx", "appendOffset(\"+HHMM\",\"+0000\")"},
      new String[]{"xxx", "appendOffset(\"+HH:MM\",\"+00:00\")"},
      new String[]{"xxxx", "appendOffset(\"+HHMMss\",\"+0000\")"},
      new String[]{"xxxxx", "appendOffset(\"+HH:MM:ss\",\"+00:00\")"},
      new String[]{"Z", "appendOffset(\"+HHMM\",\"+0000\")"},
      new String[]{"ZZ", "appendOffset(\"+HHMM\",\"+0000\")"},
      new String[]{"ZZZ", "appendOffset(\"+HHMM\",\"+0000\")"},
      new String[]{"ZZZZ", "appendLocalizedOffset(TextStyle.FULL);"},
      new String[]{"ZZZZZ", "appendOffset(\"+HH:MM:ss\",\"Z\")"}
    };

    ZonedDateTime zonedDateTime = LocalDateTime
            .parse("2015-07-13T12:27:04")
            .atZone(ZoneId.of("Asia/Tokyo"));
    System.out.printf("%-7s : %-19s\t%-19s // %s\n", "Pattern", "English", "Japanese", "Comment");
    for (String[] pattern : patterns) {
      try {
      DateTimeFormatter enFormatter = DateTimeFormatter.ofPattern(pattern[0], Locale.ENGLISH);
      String en = zonedDateTime.format(enFormatter);

      DateTimeFormatter jpFormatter = DateTimeFormatter.ofPattern(pattern[0], Locale.JAPAN);
      String jp = zonedDateTime.format(jpFormatter);

        System.out.printf("%-7s : %-19s\t%-19s // %s\n", pattern[0], en, jp, pattern[1]);
      } catch (java.time.DateTimeException e) {
        System.err.printf("cannot format '%s': %s", pattern[0], e.getMessage());
      }
    }
  }

}

出力例は以下のようになる。

Pattern : English            	Japanese            // Comment
G       : AD                 	西暦                  // appendText(ChronoField.ERA,
GG      : AD                 	西暦                  // appendText(ChronoField.ERA,
GGG     : AD                 	西暦                  // appendText(ChronoField.ERA,
GGGG    : Anno Domini        	西暦                  // appendText(ChronoField.ERA,
GGGGG   : A                  	A                   // appendText(ChronoField.ERA,
        :                    	                    // 
u       : 2015               	2015                // appendValue(ChronoField.YEAR,
uu      : 15                 	15                  // appendValueReduced(ChronoField.YEAR,
uuu     : 2015               	2015                // appendValue(ChronoField.YEAR,
uuuu    : 2015               	2015                // appendValue(ChronoField.YEAR,
y       : 2015               	2015                // appendValue(ChronoField.YEAR_OF_ERA,
yy      : 15                 	15                  // appendValueReduced(ChronoField.YEAR_OF_ERA,
yyy     : 2015               	2015                // appendValue(ChronoField.YEAR_OF_ERA,
yyyy    : 2015               	2015                // appendValue(ChronoField.YEAR_OF_ERA,
Y       : 2015               	2015                // append
YY      : 15                 	15                  // append
YYY     : 2015               	2015                // append
YYYY    : 2015               	2015                // append
        :                    	                    // 
Q       : 3                  	3                   // appendValue(IsoFields.QUARTER_OF_YEAR);
QQ      : 03                 	03                  // appendValue(IsoFields.QUARTER_OF_YEAR,
QQQ     : Q3                 	Q3                  // appendText(IsoFields.QUARTER_OF_YEAR,
QQQQ    : 3rd quarter        	第3四半期               // appendText(IsoFields.QUARTER_OF_YEAR,
QQQQQ   : 3                  	3                   // appendText(IsoFields.QUARTER_OF_YEAR,
q       : 3                  	3                   // appendValue(IsoFields.QUARTER_OF_YEAR);
qq      : 03                 	03                  // appendValue(IsoFields.QUARTER_OF_YEAR,
qqq     : 3                  	3                   // appendText(IsoFields.QUARTER_OF_YEAR,
qqqq    : 3                  	3                   // appendText(IsoFields.QUARTER_OF_YEAR,
qqqqq   : 3                  	3                   // appendText(IsoFields.QUARTER_OF_YEAR,
        :                    	                    // 
M       : 7                  	7                   // appendValue(ChronoField.MONTH_OF_YEAR);
MM      : 07                 	07                  // appendValue(ChronoField.MONTH_OF_YEAR,
MMM     : Jul                	7                   // appendText(ChronoField.MONTH_OF_YEAR,
MMMM    : July               	7月                  // appendText(ChronoField.MONTH_OF_YEAR,
MMMMM   : J                  	J                   // appendText(ChronoField.MONTH_OF_YEAR,
L       : 7                  	7                   // appendValue(ChronoField.MONTH_OF_YEAR);
LL      : 07                 	07                  // appendValue(ChronoField.MONTH_OF_YEAR,
LLL     : 7                  	7                   // appendText(ChronoField.MONTH_OF_YEAR,
LLLL    : 7                  	7                   // appendText(ChronoField.MONTH_OF_YEAR,
LLLLL   : 7                  	7                   // appendText(ChronoField.MONTH_OF_YEAR,
        :                    	                    // 
w       : 29                 	29                  // append
cannot format 'DD': Field DayOfYear cannot be printed as the value 194 exceeds the maximum print width of 2
ww      : 29                 	29                  // append
W       : 3                  	3                   // append
d       : 13                 	13                  // appendValue(ChronoField.DAY_OF_MONTH)
dd      : 13                 	13                  // appendValue(ChronoField.DAY_OF_MONTH,
D       : 194                	194                 // appendValue(ChronoField.DAY_OF_YEAR)
DDD     : 194                	194                 // appendValue(ChronoField.DAY_OF_YEAR,
F       : 6                  	6                   // appendValue(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH)
E       : Mon                	月                   // appendText(ChronoField.DAY_OF_WEEK,
EE      : Mon                	月                   // appendText(ChronoField.DAY_OF_WEEK,
EEE     : Mon                	月                   // appendText(ChronoField.DAY_OF_WEEK,
EEEE    : Monday             	月曜日                 // appendText(ChronoField.DAY_OF_WEEK,
EEEEE   : M                  	月                   // appendText(ChronoField.DAY_OF_WEEK,
e       : 2                  	2                   // append
ee      : 02                 	02                  // append
eee     : Mon                	月                   // appendText(ChronoField.DAY_OF_WEEK,
eeee    : Monday             	月曜日                 // appendText(ChronoField.DAY_OF_WEEK,
eeeee   : M                  	月                   // appendText(ChronoField.DAY_OF_WEEK,
c       : 2                  	2                   // append
ccc     : Mon                	月                   // appendText(ChronoField.DAY_OF_WEEK,
cannot format 'AAAA': Field MilliOfDay cannot be printed as the value 44824000 exceeds the maximum print width of 4
cccc    : Monday             	月曜日                 // appendText(ChronoField.DAY_OF_WEEK,
ccccc   : 1                  	1                   // appendText(ChronoField.DAY_OF_WEEK,
a       : PM                 	午後                  // appendText(ChronoField.AMPM_OF_DAY,
cannot format 'NNNN': Field NanoOfDay cannot be printed as the value 44824000000000 exceeds the maximum print width of 4
h       : 12                 	12                  // appendValue(ChronoField.CLOCK_HOUR_OF_AMPM)
hh      : 12                 	12                  // appendValue(ChronoField.CLOCK_HOUR_OF_AMPM,
H       : 12                 	12                  // appendValue(ChronoField.HOUR_OF_DAY)
HH      : 12                 	12                  // appendValue(ChronoField.HOUR_OF_DAY,
k       : 12                 	12                  // appendValue(ChronoField.CLOCK_HOUR_OF_DAY)
kk      : 12                 	12                  // appendValue(ChronoField.CLOCK_HOUR_OF_DAY,
K       : 0                  	0                   // appendValue(ChronoField.HOUR_OF_AMPM)
KK      : 00                 	00                  // appendValue(ChronoField.HOUR_OF_AMPM,
m       : 27                 	27                  // appendValue(ChronoField.MINUTE_OF_HOUR)
mm      : 27                 	27                  // appendValue(ChronoField.MINUTE_OF_HOUR,
s       : 4                  	4                   // appendValue(ChronoField.SECOND_OF_MINUTE)
ss      : 04                 	04                  // appendValue(ChronoField.SECOND_OF_MINUTE,
        :                    	                    // 
SSSS    : 0000               	0000                // appendFraction(ChronoField.NANO_OF_SECOND,
A       : 44824000           	44824000            // appendValue(ChronoField.MILLI_OF_DAY)
n       : 0                  	0                   // appendValue(ChronoField.NANO_OF_SECOND)
nnnn    : 0000               	0000                // appendValue(ChronoField.NANO_OF_SECOND,
N       : 44824000000000     	44824000000000      // appendValue(ChronoField.NANO_OF_DAY)
VV      : Asia/Tokyo         	Asia/Tokyo          // appendZoneId()
z       : JST                	JST                 // appendZoneText(TextStyle.SHORT)
zz      : JST                	JST                 // appendZoneText(TextStyle.SHORT)
zzz     : JST                	JST                 // appendZoneText(TextStyle.SHORT)
zzzz    : Japan Standard Time	日本標準時               // appendZoneText(TextStyle.FULL)
O       : GMT+9              	GMT+9               // appendLocalizedOffsetPrefixed(TextStyle.SHORT);
OOOO    : GMT+09:00          	GMT+09:00           // appendLocalizedOffsetPrefixed(TextStyle.FULL);
X       : +09                	+09                 // appendOffset("+HHmm","Z")
XX      : +0900              	+0900               // appendOffset("+HHMM","Z")
XXX     : +09:00             	+09:00              // appendOffset("+HH:MM","Z")
XXXX    : +0900              	+0900               // appendOffset("+HHMMss","Z")
XXXXX   : +09:00             	+09:00              // appendOffset("+HH:MM:ss","Z")
x       : +09                	+09                 // appendOffset("+HHmm","+00")
xx      : +0900              	+0900               // appendOffset("+HHMM","+0000")
xxx     : +09:00             	+09:00              // appendOffset("+HH:MM","+00:00")
xxxx    : +0900              	+0900               // appendOffset("+HHMMss","+0000")
xxxxx   : +09:00             	+09:00              // appendOffset("+HH:MM:ss","+00:00")
Z       : +0900              	+0900               // appendOffset("+HHMM","+0000")
ZZ      : +0900              	+0900               // appendOffset("+HHMM","+0000")
ZZZ     : +0900              	+0900               // appendOffset("+HHMM","+0000")
ZZZZ    : GMT+09:00          	GMT+09:00           // appendLocalizedOffset(TextStyle.FULL);
ZZZZZ   : +09:00             	+09:00              // appendOffset("+HH:MM:ss","Z")

この一覧表を参考にしながらコーディングすれば、簡単にフォーマットできる。と思う。

先日公開した、Java8 Date and Time の cheat sheet にも追記した。 https://gist.github.com/tokuhirom/0b7441684653cb85cefa