非 ISO 日期转换

原文: https://docs.oracle.com/javase/tutorial/datetime/iso/nonIso.html

本教程不会详细讨论 java.time.chrono包。但是,知道此软件包提供了几个非基于 ISO 的预定义年表可能会很有用,例如日语,Hijrah,Minguo 和 Thai Buddhist。您也可以使用此包创建自己的年表。

本节介绍如何在其中一个预定义的年表中转换基于 ISO 的日期和日期。

转换为非基于 ISO 的日期

您可以使用来自(TemporalAccessor)方法的将基于 ISO 的日期转换为另一个年代的日期,例如 [JapaneseDate.from(TemporalAccessor)](https://docs.oracle.com/javase/8/docs/api/java/time/chrono/JapaneseDate.html#from-java.time.temporal.TemporalAccessor-) 。如果此方法无法将日期转换为有效实例,则抛出DateTimeException。以下代码将LocalDateTime实例转换为若干预定义的非 ISO 日历日期:

  1. LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
  2. JapaneseDate jdate = JapaneseDate.from(date);
  3. HijrahDate hdate = HijrahDate.from(date);
  4. MinguoDate mdate = MinguoDate.from(date);
  5. ThaiBuddhistDate tdate = ThaiBuddhistDate.from(date);

`StringConverter `例子从LocalDate转换为ChronoLocalDateString和背部。 toString方法采用LocalDateChronology的实例,并使用提供的Chronology返回转换后的字符串。 DateTimeFormatterBuilder用于构建可用于打印日期的字符串:

  1. /**
  2. * Converts a LocalDate (ISO) value to a ChronoLocalDate date
  3. * using the provided Chronology, and then formats the
  4. * ChronoLocalDate to a String using a DateTimeFormatter with a
  5. * SHORT pattern based on the Chronology and the current Locale.
  6. *
  7. * @param localDate - the ISO date to convert and format.
  8. * @param chrono - an optional Chronology. If null, then IsoChronology is used.
  9. */
  10. public static String toString(LocalDate localDate, Chronology chrono) {
  11. if (localDate != null) {
  12. Locale locale = Locale.getDefault(Locale.Category.FORMAT);
  13. ChronoLocalDate cDate;
  14. if (chrono == null) {
  15. chrono = IsoChronology.INSTANCE;
  16. }
  17. try {
  18. cDate = chrono.date(localDate);
  19. } catch (DateTimeException ex) {
  20. System.err.println(ex);
  21. chrono = IsoChronology.INSTANCE;
  22. cDate = localDate;
  23. }
  24. DateTimeFormatter dateFormatter =
  25. DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
  26. .withLocale(locale)
  27. .withChronology(chrono)
  28. .withDecimalStyle(DecimalStyle.of(locale));
  29. String pattern = "M/d/yyyy GGGGG";
  30. return dateFormatter.format(cDate);
  31. } else {
  32. return "";
  33. }
  34. }

对于预定义的年表,使用以下日期调用方法时:

  1. LocalDate date = LocalDate.of(1996, Month.OCTOBER, 29);
  2. System.out.printf("%s%n",
  3. StringConverter.toString(date, JapaneseChronology.INSTANCE));
  4. System.out.printf("%s%n",
  5. StringConverter.toString(date, MinguoChronology.INSTANCE));
  6. System.out.printf("%s%n",
  7. StringConverter.toString(date, ThaiBuddhistChronology.INSTANCE));
  8. System.out.printf("%s%n",
  9. StringConverter.toString(date, HijrahChronology.INSTANCE));

输出如下所示:

  1. 10/29/0008 H
  2. 10/29/0085 1
  3. 10/29/2539 B.E.
  4. 6/16/1417 1

转换为基于 ISO 的日期

您可以使用静态 LocalDate.from方法从非 ISO 日期转换为LocalDate实例,如以下示例所示:

  1. LocalDate date = LocalDate.from(JapaneseDate.now());

其他基于时间的类也提供此方法,如果无法转换日期,则抛出DateTimeException

来自 `StringConverter `示例的fromString方法解析包含非 ISO 日期的String并返回一个LocalDate实例。

  1. /**
  2. * Parses a String to a ChronoLocalDate using a DateTimeFormatter
  3. * with a short pattern based on the current Locale and the
  4. * provided Chronology, then converts this to a LocalDate (ISO)
  5. * value.
  6. *
  7. * @param text - the input date text in the SHORT format expected
  8. * for the Chronology and the current Locale.
  9. *
  10. * @param chrono - an optional Chronology. If null, then IsoChronology
  11. * is used.
  12. */
  13. public static LocalDate fromString(String text, Chronology chrono) {
  14. if (text != null && !text.isEmpty()) {
  15. Locale locale = Locale.getDefault(Locale.Category.FORMAT);
  16. if (chrono == null) {
  17. chrono = IsoChronology.INSTANCE;
  18. }
  19. String pattern = "M/d/yyyy GGGGG";
  20. DateTimeFormatter df = new DateTimeFormatterBuilder().parseLenient()
  21. .appendPattern(pattern)
  22. .toFormatter()
  23. .withChronology(chrono)
  24. .withDecimalStyle(DecimalStyle.of(locale));
  25. TemporalAccessor temporal = df.parse(text);
  26. ChronoLocalDate cDate = chrono.date(temporal);
  27. return LocalDate.from(cDate);
  28. }
  29. return null;
  30. }

使用以下字符串调用方法时:

  1. System.out.printf("%s%n", StringConverter.fromString("10/29/0008 H",
  2. JapaneseChronology.INSTANCE));
  3. System.out.printf("%s%n", StringConverter.fromString("10/29/0085 1",
  4. MinguoChronology.INSTANCE));
  5. System.out.printf("%s%n", StringConverter.fromString("10/29/2539 B.E.",
  6. ThaiBuddhistChronology.INSTANCE));
  7. System.out.printf("%s%n", StringConverter.fromString("6/16/1417 1",
  8. HijrahChronology.INSTANCE));

打印的字符串应全部转换回 1996 年 10 月 29 日:

  1. 1996-10-29
  2. 1996-10-29
  3. 1996-10-29
  4. 1996-10-29