Java Chronology 接口
最后修改时间:2025 年 4 月 16 日
java.time.chrono.Chronology
接口表示一个用于组织和识别日期的日历系统。它提供了在标准 ISO-8601 日历之外,在不同日历系统中计算日期的规则。
Chronology
由各种日历系统实现,如泰历、回历和日本历。它允许使用非格里高利历的日期。该接口提供了创建日期和查询日历属性的方法。
Chronology 接口概述
Chronology
定义了创建日期对象、确定日历属性以及在日历系统之间转换的方法。它充当 Java 时间 API 中所有日历系统的抽象基类。
public interface Chronology extends Comparable<Chronology> { String getId(); String getCalendarType(); ChronoLocalDate date(int prolepticYear, int month, int dayOfMonth); ChronoLocalDate dateEpochDay(long epochDay); ChronoLocalDate dateNow(); boolean isLeapYear(long prolepticYear); int prolepticYear(Era era, int yearOfEra); Era eraOf(int eraValue); List<Era> eras(); ValueRange range(ChronoField field); }
上面的代码展示了 Chronology
接口的关键方法。这些方法允许创建日期、检查闰年和访问日历纪元。每个日历系统都提供了这些方法的自己的实现。
获取可用的 Chronology
Java 提供了几个内置的 Chronology 实现。我们可以使用 getAvailableChronologies
方法列出所有可用的 Chronology。这有助于发现受支持的日历系统。
package com.zetcode; import java.time.chrono.Chronology; import java.util.Set; public class Main { public static void main(String[] args) { // Get all available chronologies Set<Chronology> chronologies = Chronology.getAvailableChronologies(); System.out.println("Available calendar systems:"); for (Chronology chrono : chronologies) { System.out.println(chrono.getId() + " - " + chrono.getCalendarType()); } // Get default ISO chronology Chronology iso = Chronology.of("ISO"); System.out.println("\nDefault chronology: " + iso.getId()); } }
此示例列出了 JVM 中所有可用的日历系统。输出通常包括 ISO、泰历、回历和日本历。ISO Chronology 是默认的格里高利历系统。
在不同日历中创建日期
每个 Chronology 都可以创建特定于其日历系统的日期对象。date
方法使用年、月和日的值创建日期。也可以从纪元日创建日期。
package com.zetcode; import java.time.chrono.Chronology; import java.time.chrono.JapaneseDate; import java.time.chrono.ThaiBuddhistDate; public class Main { public static void main(String[] args) { // Create ISO date Chronology iso = Chronology.of("ISO"); var isoDate = iso.date(2025, 4, 15); System.out.println("ISO date: " + isoDate); // Create Japanese date Chronology japanese = Chronology.of("Japanese"); var japaneseDate = japanese.date(2025, 4, 15); System.out.println("Japanese date: " + japaneseDate); // Create Thai Buddhist date var thaiDate = ThaiBuddhistDate.now(); System.out.println("Thai Buddhist date: " + thaiDate); // Create date from epoch day var epochDate = iso.dateEpochDay(10000); System.out.println("Date from epoch day: " + epochDate); } }
此示例演示了在不同日历系统中创建日期。请注意,在不同的日历中,相同的年/月/日值如何产生不同的日期。dateEpochDay
方法从自 1970-01-01 以来经过的天数创建日期。
使用日历纪元
许多日历系统使用纪元将时间划分为不同的时期。Chronology
接口提供了使用这些纪元的方法。每个日历都定义了自己的纪元系统。
package com.zetcode; import java.time.chrono.Chronology; import java.time.chrono.JapaneseDate; import java.time.chrono.JapaneseEra; import java.time.chrono.ThaiBuddhistDate; public class Main { public static void main(String[] args) { // Get eras for Japanese calendar Chronology japanese = Chronology.of("Japanese"); System.out.println("Japanese eras:"); japanese.eras().forEach(era -> System.out.println(era)); // Create date in specific era JapaneseDate jdate = JapaneseDate.of(JapaneseEra.HEISEI, 30, 4, 15); System.out.println("\nHeisei era date: " + jdate); // Convert between era year and proleptic year int prolepticYear = japanese.prolepticYear(JapaneseEra.HEISEI, 30); System.out.println("Proleptic year: " + prolepticYear); // Get era of a date var thaiDate = ThaiBuddhistDate.now(); System.out.println("\nThai Buddhist era: " + thaiDate.getEra()); } }
此示例展示了如何使用日历纪元。日本历有多个代表天皇统治时期的纪元。prolepticYear
方法在纪元年份和连续年份计数之间进行转换。
检查闰年
不同的日历系统对闰年有不同的规则。isLeapYear
方法根据 Chronology 的规则检查某一年是否为闰年。
package com.zetcode; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.ThaiBuddhistChronology; public class Main { public static void main(String[] args) { // Check leap years in different calendars Chronology iso = Chronology.of("ISO"); System.out.println("ISO 2024 is leap: " + iso.isLeapYear(2024)); Chronology thai = ThaiBuddhistChronology.INSTANCE; System.out.println("Thai 2567 is leap: " + thai.isLeapYear(2567)); Chronology hijrah = HijrahChronology.INSTANCE; System.out.println("Hijrah 1445 is leap: " + hijrah.isLeapYear(1445)); // Range of valid years System.out.println("\nISO year range: " + iso.range(ChronoField.YEAR)); } }
此示例演示了在不同日历系统中检查闰年。请注意,同一年在一个日历中可能是闰年,而在另一个日历中则不是。range
方法显示了每个日历的有效年份值。
在日历之间转换
日期可以在不同的日历系统之间转换。这对于以多种日历格式显示日期或与旧系统一起使用非常有用。
package com.zetcode; import java.time.LocalDate; import java.time.chrono.ChronoLocalDate; import java.time.chrono.JapaneseDate; import java.time.chrono.ThaiBuddhistDate; public class Main { public static void main(String[] args) { // Convert ISO to other calendars LocalDate isoDate = LocalDate.of(2025, 4, 15); System.out.println("ISO date: " + isoDate); JapaneseDate japaneseDate = JapaneseDate.from(isoDate); System.out.println("Japanese date: " + japaneseDate); ThaiBuddhistDate thaiDate = ThaiBuddhistDate.from(isoDate); System.out.println("Thai Buddhist date: " + thaiDate); // Convert back to ISO LocalDate backFromJapanese = LocalDate.from(japaneseDate); System.out.println("\nBack to ISO from Japanese: " + backFromJapanese); // ChronoLocalDate operations ChronoLocalDate chronoDate = thaiDate; System.out.println("Day of week: " + chronoDate.get(ChronoField.DAY_OF_WEEK)); } }
此示例展示了 ISO 和其他日历系统之间的转换。from
方法执行转换,而 ChronoLocalDate
提供了常见的操作。所有转换都保持相同的时间点。
格式化 Chronology 日期
可以使用 DateTimeFormatter
格式化来自不同 Chronology 的日期。格式化程序可以使用 Chronology 特定的模式和区域设置。
package com.zetcode; import java.time.chrono.JapaneseDate; import java.time.chrono.ThaiBuddhistDate; import java.time.format.DateTimeFormatter; import java.util.Locale; public class Main { public static void main(String[] args) { // Format Japanese date JapaneseDate jdate = JapaneseDate.now(); DateTimeFormatter jformatter = DateTimeFormatter .ofPattern("GGGG y年 M月 d日") .withLocale(Locale.JAPANESE); System.out.println("Japanese formatted: " + jformatter.format(jdate)); // Format Thai Buddhist date ThaiBuddhistDate tdate = ThaiBuddhistDate.now(); DateTimeFormatter tformatter = DateTimeFormatter .ofPattern("G y年 M月 d日") .withLocale(new Locale("th", "TH")); System.out.println("Thai formatted: " + tformatter.format(tdate)); // Parse date in different chronology String text = "令和 7年 4月 15日"; JapaneseDate parsed = JapaneseDate.parse(text, jformatter); System.out.println("\nParsed Japanese date: " + parsed); } }
此示例演示了在不同日历系统中格式化和解析日期。格式化程序使用特定于区域设置的模式和纪元名称。请注意,对于日本日期,使用 GGGG
表示完整的纪元名称。
来源
在本文中,我们介绍了 Java Chronology 接口的基本方法和功能。理解这些概念对于在 Java 应用程序中使用多个日历系统至关重要。
作者
列出所有Java教程。