在 java 中,处理日期和时间的类随着版本的发展有不同的体系。早期版本主要使用 java.util.date
、java.util.calendar
等类,java 8 及以后引入了新的日期和时间 api(jsr 310),包含在 java.time
包中。
甲骨文官方文档
overview (java se 21 & jdk 21)
jdk中文文档。https://java.cunzaima.cn/jdk21/doc-zh/api/index.html
旧的日期时间api
1. java.util.date
- 概述:
date
类表示特定的瞬间,精确到毫秒。不过它的很多方法在 java 1.1 之后已经被弃用,因为其设计存在一些问题,比如线程不安全、缺乏时区支持等。 - 常用方法
date()
:创建一个表示当前时间的date
对象。date(long date)
:根据给定的毫秒数创建date
对象,该毫秒数是从 1970 年 1 月 1 日 00:00:00 gmt 开始计算的。gettime()
:返回自 1970 年 1 月 1 日 00:00:00 gmt 以来此date
对象表示的毫秒数。equals(object obj)
:比较两个date
对象是否相等。
import java.util.date; public class dateexample { public static void main(string[] args) { // 创建表示当前时间的 date 对象 date currentdate = new date(); system.out.println("当前时间: " + currentdate); // 根据毫秒数创建 date 对象 long milliseconds = 1609459200000l; date specificdate = new date(milliseconds); system.out.println("指定时间: " + specificdate); // 获取毫秒数 long timeinmillis = currentdate.gettime(); system.out.println("当前时间的毫秒数: " + timeinmillis); // 比较两个 date 对象 boolean isequal = currentdate.equals(specificdate); system.out.println("两个日期是否相等: " + isequal); } }
2. java.util.calendar
- 概述:
calendar
是一个抽象类,用于在 java 中进行日期和时间的计算。它提供了一些方法来获取和设置年、月、日、时、分、秒等信息,并且支持时区和本地化。 - 常用方法
calendar.getinstance()
:获取一个calendar
实例,该实例使用默认时区和语言环境。get(int field)
:获取指定字段的值,例如calendar.year
、calendar.month
等。set(int field, int value)
:设置指定字段的值。add(int field, int amount)
:对指定字段进行加减操作。
import java.util.calendar; public class calendarexample { public static void main(string[] args) { // 获取 calendar 实例 calendar calendar = calendar.getinstance(); // 获取年、月、日 int year = calendar.get(calendar.year); int month = calendar.get(calendar.month) + 1; // 月份从 0 开始,所以要加 1 int day = calendar.get(calendar.day_of_month); system.out.println("当前日期: " + year + "-" + month + "-" + day); // 设置日期 calendar.set(calendar.year, 2025); calendar.set(calendar.month, calendar.june); calendar.set(calendar.day_of_month, 15); system.out.println("设置后的日期: " + calendar.gettime()); // 日期加减操作 calendar.add(calendar.day_of_month, 5); system.out.println("加 5 天后的日期: " + calendar.gettime() +"\t" + calendar.gettime().gettime()+"\t"+ calendar.gettimeinmillis() +"\t" + calendar.gettimezone().getoffset(calendar.gettimeinmillis())); // 设置时区 timezone timezone = timezone.gettimezone("america/new_york"); calendar.settimezone(timezone); system.out.println("美国纽约的日期: " + calendar.gettime() +"\t" + calendar.gettime().gettime() +"\t"+ calendar.gettimeinmillis() +"\t" + calendar.gettimezone().getoffset(calendar.gettimeinmillis())); } }
simpledateformat
:用于将date
对象格式化为指定的字符串格式,或者将字符串解析为date
对象。它通过模式字符串来定义日期和时间的格式,常用的模式字符有:
y
:年,如yyyy
表示四位年份,yy
表示两位年份。m
:月,mm
表示两位数字的月份,mmm
表示月份的缩写(如 jan、feb 等),mmmm
表示月份的全称。d
:日,dd
表示两位数字的日。h
:小时(24 小时制),hh
表示两位数字的小时。h
:小时(12 小时制)。m
:分钟,mm
表示两位数字的分钟。s
:秒,ss
表示两位数字的秒。s
:毫秒。z
:时区,如cst
。
例如,simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss");
可以将date
对象格式化为2024-05-08 14:34:56
这样的字符串。
java.util.calendar
:calendar
类主要用于对日期和时间进行操作和计算,它本身没有直接的日期格式表示。但可以通过simpledateformat
将calendar
对象转换为指定格式的字符串,例如:
calendar calendar = calendar.getinstance(); simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); string datestr = sdf.format(calendar.gettime()); string datestring = "2024-10-01 14:30:00"; try { date date = sdf.parse(datestring); system.out.println("解析后的日期: " + date); } catch (parseexception e) { system.out.println("解析日期时出错: " + e.getmessage()); }
新的日期时间 api(java 8+)
1. java.time.localdate
- 概述:
localdate
表示一个不可变的日期对象,只包含日期信息(年、月、日),不包含时间和时区信息。 - 常用方法
localdate.now()
:获取当前日期。localdate.of(int year, int month, int dayofmonth)
:根据指定的年、月、日创建localdate
对象。getyear()
、getmonth()
、getdayofmonth()
:获取年、月、日信息。plusdays(long daystoadd)
、minusdays(long daystosubtract)
:进行日期的加减操作。
import java.time.localdate; public class localdateexample { public static void main(string[] args) { // 获取当前日期 localdate currentdate = localdate.now(); system.out.println("当前日期: " + currentdate); // 根据指定的年、月、日创建 localdate 对象 localdate specificdate = localdate.of(2025, 6, 15); system.out.println("指定日期: " + specificdate); // 获取日期信息 int year = specificdate.getyear(); int month = specificdate.getmonthvalue(); int day = specificdate.getdayofmonth(); system.out.println("指定日期的年: " + year + ", 月: " + month + ", 日: " + day); // 日期加减操作 localdate newdate = specificdate.plusdays(5); system.out.println("加 5 天后的日期: " + newdate); } }
2. java.time.localtime
- 概述:
localtime
表示一个不可变的时间对象,只包含时间信息(时、分、秒、纳秒),不包含日期和时区信息。 - 常用方法
localtime.now()
:获取当前时间。localtime.of(int hour, int minute)
:根据指定的时、分创建localtime
对象。gethour()
、getminute()
、getsecond()
:获取时、分、秒信息。plushours(long hourstoadd)
、minusminutes(long minutestosubtract)
:进行时间的加减操作。
import java.time.localtime; public class localtimeexample { public static void main(string[] args) { // 获取当前时间 localtime currenttime = localtime.now(); system.out.println("当前时间: " + currenttime); // 根据指定的时、分创建 localtime 对象 localtime specifictime = localtime.of(14, 30); system.out.println("指定时间: " + specifictime); // 获取时间信息 int hour = specifictime.gethour(); int minute = specifictime.getminute(); system.out.println("指定时间的时: " + hour + ", 分: " + minute); // 时间加减操作 localtime newtime = specifictime.plushours(2); system.out.println("加 2 小时后的时间: " + newtime); } }
3. java.time.localdatetime
- 概述:
localdatetime
表示一个不可变的日期和时间对象,包含日期和时间信息(年、月、日、时、分、秒、纳秒),不包含时区信息。 - 常用方法:结合了
localdate
和localtime
的方法,可进行日期和时间的操作。
import java.time.localdatetime; public class localdatetimeexample { public static void main(string[] args) { // 获取当前日期和时间 localdatetime currentdatetime = localdatetime.now(); system.out.println("当前日期和时间: " + currentdatetime); // 根据指定的日期和时间创建 localdatetime 对象 localdatetime specificdatetime = localdatetime.of(2025, 6, 15, 14, 30); system.out.println("指定日期和时间: " + specificdatetime); // 日期和时间加减操作 localdatetime newdatetime = specificdatetime.plusdays(2).plushours(3); system.out.println("加 2 天 3 小时后的日期和时间: " + newdatetime); } }
4. java.time.zoneddatetime
- 概述:
zoneddatetime
表示一个带时区的日期和时间对象,包含日期、时间和时区信息。 - 常用方法
zoneddatetime.now()
:获取当前带时区的日期和时间。zoneddatetime.of(localdatetime localdatetime, zoneid zone)
:根据localdatetime
和zoneid
创建zoneddatetime
对象。getzone()
:获取时区信息。
import java.time.localdatetime; import java.time.zoneid; import java.time.zoneddatetime; public class zoneddatetimeexample { public static void main(string[] args) { // 获取当前带时区的日期和时间 zoneddatetime currentzoneddatetime = zoneddatetime.now(); system.out.println("当前带时区的日期和时间: " + currentzoneddatetime); // 根据 localdatetime 和 zoneid 创建 zoneddatetime 对象 localdatetime localdatetime = localdatetime.of(2025, 6, 15, 14, 30); zoneid zoneid = zoneid.of("asia/shanghai"); zoneddatetime specificzoneddatetime = zoneddatetime.of(localdatetime, zoneid); system.out.println("指定带时区的日期和时间: " + specificzoneddatetime); // 获取时区信息 zoneid zone = specificzoneddatetime.getzone(); system.out.println("时区: " + zone); } }
instant
对象
now
方法:可以通过instant.now()
获取当前时间的instant
对象。例如,instant instant = instant.now();
,这将返回当前时刻的instant
,精确到纳秒。
获取时间戳
toepochmilli
方法:instant
提供了toepochmilli
方法来获取从 1970 年 1 月 1 日 00:00:00 utc 到该instant
所表示的时间点的毫秒数。例如,long millis = instant.toepochmilli();
,可以将instant
对象转换为时间戳,方便与其他需要时间戳的系统或 api 进行交互。getepochsecond
方法:获取从 1970 年 1 月 1 日 00:00:00 utc 到该instant
所表示的时间点的秒数。例如,long seconds = instant.getepochsecond();
,如果需要以秒为单位获取时间戳,可以使用该方法。
时间计算
instant
可以进行时间的加减运算,通过plus
和minus
方法来实现。例如,要获取当前时间 5 秒后的instant
,可以使用instant futureinstant = instant.now().plusseconds(5);
;要获取 10 分钟前的instant
,可以使用instant pastinstant = instant.now().minusminutes(10);
。
与其他日期时间类型的转换
- 与
localdatetime
转换:可以通过atzone
方法将instant
转换为指定时区的localdatetime
。例如,instant instant = instant.now(); localdatetime ldt = localdatetime.ofinstant(instant, zoneid.systemdefault());
,这将把当前的instant
转换为系统默认时区的localdatetime
。反之,也可以通过toinstant
方法将localdatetime
转换为instant
,例如,localdatetime ldt = localdatetime.now(); instant instant = ldt.toinstant(zoneoffset.utc);
,将当前的localdatetime
转换为 utc 时区的instant
。 - 与
zoneddatetime
转换:instant
可以直接通过atzone
方法转换为zoneddatetime
,例如,instant instant = instant.now(); zoneddatetime zdt = instant.atzone(zoneid.systemdefault());
,将当前的instant
转换为系统默认时区的zoneddatetime
。而zoneddatetime
也可以通过toinstant
方法转换为instant
,例如,zoneddatetime zdt = zoneddatetime.now(); instant instant = zdt.toinstant();
。
datetimeformatter
java.time
包中的格式化类:新日期时间 api 提供了datetimeformatter
类来进行日期和时间的格式化与解析。它的模式定义与simpledateformat
有一些相似之处,但更加灵活和强大。常用的模式字符与simpledateformat
类似,例如yyyy-mm-dd
、hh:mm:ss
等。localdate
、localtime
和localdatetime
:localdate
:表示日期,默认格式为yyyy-mm-dd
,例如2024-05-08
。可以使用datetimeformatter
进行格式化,如
localdate.now().format(datetimeformatter.ofpattern("dd/mm/yyyy")) //会将当前日期格式化为08/05/2024。
localtime
:表示时间,默认格式为hh:mm:ss.sss
,例如14:34:56.123
。同样可以通过datetimeformatter
进行自定义格式化。localdatetime
:表示日期和时间,默认格式为yyyy-mm-dd hh:mm:ss.sss
,例如2024-05-08 14:34:56.123
。也能使用datetimeformatter
按照需求进行格式化。
综合案例:
import java.time.localdatetime; import java.time.format.datetimeformatter; public class datetimeformatterexample { public static void main(string[] args) { // 1. 通过模式字符串创建datetimeformatter datetimeformatter formatter1 = datetimeformatter.ofpattern("yyyy-mm-dd hh:mm:ss"); // 2. 格式化当前日期时间 localdatetime now = localdatetime.now(); string formatteddatetime1 = formatter1.format(now); system.out.println("formatted datetime 1: " + formatteddatetime1); // 3. 使用预定义的格式创建datetimeformatter datetimeformatter formatter2 = datetimeformatter.iso_local_date_time; string formatteddatetime2 = formatter2.format(now); system.out.println("formatted datetime 2: " + formatteddatetime2); // 4. 解析字符串为日期时间对象 string datetimestr = "2024-05-08 12:30:00"; localdatetime parseddatetime = localdatetime.parse(datetimestr, formatter1); system.out.println("parsed datetime: " + parseddatetime); // 5. 基于本地化创建datetimeformatter datetimeformatter formatter3 = datetimeformatter.oflocalizeddatetime(formatstyle.full) .withlocale(locale.china); string formatteddatetime3 = formatter3.format(now); system.out.println("formatted datetime 3: " + formatteddatetime3); } }
duration
duration
类用于以秒和纳秒的方式表示时间间隔,它主要处理基于时间(小时、分钟、秒、纳秒)的时间量,适用于处理诸如程序执行时间、两个时间点之间的时间差等场景。
创建 duration
对象
duration.between(temporal startinclusive, temporal endexclusive)
:根据两个temporal
对象(如localtime
、localdatetime
或instant
)计算它们之间的时间间隔。
import java.time.duration; import java.time.localtime; public class durationexample { public static void main(string[] args) { localtime starttime = localtime.of(9, 0); localtime endtime = localtime.of(12, 30); duration duration = duration.between(starttime, endtime); system.out.println("时间间隔: " + duration); } }
duration.of(long amount, temporalunit unit)
:通过指定数量和时间单位来创建duration
对象。
duration duration = duration.of(2, java.time.temporal.chronounit.hours); system.out.println("自定义时间间隔: " + duration);
获取 duration
中的值
可以使用 getseconds()
方法获取 duration
中的总秒数,使用 tohours()
、tominutes()
等方法将其转换为不同的时间单位
duration duration = duration.of(2, java.time.temporal.chronounit.hours); system.out.println("总秒数: " + duration.getseconds()); system.out.println("总小时数: " + duration.tohours());
对 duration
进行操作
duration duration1 = duration.of(1, java.time.temporal.chronounit.hours); duration duration2 = duration.of(2, java.time.temporal.chronounit.hours); duration sumduration = duration1.plus(duration2); duration diffduration = duration1.minus(duration2); system.out.println("相加后的间隔: " + sumduration); system.out.println("相减后的间隔: " + diffduration);
period
period
类用于以年、月、日的方式表示日期之间的间隔,它主要处理基于日期(年、月、日)的时间量,适用于处理诸如人的年龄、两个事件之间的日期差等场景。
创建 period
对象
period.between(localdate startdate, localdate enddate)
:根据两个 localdate
对象计算它们之间的日期间隔。
import java.time.localdate; import java.time.period; public class periodexample { public static void main(string[] args) { localdate startdate = localdate.of(2020, 1, 1); localdate enddate = localdate.of(2023, 12, 31); period period = period.between(startdate, enddate); system.out.println("日期间隔: " + period); } }
period.of(int years, int months, int days)
:通过指定年、月、日的值来创建 period
对象。
period period = period.of(2, 3, 10); system.out.println("自定义日期间隔: " + period);
获取 period
中的值
可以使用 getyears()
、getmonths()
和 getdays()
方法分别获取 period
中的年、月、日部分
period period = period.of(2, 3, 10); system.out.println("年: " + period.getyears()); system.out.println("月: " + period.getmonths()); system.out.println("日: " + period.getdays());
对 period
进行操作
plus(period other)
:将两个period
对象相加。minus(period other)
:从当前period
中减去另一个period
对象。duration.between(temporal startinclusive, temporal endexclusive)
:根据两个temporal
对象(如localtime
、localdatetime
或instant
)计算它们之间的时间间隔。duration.of(long amount, temporalunit unit)
:通过指定数量和时间单位来创建duration
对象。plus(duration other)
:将两个duration
对象相加。minus(duration other)
:从当前duration
中减去另一个duration
对象。
总结
period
用于处理基于日期的时间间隔,以年、月、日为单位。duration
用于处理基于时间的时间间隔,以秒和纳秒为单位。
新旧日期时间 api 对比
- 线程安全性:旧的
date
和calendar
类不是线程安全的,而新的日期时间 api 中的类都是不可变的,是线程安全的。 - 易用性:新的日期时间 api 提供了更丰富的方法和更清晰的设计,使用起来更加方便。
- 功能完整性:新的 api 对时区、日期计算等功能的支持更加完善。
到此这篇关于java日期类的文章就介绍到这了,更多相关java日期类内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论