日期时间API
概述
Java 8引入了新的日期时间API(java.time包),解决了旧API(Date、Calendar)的线程安全和设计问题。
LocalDate
表示日期(年月日)。
java
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class LocalDateDemo {
public static void main(String[] args) {
// 创建
LocalDate today = LocalDate.now(); // 当前日期
LocalDate date = LocalDate.of(2024, 1, 1); // 指定日期
LocalDate parse = LocalDate.parse("2024-01-01"); // 解析
// 获取信息
System.out.println("年: " + today.getYear());
System.out.println("月: " + today.getMonth());
System.out.println("月: " + today.getMonthValue());
System.out.println("日: " + today.getDayOfMonth());
System.out.println("星期: " + today.getDayOfWeek());
System.out.println("年中第几天: " + today.getDayOfYear());
// 计算
LocalDate tomorrow = today.plusDays(1);
LocalDate lastWeek = today.minusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);
// 比较
boolean isBefore = today.isBefore(tomorrow);
boolean isAfter = today.isAfter(lastWeek);
boolean isLeap = today.isLeapYear();
// 调整
LocalDate firstDayOfMonth = today.withDayOfMonth(1);
LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth());
// 格式化
String formatted = today.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
System.out.println(formatted);
}
}LocalTime
表示时间(时分秒)。
java
import java.time.LocalTime;
public class LocalTimeDemo {
public static void main(String[] args) {
// 创建
LocalTime now = LocalTime.now();
LocalTime time = LocalTime.of(14, 30, 0);
LocalTime parse = LocalTime.parse("14:30:00");
// 获取信息
System.out.println("时: " + now.getHour());
System.out.println("分: " + now.getMinute());
System.out.println("秒: " + now.getSecond());
System.out.println("纳秒: " + now.getNano());
// 计算
LocalTime later = now.plusHours(1);
LocalTime earlier = now.minusMinutes(30);
// 比较
boolean isBefore = now.isBefore(later);
// 常用时间
LocalTime midnight = LocalTime.MIDNIGHT; // 00:00
LocalTime noon = LocalTime.NOON; // 12:00
LocalTime min = LocalTime.MIN; // 00:00
LocalTime max = LocalTime.MAX; // 23:59:59.999999999
}
}LocalDateTime
表示日期和时间。
java
import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class LocalDateTimeDemo {
public static void main(String[] args) {
// 创建
LocalDateTime now = LocalDateTime.now();
LocalDateTime dateTime = LocalDateTime.of(2024, 1, 1, 10, 30);
LocalDateTime dateTime2 = LocalDateTime.of(LocalDate.now(), LocalTime.now());
// 解析
LocalDateTime parse = LocalDateTime.parse("2024-01-01T10:30:00");
LocalDateTime parse2 = LocalDateTime.parse("2024-01-01 10:30:00",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
// 获取LocalDate和LocalTime
LocalDate date = now.toLocalDate();
LocalTime time = now.toLocalTime();
// 计算
LocalDateTime tomorrow = now.plusDays(1);
LocalDateTime nextHour = now.plusHours(1);
// 格式化
String formatted = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(formatted);
}
}Instant
表示时间戳(机器时间)。
java
import java.time.Instant;
import java.time.Duration;
public class InstantDemo {
public static void main(String[] args) {
// 创建
Instant now = Instant.now();
Instant instant = Instant.ofEpochSecond(1000);
Instant parse = Instant.parse("2024-01-01T00:00:00Z");
// 获取时间戳
long epochSecond = now.getEpochSecond();
long epochMilli = now.toEpochMilli();
// 计算
Instant later = now.plusSeconds(60);
Instant earlier = now.minusMillis(1000);
// 时间差
Duration duration = Duration.between(now, later);
System.out.println("秒数: " + duration.getSeconds());
}
}Duration和Period
Duration - 时间间隔
java
import java.time.Duration;
import java.time.LocalTime;
import java.time.LocalDateTime;
public class DurationDemo {
public static void main(String[] args) {
LocalTime start = LocalTime.of(9, 0);
LocalTime end = LocalTime.of(17, 0);
Duration duration = Duration.between(start, end);
System.out.println("小时: " + duration.toHours()); // 8
System.out.println("分钟: " + duration.toMinutes()); // 480
System.out.println("秒: " + duration.getSeconds()); // 28800
// 创建Duration
Duration hours = Duration.ofHours(2);
Duration minutes = Duration.ofMinutes(30);
Duration days = Duration.ofDays(1);
// 计算
Duration added = duration.plusHours(1);
Duration multiplied = duration.multipliedBy(2);
}
}Period - 日期间隔
java
import java.time.Period;
import java.time.LocalDate;
public class PeriodDemo {
public static void main(String[] args) {
LocalDate start = LocalDate.of(2024, 1, 1);
LocalDate end = LocalDate.of(2024, 12, 31);
Period period = Period.between(start, end);
System.out.println("年: " + period.getYears()); // 0
System.out.println("月: " + period.getMonths()); // 11
System.out.println("日: " + period.getDays()); // 30
// 创建Period
Period days = Period.ofDays(10);
Period months = Period.ofMonths(6);
Period years = Period.ofYears(1);
Period custom = Period.of(1, 2, 3); // 1年2月3日
}
}DateTimeFormatter
java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class FormatterDemo {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
// 预定义格式
DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_DATE_TIME;
DateTimeFormatter isoDate = DateTimeFormatter.ISO_DATE;
DateTimeFormatter isoTime = DateTimeFormatter.ISO_TIME;
// 自定义格式
DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
// 格式化
String formatted = now.format(formatter1);
System.out.println(formatted);
// 解析
LocalDateTime parsed = LocalDateTime.parse("2024-01-01 10:30:00", formatter1);
System.out.println(parsed);
// 常用格式
DateTimeFormatter[] formatters = {
DateTimeFormatter.BASIC_ISO_DATE, // 20240101
DateTimeFormatter.ISO_LOCAL_DATE, // 2024-01-01
DateTimeFormatter.ISO_LOCAL_TIME, // 10:30:00
DateTimeFormatter.ISO_LOCAL_DATE_TIME, // 2024-01-01T10:30:00
DateTimeFormatter.ofPattern("yyyy/MM/dd"), // 2024/01/01
};
}
}时区处理
ZonedDateTime
java
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeDemo {
public static void main(String[] args) {
// 创建
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime specific = ZonedDateTime.of(
2024, 1, 1, 10, 30, 0, 0,
ZoneId.of("Asia/Shanghai")
);
// 指定时区
ZonedDateTime tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
ZonedDateTime newYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
// 时区转换
ZonedDateTime converted = now.withZoneSameInstant(ZoneId.of("UTC"));
// 获取时区信息
ZoneId zone = now.getZone();
System.out.println("时区: " + zone);
// 可用时区
ZoneId.getAvailableZoneIds().forEach(System.out::println);
}
}ZoneId
java
import java.time.ZoneId;
public class ZoneIdDemo {
public static void main(String[] args) {
// 系统默认时区
ZoneId defaultZone = ZoneId.systemDefault();
// 指定时区
ZoneId shanghai = ZoneId.of("Asia/Shanghai");
ZoneId utc = ZoneId.of("UTC");
ZoneId offset = ZoneId.of("+08:00");
// 常用时区
String[] commonZones = {
"Asia/Shanghai", // 上海
"Asia/Tokyo", // 东京
"America/New_York", // 纽约
"Europe/London", // 伦敦
"UTC" // 协调世界时
};
}
}旧API转换
java
import java.time.*;
import java.util.Date;
import java.util.Calendar;
public class ConversionDemo {
public static void main(String[] args) {
// Date -> Instant -> LocalDateTime
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// LocalDateTime -> Instant -> Date
LocalDateTime now = LocalDateTime.now();
Instant instant2 = now.atZone(ZoneId.systemDefault()).toInstant();
Date date2 = Date.from(instant2);
// Calendar -> Instant -> ZonedDateTime
Calendar calendar = Calendar.getInstance();
Instant instant3 = calendar.toInstant();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant3, ZoneId.systemDefault());
// 时间戳转换
long timestamp = System.currentTimeMillis();
Instant fromTimestamp = Instant.ofEpochMilli(timestamp);
LocalDateTime fromTimestamp2 = LocalDateTime.ofInstant(fromTimestamp, ZoneId.systemDefault());
}
}实战示例
计算年龄
java
public static int calculateAge(LocalDate birthDate) {
return Period.between(birthDate, LocalDate.now()).getYears();
}判断工作日
java
public static boolean isWorkday(LocalDate date) {
DayOfWeek dayOfWeek = date.getDayOfWeek();
return dayOfWeek != DayOfWeek.SATURDAY && dayOfWeek != DayOfWeek.SUNDAY;
}计算两个日期之间的工作日
java
public static long countWorkdays(LocalDate start, LocalDate end) {
return start.datesUntil(end)
.filter(d -> !d.getDayOfWeek().equals(DayOfWeek.SATURDAY)
&& !d.getDayOfWeek().equals(DayOfWeek.SUNDAY))
.count();
}时间范围判断
java
public static boolean isInTimeRange(LocalTime time, LocalTime start, LocalTime end) {
return !time.isBefore(start) && !time.isAfter(end);
}