Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
本教程不会详细讨论 java.time.chrono 包。但是,知道此软件包提供了几个基于非 ISO 的预定义年表可能会很有用,例如 Japanese,Hijrah,Minguo 和 Thai Buddhist。你也可以使用此包创建自己的年表。
本节介绍如何在其中一个预定义的年表和基于 ISO 的日期和日期间转换。
你可以使用 from(TemporalAccessor) 方法将基于 ISO 的日期转换为另一个年代表中的日期,例如 JapaneseDate.from(TemporalAccessor)。如果此方法无法将日期转换为有效实例,则抛出 DateTimeException。以下代码将 LocalDateTime 实例转换为若干预定义的非 ISO 日历日期:
LocalDateTime date = LocalDateTime.of(2013, Month.JULY, 20, 19, 30); JapaneseDate jdate = JapaneseDate.from(date); HijrahDate hdate = HijrahDate.from(date); MinguoDate mdate = MinguoDate.from(date); ThaiBuddhistDate tdate = ThaiBuddhistDate.from(date);
StringConverter
示例从 LocalDate 转换为 ChronoLocalDate 到 String 并返回。toString 方法采用 LocalDate 和 Chronology 的实例,并使用提供的 Chronology 返回转换后的字符串。DateTimeFormatterBuilder 用于构建可用于打印日期的字符串:
/** * Converts a LocalDate (ISO) value to a ChronoLocalDate date * using the provided Chronology, and then formats the * ChronoLocalDate to a String using a DateTimeFormatter with a * SHORT pattern based on the Chronology and the current Locale. * * @param localDate - the ISO date to convert and format. * @param chrono - an optional Chronology. If null, then IsoChronology is used. */ public static String toString(LocalDate localDate, Chronology chrono) { if (localDate != null) { Locale locale = Locale.getDefault(Locale.Category.FORMAT); ChronoLocalDate cDate; if (chrono == null) { chrono = IsoChronology.INSTANCE; } try { cDate = chrono.date(localDate); } catch (DateTimeException ex) { System.err.println(ex); chrono = IsoChronology.INSTANCE; cDate = localDate; } DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT) .withLocale(locale) .withChronology(chrono) .withDecimalStyle(DecimalStyle.of(locale)); String pattern = "M/d/yyyy GGGGG"; return dateFormatter.format(cDate); } else { return ""; } }
对于预定义的年表,使用以下日期调用方法时:
LocalDate date = LocalDate.of(1996, Month.OCTOBER, 29); System.out.printf("%s%n", StringConverter.toString(date, JapaneseChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.toString(date, MinguoChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.toString(date, ThaiBuddhistChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.toString(date, HijrahChronology.INSTANCE));
输出如下所示:
10/29/0008 H 10/29/0085 1 10/29/2539 B.E. 6/16/1417 1
你可以使用静态 LocalDate.from 方法从非 ISO 日期转换为 LocalDate 实例,如以下示例所示:
LocalDate date = LocalDate.from(JapaneseDate.now());
其他基于时间的类也提供此方法,如果无法转换日期,则抛出 DateTimeException。
来自 StringConverter
示例的 fromString 方法解析包含非 ISO 日期的 String 并返回 LocalDate 实例。
/** * Parses a String to a ChronoLocalDate using a DateTimeFormatter * with a short pattern based on the current Locale and the * provided Chronology, then converts this to a LocalDate (ISO) * value. * * @param text - the input date text in the SHORT format expected * for the Chronology and the current Locale. * * @param chrono - an optional Chronology. If null, then IsoChronology * is used. */ public static LocalDate fromString(String text, Chronology chrono) { if (text != null && !text.isEmpty()) { Locale locale = Locale.getDefault(Locale.Category.FORMAT); if (chrono == null) { chrono = IsoChronology.INSTANCE; } String pattern = "M/d/yyyy GGGGG"; DateTimeFormatter df = new DateTimeFormatterBuilder().parseLenient() .appendPattern(pattern) .toFormatter() .withChronology(chrono) .withDecimalStyle(DecimalStyle.of(locale)); TemporalAccessor temporal = df.parse(text); ChronoLocalDate cDate = chrono.date(temporal); return LocalDate.from(cDate); } return null; }
使用以下字符串调用该方法时:
System.out.printf("%s%n", StringConverter.fromString("10/29/0008 H", JapaneseChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.fromString("10/29/0085 1", MinguoChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.fromString("10/29/2539 B.E.", ThaiBuddhistChronology.INSTANCE)); System.out.printf("%s%n", StringConverter.fromString("6/16/1417 1", HijrahChronology.INSTANCE));
打印的字符串应全部转换回 1996 年 10 月 29 日:
1996-10-29 1996-10-29 1996-10-29 1996-10-29