当前位置: 首页 > news >正文

Java 时间日期类笔记

1. 核心时间日期API发展历程

1.1 各版本主要API

  • Java 8之前: DateCalendarSimpleDateFormat
  • Java 8+: java.time包 (JSR-310)
  • 推荐: 新项目统一使用java.time

2. Java 8+ 时间日期API (java.time)

2.1 核心类概览

类名 描述 示例
LocalDate 日期 (年月日) 2023-10-25
LocalTime 时间 (时分秒纳秒) 14:30:15.123
LocalDateTime 日期时间 2023-10-25T14:30:15
ZonedDateTime 带时区的日期时间 2023-10-25T14:30:15+08:00[Asia/Shanghai]
Instant 时间戳 (Unix时间) 1698215415
Duration 时间间隔 (秒、纳秒) PT1H30M
Period 日期间隔 (年、月、日) P1Y2M3D

2.2 基础使用示例

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;public class DateTimeExamples {public static void main(String[] args) {// 1. 获取当前时间LocalDate currentDate = LocalDate.now();LocalTime currentTime = LocalTime.now();LocalDateTime currentDateTime = LocalDateTime.now();System.out.println("当前日期: " + currentDate);System.out.println("当前时间: " + currentTime);System.out.println("当前日期时间: " + currentDateTime);// 2. 创建特定时间LocalDate specificDate = LocalDate.of(2023, 10, 25);LocalTime specificTime = LocalTime.of(14, 30, 15);LocalDateTime specificDateTime = LocalDateTime.of(2023, 10, 25, 14, 30, 15);// 3. 日期计算LocalDate tomorrow = currentDate.plusDays(1);LocalDate lastWeek = currentDate.minusWeeks(1);LocalDate nextMonth = currentDate.plusMonths(1);// 4. 日期比较boolean isAfter = specificDate.isAfter(currentDate);boolean isBefore = specificDate.isBefore(currentDate);boolean isEqual = specificDate.isEqual(currentDate);// 5. 获取日期组成部分int year = currentDate.getYear();Month month = currentDate.getMonth();int dayOfMonth = currentDate.getDayOfMonth();DayOfWeek dayOfWeek = currentDate.getDayOfWeek();}
}

2.3 时区处理

public class TimeZoneExamples {public static void main(String[] args) {// 1. 时区日期时间ZonedDateTime beijingTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));System.out.println("北京时间: " + beijingTime);System.out.println("纽约时间: " + newYorkTime);// 2. 时区转换ZonedDateTime convertedTime = beijingTime.withZoneSameInstant(ZoneId.of("UTC"));System.out.println("UTC时间: " + convertedTime);// 3. 获取所有可用时区// ZoneId.getAvailableZoneIds().forEach(System.out::println);// 4. Instant (时间戳)Instant instant = Instant.now();System.out.println("当前时间戳: " + instant.toEpochMilli());// 从时间戳创建Instant fromTimestamp = Instant.ofEpochMilli(1698215415000L);}
}

2.4 时间间隔计算

public class DurationPeriodExamples {public static void main(String[] args) {// 1. Duration - 时间间隔 (精确到纳秒)LocalTime startTime = LocalTime.of(9, 0, 0);LocalTime endTime = LocalTime.of(17, 30, 0);Duration duration = Duration.between(startTime, endTime);System.out.println("工作时间: " + duration.toHours() + "小时");System.out.println("总分钟数: " + duration.toMinutes());// 2. Period - 日期间隔 (年、月、日)LocalDate birthDate = LocalDate.of(1990, 5, 15);LocalDate currentDate = LocalDate.now();Period age = Period.between(birthDate, currentDate);System.out.println("年龄: " + age.getYears() + "年" + age.getMonths() + "月" + age.getDays() + "天");// 3. 使用ChronoUnit计算差值long daysBetween = ChronoUnit.DAYS.between(birthDate, currentDate);long monthsBetween = ChronoUnit.MONTHS.between(birthDate, currentDate);System.out.println("总天数: " + daysBetween);System.out.println("总月数: " + monthsBetween);}
}

2.5 格式化与解析

public class FormattingExamples {public static void main(String[] args) {// 1. 预定义格式器LocalDateTime now = LocalDateTime.now();String isoFormat = now.format(DateTimeFormatter.ISO_DATE_TIME);String basicFormat = now.format(DateTimeFormatter.BASIC_ISO_DATE);System.out.println("ISO格式: " + isoFormat);System.out.println("基本ISO格式: " + basicFormat);// 2. 自定义格式DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String customFormat = now.format(customFormatter);System.out.println("自定义格式: " + customFormat);// 3. 解析字符串为日期String dateString = "2023-10-25 14:30:15";LocalDateTime parsedDateTime = LocalDateTime.parse(dateString, customFormatter);System.out.println("解析结果: " + parsedDateTime);// 4. 本地化格式DateTimeFormatter germanFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.GERMAN);String germanFormat = now.format(germanFormatter);System.out.println("德语格式: " + germanFormat);}
}

3. 传统日期API (Java 8之前)

3.1 Date 和 Calendar

import java.util.*;
import java.text.SimpleDateFormat;public class LegacyDateTime {public static void main(String[] args) throws Exception {// 1. Date 类Date now = new Date();System.out.println("当前时间: " + now);// 2. Calendar 类Calendar calendar = Calendar.getInstance();calendar.set(2023, Calendar.OCTOBER, 25, 14, 30, 15);Date specificDate = calendar.getTime();// 日历计算calendar.add(Calendar.DAY_OF_MONTH, 7); // 加7天calendar.add(Calendar.MONTH, -1); // 减1个月// 3. SimpleDateFormatSimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String formatted = sdf.format(now);System.out.println("格式化: " + formatted);// 解析Date parsedDate = sdf.parse("2023-10-25 14:30:15");// 注意: SimpleDateFormat 非线程安全!}
}

3.2 线程安全问题

// 错误的用法 - 多线程环境下会有问题
public class UnsafeDateFormat {private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 多线程调用时会抛出异常或返回错误结果
}// 正确的用法 - 使用ThreadLocal
public class SafeDateFormat {private static final ThreadLocal<SimpleDateFormat> threadLocal =ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));public static String format(Date date) {return threadLocal.get().format(date);}
}

4. 新旧API转换

4.1 互相转换方法

public class ConversionExamples {public static void main(String[] args) {// 1. Date -> Instant -> LocalDateTimeDate oldDate = new Date();Instant instant = oldDate.toInstant();LocalDateTime newDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());// 2. LocalDateTime -> Instant -> DateLocalDateTime localDateTime = LocalDateTime.now();Instant instant2 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();Date newDate = Date.from(instant2);// 3. Calendar -> ZonedDateTimeCalendar calendar = Calendar.getInstance();ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());// 4. 时间戳转换long timestamp = System.currentTimeMillis();Instant instantFromTimestamp = Instant.ofEpochMilli(timestamp);LocalDateTime dateTimeFromTimestamp = LocalDateTime.ofInstant(instantFromTimestamp, ZoneId.systemDefault());}
}

5. 最佳实践和注意事项

5.1 推荐做法

public class BestPractices {// 1. 使用不可变对象public void processOrder(LocalDateTime orderTime) {LocalDateTime processedTime = orderTime.plusMinutes(30); // 返回新对象// orderTime 保持不变}// 2. 使用常量格式器private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");// 3. 明确处理时区public ZonedDateTime convertToTimezone(LocalDateTime localDateTime, String zoneId) {return localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of(zoneId));}// 4. 使用合适的类public void demonstrateAppropriateUse() {// 只需要日期LocalDate birthday = LocalDate.of(1990, 5, 15);// 只需要时间LocalTime meetingTime = LocalTime.of(14, 30);// 需要日期时间但不需要时区LocalDateTime createdTime = LocalDateTime.now();// 需要时区信息ZonedDateTime publishTime = ZonedDateTime.now(ZoneId.of("UTC"));// 时间戳存储Instant timestamp = Instant.now();}
}

5.2 常见陷阱

public class CommonPitfalls {public static void main(String[] args) {// 1. 不要使用已废弃的构造方法// Date date = new Date(123, 9, 25); // 已废弃!// 2. Calendar 的月份从0开始Calendar cal = Calendar.getInstance();cal.set(2023, 9, 25); // 10月 (0=1月, 9=10月)// 3. 时区处理要一致LocalDateTime local = LocalDateTime.now();// 错误的时区假设// ZonedDateTime zoned = local.atZone(ZoneId.of("UTC")); // 正确的做法ZonedDateTime zoned = local.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"));// 4. 格式化解析要匹配String input = "2023/10/25";// DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 错误!DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd"); // 正确}
}

总结

  1. 新项目优先使用 java.time
  2. 根据需求选择合适的类: LocalDateLocalTimeLocalDateTimeZonedDateTime
  3. 时区处理要明确, 避免隐式时区转换
  4. 格式化器尽量重用, 避免重复创建
  5. 注意线程安全问题, 特别是传统API
  6. 利用不可变特性, 避免意外的状态修改

这套新的日期时间API设计更加合理,解决了传统API的很多问题,是Java日期时间处理的现代解决方案。

http://www.gsyq.cn/news/38522.html

相关文章:

  • Day11伪类选择器
  • 检测php get变量是否存在以及是否有值
  • JAVA中三个类的对比:String、StringBuffer和StringBuilder
  • 2025年11月工装装修公司专业排行:深度评测与使用指南
  • 欢迎报名!Kusica 基于K8s的多方安全协同框架11月亮相杭州KCD
  • 2025年11月工装装修公司推荐榜单:权威评测与选择指南
  • 2025 年 11 月沈阳办公家具厂家推荐排行榜,办公桌,办公椅,文件柜,会议桌,办公沙发公司推荐
  • 2025 年 11 月沈阳办公家具厂家推荐排行榜,办公桌,办公椅,文件柜,会议桌,办公沙发公司推荐,品质与设计双重保障!
  • 单机模式下nacos的安装与使用
  • Pymarchenko程序
  • 软件需求分析课堂加分 - 2305
  • 2025年11月黄褐斑改善产品对比榜:五款高回购单品全维度评价
  • #20232329易杨文轩 2025-2026-1 《网络与系统攻防技术》 实验四实验报告
  • 前端chatbox
  • 2025年11月合肥建筑律师推荐榜:全过程覆盖能力对比评价
  • 2025 年塑料挤出设备厂家最新推荐榜单:深度甄选聚焦技术实力、客户认可及设备性能全方位测评塑料板材挤出设备/塑料挤出设备生产线/塑料管材挤出设备生产线公司推荐
  • AtCoder Beginner Contest 430 ABCDEF 题目解析
  • 2025年广东空运到印度专线机构权威推荐榜单:广东到印度的海运平台/广东空运到印度物流平台/广东到印度专线双清包税服务源头机构精选
  • 2025 年最新推荐锰钢编织筛网厂家排行榜,涵盖耐磨矿用等多类型产品,精选五大靠谱品牌助力企业采购滚筒/平筛/黑钢锰钢编织筛网公司推荐
  • 用四端法测量Fe-Cr-Al丝的电阻率
  • 2025 年国际高中学校最新推荐榜,聚焦办学资质与升学成果深度解析及教学质量与综合实力全面评估松江区 / 青浦区 / 奉贤区 / 崇明区国际高中推荐
  • 2025年汽车超薄低音源头厂家权威推荐榜单:汽车音响超薄低音/汽车超薄低音炮/汽车音响超薄低音炮源头厂家精选
  • 2025年保洁服务公司新排行榜推荐,海獭顾家无忧保洁服务详细介绍
  • 2025 年阳台光伏厂家推荐:昱电宝依托昱能科技技术积淀,打造场景化光伏解决方案与服务体系
  • 【2025-11-01】连岳摘抄
  • 2025年度锂电池回收再利用机器制造厂排名:口碑好的锂电池回收设备厂家推荐
  • 2025年五大游乐设备优质厂家推荐,景区游乐设备厂实力全解析
  • 2025年郑州口碑不错的大巴车租赁专业公司推荐,知名的大巴车租赁企业实力全解析
  • vscode配置MCP
  • 2025年11月数控加工中心制造厂家榜单:诚信企业参数对比与专业评测