文档

Java™教程
隐藏目录
非ISO日期转换
路径:日期 时间
课程:标准日历

非ISO日期转换

本教程不详细讨论java.time.chrono包。然而,知道这个包提供了几个预定义的非ISO基准的年代历法可能会有用,例如日本、伊斯兰、民国和泰国佛教历法。您也可以使用这个包来创建自己的年代历法。

本节将向您展示如何在ISO基准日期和其他预定义年代历法之间进行转换。

转换为非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);

示例StringConverterLocalDate转换为ChronoLocalDate,再转换为String,然后再转换回来。toString方法接受LocalDate实例和Chronology,并使用提供的Chronology返回转换后的字符串。使用DateTimeFormatterBuilder构建可用于打印日期的字符串:

/**
 * 使用提供的年代历法将ISO的LocalDate值转换为ChronoLocalDate日期,
 * 然后使用基于年代历法和当前区域设置的SHORT模式的DateTimeFormatter
 * 格式化ChronoLocalDate为String。
 *
 * @param localDate - 要转换和格式化的ISO日期。
 * @param chrono - 可选的年代历法。如果为null,则使用IsoChronology。
 */
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

转换为基于ISO的日期

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

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

其他基于时间的类也提供了这个方法,如果无法转换日期,则会抛出DateTimeException异常。

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

/**
 * 使用基于当前语言环境和提供的年表的短格式的DateTimeFormatter
 * 将字符串解析为ChronoLocalDate,然后将其转换为LocalDate(ISO)值。
 *
 * @param text   - Chronology和当前语言环境所期望的SHORT格式的输入日期文本。
 *
 * @param chrono - 可选的年表。如果为null,则使用IsoChronology。
 */
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

上一页: 时钟
下一页: 传统日期时间代码