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教程。