本文所有源码的jdk版本是:jdk-13.0.1
Chronology接口代表日历系统接口,实现这个接口的类表示某一个日历系统。
Chronology接口的官方文档:https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/time/chrono/Chronology.html
世界上有很多不同的日历系统。其中我们日常使用的公历属于ISO日历系统,这个是世界通用的标准日历系统。除此之外还有非通用的,比如日本历、泰国日历、中华民国日历、伊斯兰历、农历等。
java已经写好了一些类代表一些常用的日历系统:
其中IsoChronology类就是代表ISO日历系统。HijrahChronology是伊斯兰日历系统,JapaneseChronology是日本历,MinguoChronology是民国历,ThaiBuddhistChronology是泰国佛教历。除了ISO日历系统,其他日历系统我们都不怎么用,因此不作介绍。而java的日期依赖的就是ISO日历系统。
这里介绍其中一个静态属性:
/**
* Singleton instance of the ISO chronology.
*/
public static final IsoChronology INSTANCE = new IsoChronology();
这里用了单例设计模式,因为日历系统只需要一个就够了。这个类的构造方法是私有的,所以获取ISO日历系统实例的方法只有:
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
}
获取IsoChronology类所代表的日历系统的ID和类型
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
System.out.println(iso.getId());//ISO
System.out.println(iso.getCalendarType());//iso8601
}
用日历系统创建本地LocalDate日期对象,传入时代对象、年、月、日
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
LocalDate ld1=iso.date(1,1,1);
System.out.println(ld1);// 0001-01-01
//公历公元1年为0001年,以公元前1年为0000年,公元前2年为-0001年,其他以此类推。
//A definition has therefore been created with two eras
//'Current era' (CE) for years on or after 0001-01-01 (ISO)
//and 'Before current era' (BCE) for years before that.
LocalDate ld2=iso.date(IsoEra.BCE,10,10,10);
System.out.println(ld2);// -0009-10-10
LocalDate ld3=iso.date(IsoEra.CE,10,10,10);
System.out.println(ld3);// 0010-10-10
}
不同的日历系统有不同的时代划分,比如公历有两个:公元(CE)和公元前(BCE);而日本历则每一个天皇都可能有一个时代,比如明治时代、昭和时代等。关于上述几个日历系统的时代java已经帮我们枚举出来了,有空大家可以查看一下源码:
Era接口的官方文档:https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/time/chrono/Era.html
根据时代对象、年、天数来创建本地LocalDate对象。天数必须要传1~365/366之间的整数,否则报错。
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
LocalDate ld1=iso.dateYearDay(2, 100);
System.out.println(ld1);// 0002-04-10
LocalDate ld2=iso.dateYearDay(IsoEra.CE, 2, 100);
System.out.println(ld2);
LocalDate ld3=iso.dateYearDay(IsoEra.BCE, 2, 100);
System.out.println(ld3);// -0001-04-10
}
dateEpochDay(long)方法从纪元天开始按传入的天数获取本地日期。纪元天指1970-01-01
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
LocalDate ld1=iso.dateEpochDay(0);
System.out.println(ld1);// 1970-01-01
LocalDate ld2=iso.dateEpochDay(10);
System.out.println(ld2);// 1970-01-11
}
从另一个日期时间对象获取ISO当地日期。和LocalDate.from(TemporalAccessor)等价
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
LocalDate ld1=iso.date(LocalDate.of(1, 1, 1));
System.out.println(ld1);// 0001-01-01
}
从 1970-01-01T00:00:00Z 的UTC时间开始获取到指定的日期时间的秒数。可以为负数。ZoneOffset对象指与格林威治/ UTC的时区偏移量,北京时间是东八区时间,时区偏移量是+0800(比UTC时间快8小时)。
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
long seconds=iso.epochSecond(2019, 12, 16, 20, 48, 30, ZoneOffset.of("+0800"));
System.out.println(seconds);// 1576500510
long seconds2=iso.epochSecond(IsoEra.CE, 1960, 12, 16, 20, 48, 30, ZoneOffset.of("+0800"));
System.out.println(seconds2);// -285333090
}
关于ZoneOffset类的详细介绍请移步我的另一篇博文>>>Java日期时间主要API:java.time.ZoneId及其子类ZoneOffset
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//LocalDateTime是本地时间,和操作系统时间同步,不带有时区信息
//ZoneDateTime也是本地时间,但是带有时区信息。
//从另一个时间对象获取此时间顺序中的本地日期时间(简直就是复制)
LocalDateTime ldt=iso.localDateTime(LocalDateTime.of(2019, 12, 12, 12, 12,12));
System.out.println(ldt);// 2019-12-12T12:12:12
//和上面一样。
ZonedDateTime zdt1=iso.zonedDateTime(ZonedDateTime.now());
System.out.println(zdt1);// 2019-12-16T21:22:18.583088800+08:00[Asia/Shanghai]
//根据时间瞬时点和该瞬时点的时区来创建一个日期时间对象
ZonedDateTime zdt2=iso.zonedDateTime(Instant.now(),ZoneId.of("America/New_York"));
System.out.println(zdt2);// 2019-12-16T21:22:18.583088800-05:00[America/New_York]
}
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//当前日期
LocalDate ld1=iso.dateNow();
System.out.println(ld1);//2019-12-16
//现在北京时间是12月16日22时,而太平洋/奥克兰时区的日期已经是12月17日了
LocalDate ld2=iso.dateNow(ZoneId.of("Pacific/Auckland"));
System.out.println(ld2);//2019-12-17
//Clock可以理解为就是一个时钟,有日期时间等信息,通过某些方法获取这些信息
//Clock.systemUTC()获取当下零时区的时钟,根据时钟的日期信息创建一个日期对象。
LocalDate ld3=iso.dateNow(Clock.systemUTC());
System.out.println(ld3);//2019-12-16
}
关于Clock类的详细介绍请移步我的另一篇博文>>>Java日期时间主要API:java.time.Clock抽象类及其子类
isLeapYear(long)查看给定的年份是否为闰年
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
System.out.println(iso.isLeapYear(2004)); //true
}
prolepticYear(Era, int)给定一个Era对象和一个int类型数值,看看这个数值在这个时代中代表多少年。
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//公元前2003年
System.out.println(iso.prolepticYear(IsoEra.BCE, 2004)); //-2003
}
eraOf(int)根据数字值创建年代时代对象。从概念上讲,该时代是时间线的最大划分。大多数日历系统只有一个纪元,将时间线分为两个时代。但是,有些有多个时代,例如每个领导人的统治时期。确切的含义由时间顺序根据以下约束条件确定:1970年1月1日使用的时代必须具有值1。以后的时代必须具有依次更高的值。较早的时代必须具有依次较低的值。每个日历系统必须引用一个枚举或类似的单例来提供时代值。
在ISO日历系统中,java已经用一个枚举类IsoEra为我们枚举了两个时代值:BCE(公元前,值为0)和CE(公元,值为1)。
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//公元前
System.out.println(iso.eraOf(0)); //BCE
//公元
System.out.println(iso.eraOf(1)); //CE
}
eras()方法返回这个日历系统的所有时代的list集合
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//ISO日历系统的所有时代集合
System.out.println(iso.eras()); //[BCE, CE]
JapaneseChronology japan=JapaneseChronology.INSTANCE;
//日本历所有时代集合
System.out.println(japan.eras());//[Meiji, Taisho, Showa, Heisei, Reiwa]
}
resolveDate(Map
range(ChronoField)查看这个日历系统的一些日期时间字段的数值范围
public static void main(String[] args) {
IsoChronology iso=IsoChronology.INSTANCE;
//ISO日历系统中每月的天数这个字段的数值范围是多少(每月最小值是1,最大值在28~31天之间)
System.out.println(iso.range(ChronoField.DAY_OF_MONTH)); //1 - 28/31
}
ChronoField是日期时间字段的枚举类。关于ChronoField类的详细介绍请移步我的另一篇博文>>>Java日期时间主要API:java.time.temporal.TemporalField接口及其实现类ChronoField
period(int, int, int)这个方法与Period.of(int years, int months, int days)这个方法等价
谢谢浏览!