Java 时间日期类笔记

news/2025/11/3 13:01:18/文章来源:https://www.cnblogs.com/roadtojava/p/19186760

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.mzph.cn/news/954462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day11伪类选择器

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">…

写在十年之后

在博客园上断断续续写了有十年了,打算停更了;后续文章会写到公众号上,有需要的可以关注下,谢谢! #MySignature { background-color: #f8f8ee; border: solid 1px #e8e7d0; padding: 10px; margin-bottom: 10px; c…

检测php get变量是否存在以及是否有值

检测php get变量是否存在以及是否有值// 检测GET变量是否存在 if (isset($_GET[writer])) {// 变量存在$writer = $_GET[writer]; } else {// 变量不存在$writer = ; }// 检测GET变量是否存在且有值(不是空字符串、0、…

Python 文件操作

1. 创建文件 # open("文件名",读取模式,编码) , 需要手动关闭文件 fp = open("文件名",mode="a+",encoding="utf-8") # with open("文件名",读取模式,编码) , 自…

tp8-商城项目 命令合集

# 1. 解除框架版本锁定 composer remove topthink/framework --no-update # 2. 重装指定版本框架composer require topthink/framework:8.0.4 --no-plugins # 3. 安装微信支付SDKcomposer require wechatpay/wechatpay…

谭剑波day10

一 名从在翻译中的应用The notion that people have failed to detect the massive change is important.这是同位语从句翻译成也就是,同位语是可以调换顺序的,其他名从大都顺着翻译宾语从句:在介词,动词,及物动词…

2025年11月工装设计公司推荐排行:全国服务网络与项目经验深度解析

在选择工装设计公司时,企业决策者往往面临着诸多考量。无论是新办公空间的规划,还是商业场所的升级改造,都需要专业的设计团队提供全方位的解决方案。当前工装设计行业呈现出专业化、标准化的发展趋势,随着企业对工…

2025年11月上海遗产继承律师评测榜:基于真实数据的深度剖析

在当今社会,随着财富积累和家庭结构的多元化,遗产继承问题日益凸显其复杂性和重要性。上海作为中国的经济中心,涉及跨境资产、家族企业传承等高端继承案件频发,对律师的专业素养提出了更高要求。许多用户可能正面临…

JAVA中三个类的对比:String、StringBuffer和StringBuilder

在Java中,String、StringBuffer和StringBuilder都是用于处理字符串的类,但它们有不同的特性和适用场景。以下是它们的详细对比: 1. String 类 特性:不可变性:String对象一旦创建就不能被修改,底层使用char、底层…

2025年11月工装装修公司专业排行:深度评测与使用指南

随着企业规模的扩大和商业空间的升级需求,工装装修市场在2025年呈现出稳步增长的趋势。根据中国建筑装饰协会发布的数据,2024年工装市场规模已达到2.1万亿元,预计2025年将保持8%左右的年增长率。在这样的市场背景下…

Lora Image Cropper

Lora Image CropperLora Image Cropper is a simple Qt desktop application for cropping images. It allows you to load an image, crop it to a specific size, and save the cropped image to a file. 把from Py…

欢迎报名!Kusica 基于K8s的多方安全协同框架11月亮相杭州KCD

当三秋桂子遇见分布式计算,当十里荷花碰撞微服务架构,这座被马可波罗誉为"世界最美丽华贵之天城"的数字经济之城,即将迎来一场重量级技术盛宴。本次活动,隐语社区作为可信数据流通领域的先锋力量,将亮相…

2025年11月工装装修公司推荐榜单:权威评测与选择指南

在当今商业环境快速发展的背景下,工装装修已成为企业提升形象、优化功能空间的重要环节。无论是新办公场所的设立,还是现有商业空间的升级改造,选择一家可靠的工装装修公司至关重要。企业决策者、物业管理者或项目负…

2025 年 11 月沈阳办公家具厂家推荐排行榜,办公桌,办公椅,文件柜,会议桌,办公沙发公司推荐

2025年11月沈阳办公家具厂家推荐排行榜:专业采购指南行业背景与发展趋势随着现代办公理念的不断升级,办公家具行业正经历着深刻的变革。2025年的办公家具市场呈现出智能化、人性化、环保化三大发展趋势。智能办公家具…

2025 年 11 月沈阳办公家具厂家推荐排行榜,办公桌,办公椅,文件柜,会议桌,办公沙发公司推荐,品质与设计双重保障!

2025年11月沈阳办公家具厂家推荐排行榜:品质与设计双重保障在现代化办公环境建设中,办公家具作为企业形象与工作效率的重要载体,其选择标准已从单一的功能性需求,逐步发展为集人体工学、空间美学、环保标准与使用体…

软件技术工程第二次作业

龚可为 2023329301124 链接 https://gitee.com/gongkewei/homework

git 命令别名设置

目录背景和价值参考资料 背景和价值 git config --global alias.br branch 参考资料

单机模式下nacos的安装与使用

一、nacos 的安装(安装包方式) ① 下载安装包 https://nacos.io/download/nacos-server/ 并进行解压缩 unzip nacos-server-$version.zip # 或者 tar -xvf nacos-server-$version.tar.gz cd nacos/bin② 修改配置文件…

ch2题解

ch2题解 A-数列有序 考察数组遍历和插入。 题意: 给你一个升序的长度为 \(n\) 的 \(a\) 数组,然后给你一个 \(x\),把 \(x\) 插入到数组 \(a\) 中使它依然有序。 输出插入后的数组。 解题思路: 因为 \(a\) 数组是有…