在 Java8 API 中,有两种人类时间,本地日期/时间和带时区的时间。本地日期/时间表示一个日期和/或一天中是时间,但是不关联任何时区信息。例如,June 14,1903 就是一个本地日期。由于日期既不含一天中的时间,也不含时区信息,所以它无法与一个准确的瞬时点对应。相反,July 16,1969,09:32:00 EDT 就是一个带时区的日期/时间,它表示了时间轴上准确的一点。
有许多计算是不需要时区的,并且在某些情况下,考虑时区甚至可能导致错误的结果。假设你安排了一个每周 10:00 的会议,如果你在上一次带时区的时间上添加了 7 天,并且这期间恰好越过了夏令时,那么会议就会被提前或推迟1小时!
什么是夏令时?
夏令时(Daylight Saving Time,简称DST),又称“夏时制”、“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度。在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季,人们会人为将时间调快一小时,这样可以使人早起早睡,减少照明用电,以充分利用光照资源。
出于以上原因,API 的设计者们推荐不使用带时区的时间,除非你真的希望表示绝对的瞬时点。生日、假期、会议时间等,最好都用本地日期或时间来表示。
LocalDate 是一个不可变的日期时间对象,表示日期,通常被视为年月日。也可以访问其他日期字段,例如日期,星期几和星期。 例如,值“2007年10月2日”可存储在 LocalDate 。
LocalDate 不存储或表示时间或时区。相反,它是日期的描述,用于生日、纪念日等。它不能代表时间线上的瞬时信息( Instant),且没有附加信息,如偏移或时区。
LocalDate 主要特点:
不可变性:LocalDate 实例是不可变的,一旦创建就不能更改。
线程安全:由于不可变性,LocalDate 实例是线程安全的。
无时区:LocalDate 仅表示日期,没有时区信息。
工厂方法:提供了多种静态方法来创建 LocalDate 实例,如 now(), of(), parse() 等。
调整日期:提供了 plusDays(), plusWeeks(), plusMonths(), plusYears() 等方法来调整日期。
查询日期:提供了 getDayOfMonth(), getDayOfWeek(), getMonth(), getYear() 等方法来查询日期的各个部分。
日期比较:可以使用 equals(), isBefore(), isAfter() 等方法来比较两个日期。
日期格式化:可以使用 DateTimeFormatter 类来格式化 LocalDate 实例。
要创建一个 LocalDate,你可以使用静态方法 now() 或者 of(),例如:
package com.hxstrive.jdk8.date_time.local_date;
import java.time.LocalDate;
/**
* LocalDate 类
* @author hxstrive.com
*/
public class LocalDateDemo1 {
public static void main(String[] args) {
// 使用当前日期创建LocalDate实例
LocalDate today = LocalDate.now();
System.out.println("Today's date: " + today);
// 使用指定的年月日创建LocalDate实例
LocalDate someDate = LocalDate.of(2023, 3, 15);
System.out.println("Specific date: " + someDate);
// 解析字符串创建LocalDate实例
LocalDate parsedDate = LocalDate.parse("2023-03-15");
System.out.println("Parsed date: " + parsedDate);
//输出:
//Today's date: 2024-06-29
//Specific date: 2023-03-15
//Parsed date: 2023-03-15
}
}LocalDate 类提供了一些方法来调整日期,如:plusDays(), plusWeeks(), plusMonths(), plusYears() 等方法。例如:
package com.hxstrive.jdk8.date_time.local_date;
import java.time.LocalDate;
/**
* LocalDate 类
* @author hxstrive.com
*/
public class LocalDateDemo2 {
public static void main(String[] args) {
// 使用当前日期创建 LocalDate 实例
LocalDate today = LocalDate.now();
System.out.println("Today's date: " + today);
// Today's date: 2024-06-29
// 使用 plusYears 方法增加 10 年
LocalDate localDate1 = today.plusYears(10);
System.out.println(localDate1); // 2034-06-29
// 使用 plusMonths 方法增加 5 个月
LocalDate localDate2 = today.plusMonths(5);
System.out.println(localDate2); // 2024-11-29
// 使用 plusWeeks 方法增加 2 周
LocalDate localDate3 = today.plusWeeks(2);
System.out.println(localDate3); // 2024-07-13
// 使用 plusDays 方法增加 30 天
LocalDate localDate4 = today.plusDays(30);
System.out.println(localDate4); // 2024-07-29
}
}LocalDate 类提供了多种方法来查询日期的相关信息,以下是一些常见的方法:
getYear():获取年份。
getMonthValue():获取月份,返回 1 到 12 的整数值。
getMonth():获取月份,返回Month枚举类型。
getDayOfMonth():获取该月的第几天。
getDayOfYear():获取该年的第几天。
getDayOfWeek():获取星期几,返回 DayOfWeek 枚举类型。DayOfWeek 是一个枚举类型,用于表示一周中的星期几,取值如下:
MONDAY 表示星期一
TUESDAY 表示星期二
WEDNESDAY 表示星期三
THURSDAY 表示星期四
FRIDAY 表示星期五
SATURDAY 表示星期六
SUNDAY 表示星期天
DayOfWeek 枚举还提供了一些方便的方法 plus 和 minus, 用来计算值为 7 是星期几。例如 Dayofweek.SATURDAY.plus(3) 会返回 DayofWeek.TUESDAY。
注意:DayOfWeek 中周末实际上位于一周的末尾,这与 java.util.Calendar 不同。在 java.util.Calendar 中,周日的值为1, 而周六的值为7。
示例:
package com.hxstrive.jdk8.date_time.local_date;
import java.time.LocalDate;
/**
* LocalDate 类
* @author hxstrive.com
*/
public class LocalDateDemo3 {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
int year = today.getYear();
System.out.println("年份: " + year); //年份: 2024
int monthValue = today.getMonthValue();
System.out.println("月份(数字): " + monthValue); //月份(数字): 6
java.time.Month month = today.getMonth();
System.out.println("月份(枚举): " + month); //月份(枚举): JUNE
int dayOfMonth = today.getDayOfMonth();
System.out.println("该月第几天: " + dayOfMonth); //该月第几天: 29
int dayOfYear = today.getDayOfYear();
System.out.println("该年第几天: " + dayOfYear); //该年第几天: 181
java.time.DayOfWeek dayOfWeek = today.getDayOfWeek();
System.out.println("星期几(枚举): " + dayOfWeek); //星期几(枚举): SATURDAY
boolean leapYear = today.isLeapYear();
System.out.println("是否是闰年: " + leapYear); //是否是闰年: true
}
}LocalDate 类提供了一些用于日期比较的方法,常见的有:
isBefore(other):判断当前日期是否在另一个日期之前,如果是则返回true,否则返回false。
isAfter(other):判断当前日期是否在另一个日期之后,如果是则返回true,否则返回false。
isEqual(other):判断当前日期与另一个日期是否相等,如果相等则返回true,否则返回false。
例如:
package com.hxstrive.jdk8.date_time.local_date;
import java.time.LocalDate;
/**
* LocalDate 类
* @author hxstrive.com
*/
public class LocalDateDemo4 {
public static void main(String[] args) {
LocalDate date1 = LocalDate.of(2024, 6, 29);
LocalDate date2 = LocalDate.of(2024, 7, 1);
// 判断 date1 是否在 date2 之前
boolean isBefore = date1.isBefore(date2);
System.out.println("date1 在 date2 之前? " + isBefore);
//date1 在 date2 之前? true
// 判断 date1 是否在 date2 之后
boolean isAfter = date1.isAfter(date2);
System.out.println("date1 在 date2 之后? " + isAfter);
//date1 在 date2 之后? false
// 判断 date1 是否与 date2 相等
boolean isEqual = date1.isEqual(date2);
System.out.println("date1 与 date2 相等? " + isEqual);
//date1 与 date2 相等? false
}
}