在开发中经常需要处理日期和时间,Java提供了一套专门用于处理日期时间的API,在日期时间类中了包含LocalDate类、LocalTime类、Instant类、Duration类以及Period类等,这些类都包含在java.time包中。
类的名称
功能描述
Instant
表示时刻,代表的是时间戳
LocalDate
不包含具体时间的日期
LocalTime
不包含日期的时间
LocalDateTime
包含了日期和时间
Duration
基于时间的值测量时间量
Period
计算日期时间差异,只能精确到年月日
Clock
时钟系统,用于查找当前时刻
Instant(时间戳)类 Instant 类代表的是某个时间。其内部是由两个Long字段组成,
第一部分是保存自标准Java计算时代(即1970年1月1日开始)至当前时间的秒数,即时间戳(Timestamp)。该时间戳表示从参考时间点开始经过的秒数。
第二部分是保存纳秒数。纳秒是时间的更精细单位,表示每秒钟的十亿分之一。
常用方法:
now():使用系统时钟获取当前瞬时。
now(Clock clock):使用指定时钟获取当前瞬时。
ofEpochSecond(long epochSecond):使用自标准Java计算时代开始的秒数获得一个Instant实例。
ofEpochMilli(long epochMilli):使用自标准Java计算时代开始的毫秒数获得一个Instant实例。
getEpochSecond():获取时间戳的秒数部分。
getNano():获取时间戳的纳秒数部分。
parse(CharSequence text):将表示时间的字符串转换为对应的Instant对象。
from(TemporalAccessor tenporal):从时间对象获取一个Instant的实例。
plusSeconds(long seconds) 和 plusMillis(long millis):在时间戳的基础上增加指定的秒数或毫秒数。
minusSeconds() 和 minusMillis():在时间戳的基础上减去指定的秒数或毫秒数。
isBefore() 和 isAfter() 方法:比较两个时间戳的先后顺序。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import java.time.Clock;import java.time.Instant;public class InstantExample { public static void main (String[] args) { Instant now = Instant.now(); System.out.println("当前时间:" + now); Clock clock = Clock.systemUTC(); Instant nowWithClock = Instant.now(clock); System.out.println("当前时间(使用指定时钟):" + nowWithClock); Instant epochSecondInstant = Instant.ofEpochSecond(1234567890 ); System.out.println("自1970年1月1日起的秒数对应的时间:" + epochSecondInstant); Instant epochMilliInstant = Instant.ofEpochMilli(1627368000000L ); System.out.println("自1970年1月1日起的毫秒数对应的时间:" + epochMilliInstant); long seconds = now.getEpochSecond(); System.out.println("时间戳的秒数部分:" + seconds); int nanos = now.getNano(); System.out.println("时间戳的纳秒数部分:" + nanos); String timeString = "2023-08-14T10:30:00Z" ; Instant parsedInstant = Instant.parse(timeString); System.out.println("解析后的时间:" + parsedInstant); Instant plusSecondsInstant = now.plusSeconds(3600 ); Instant plusMillisInstant = now.plusMillis(1000 ); System.out.println("增加1小时后的时间:" + plusSecondsInstant); System.out.println("增加1秒后的时间:" + plusMillisInstant); Instant minusSecondsInstant = now.minusSeconds(1800 ); Instant minusMillisInstant = now.minusMillis(500 ); System.out.println("减去30分钟后的时间:" + minusSecondsInstant); System.out.println("减去0.5秒后的时间:" + minusMillisInstant); Instant earlierInstant = Instant.parse("2023-08-14T09:00:00Z" ); Instant laterInstant = Instant.parse("2023-08-14T11:00:00Z" ); boolean isBefore = earlierInstant.isBefore(laterInstant); boolean isAfter = earlierInstant.isAfter(laterInstant); System.out.println("earlierInstant是否在laterInstant之前:" + isBefore); System.out.println("earlierInstant是否在laterInstant之后:" + isAfter); } }
运行结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 当前时间:2023 -10 -25T05:09:44. 739476300Z 当前时间(使用指定时钟):2023 -10 -25T05:09:44. 743463Z 自1970 年1 月1 日起的秒数对应的时间:2009 -02 -13T23:31 :30Z 自1970 年1 月1 日起的毫秒数对应的时间:2021 -07 -27T06:40 :00Z 时间戳的秒数部分:1698210584 时间戳的纳秒数部分:739476300 解析后的时间:2023 -08-14T10:30 :00Z 增加1 小时后的时间:2023 -10 -25T06:09:44. 739476300Z 增加1 秒后的时间:2023 -10 -25T05:09:45. 739476300Z 减去30 分钟后的时间:2023 -10 -25T04:39 :44. 739476300Z 减去0.5 秒后的时间:2023 -10 -25T05:09:44. 239476300Z earlierInstant是否在laterInstant之前:true earlierInstant是否在laterInstant之后:false
LocalData(日期 )类 LocalData类是Java 8引入的日期类,用于表示日期(年、月、日)信息。该类具有以下方法:
常用方法:
now():这是一个静态方法,返回表示当前日期的LocalDate对象。例如,LocalDate.now()将返回表示今天日期的对象。
of(int year, int month, int dayOfMonth):这是另一个静态方法,通过指定年、月、日创建LocalDate对象。参数year表示年份,month表示月份(1到12之间),dayOfMonth表示月份中的某一天。
format(DateTimeFormatter formatter):该方法可将LocalDate对象按照指定的格式转换为字符串表示。需要传入一个DateTimeFormatter对象,可以使用预定义的格式或自定义格式。例如,date.format(DateTimeFormatter.ofPattern(“yyyy-MM-dd”))将返回带有“年-月-日”格式的日期字符串。
plusYears(long years) / minusYears(long years):这些方法用于在现有的LocalDate对象上增加或减少指定的年数。参数years表示要增加或减少的年数。
plusMonths(long months) / minusMonths(long months):与上述方法类似,这些方法用于在现有的LocalDate对象上增加或减少指定的月数。
plusDays(long days) / minusDays(long days):这些方法用于在现有的LocalDate对象上增加或减少指定的天数。
isBefore(LocalDate other) / isAfter(LocalDate other):这两个方法用于比较两个LocalDate对象的先后顺序。isBefore()方法返回一个布尔值,表示该日期是否在参数日期之前;isAfter()方法返回一个布尔值,表示该日期是否在参数日期之后。
getYear() / getMonthValue() / getDayOfMonth():这些方法用于获取LocalDate对象的年、月、日信息。
isLeapYear():用于判断指定年份是否为闰年。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import java.time.LocalDate;import java.time.format.DateTimeFormatter;public class Test { public static void main (String[] args) { LocalDate currentDate = LocalDate.now(); System.out.println("当前日期:" + currentDate); LocalDate customDate = LocalDate.of(2023 , 8 , 14 ); System.out.println("自定义日期:" + customDate); String formattedDate = customDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd" )); System.out.println("格式化后的日期:" + formattedDate); LocalDate futureDate = customDate.plusYears(2 ); System.out.println("增加两年后的日期:" + futureDate); boolean isBefore = customDate.isBefore(currentDate); boolean isAfter = customDate.isAfter(currentDate); System.out.println("自定义日期是否在当前日期之前:" + isBefore); System.out.println("自定义日期是否在当前日期之后:" + isAfter); int year = customDate.getYear(); int month = customDate.getMonthValue(); int dayOfMonth = customDate.getDayOfMonth(); System.out.println("年:" + year); System.out.println("月:" + month); System.out.println("日:" + dayOfMonth); boolean isLeapYear = customDate.isLeapYear(); System.out.println("自定义日期所在年份是否为闰年:" + isLeapYear); } }
运行结果: 1 2 3 4 5 6 7 8 9 10 当前日期:2023 -10 -25 自定义日期:2023 -08-14 格式化后的日期:2023 -08-14 增加两年后的日期:2025 -08-14 自定义日期是否在当前日期之前:true 自定义日期是否在当前日期之后:false 年:2023 月:8 日:14 自定义日期所在年份是否为闰年:false
LocalTime(时间)类 LocalTime类用来表示时间,通常表示的是小时分钟秒。与LocalData类一样,该类不能代表时间线上的即时信息,只是时间的描述。在LocalTime类中提供了获取时间对象的方法,与LocalData用法类似。
同时LocalTime类也提供了与日期类相对应的时间格式化、增减时分秒等常用方法,这些方法与LocalData(日期)类相对应,这里我们不再详细列举。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import java.time.LocalTime;import java.time.format.DateTimeFormatter;public class Test { public static void main (String[] args) { LocalTime currentTime = LocalTime.now(); System.out.println("当前时间:" + currentTime); LocalTime customTime = LocalTime.of(12 , 30 , 45 ); System.out.println("自定义时间:" + customTime); String formattedTime = customTime.format(DateTimeFormatter.ofPattern("HH:mm:ss" )); System.out.println("格式化后的时间:" + formattedTime); LocalTime futureTime = customTime.plusHours(2 ); System.out.println("增加两小时后的时间:" + futureTime); boolean isBefore = customTime.isBefore(currentTime); boolean isAfter = customTime.isAfter(currentTime); System.out.println("自定义时间是否在当前时间之前:" + isBefore); System.out.println("自定义时间是否在当前时间之后:" + isAfter); int hour = customTime.getHour(); int minute = customTime.getMinute(); int second = customTime.getSecond(); System.out.println("小时:" + hour); System.out.println("分钟:" + minute); System.out.println("秒:" + second); } }
运行结果: 1 2 3 4 5 6 7 8 9 当前时间:13 :13 :29.649140600 自定义时间:12 :30 :45 格式化后的时间:12 :30 :45 增加两小时后的时间:14 :30 :45 自定义时间是否在当前时间之前:true 自定义时间是否在当前时间之后:false 小时:12 分钟:30 秒:45
LocalDataTime(日期时间)类 LocalDataTime类是日期(LocalDate)类与时间(LocalTime)类的综合,它即包含日期也包含时间,通过查看API可以知道,LocalDataTime类中的方法包含了LocalData类与LocalTime类的方法。
需要注意的是,LocalDateTime默认的格式是 2020-02-29T21:23:26.774,这可能与我们经常使用的格式不太符合,所以它经常和DateTimeFormatter一起使用指定格式,除了LocalData与LocalTime类中的方法,额外提供了转换的方法。
常用方法: 以下是一些LocalDateTime类常用的方法:
now():静态方法,返回当前日期和时间的LocalDateTime对象。
of(int year, int month, int dayOfMonth, int hour, int minute) / of(int year, int month, int dayOfMonth, int hour, int minute, int second):静态方法,通过指定年、月、日、小时、分钟以及秒数(可选)创建LocalDateTime对象。
parse(CharSequence text):静态方法,将字符串解析为LocalDateTime对象。
format(DateTimeFormatter formatter):将LocalDateTime对象按照指定格式转换为字符串表示。
toLocalDate():获取LocalDateTime对象的日期部分,返回LocalDate对象。
toLocalTime():获取LocalDateTime对象的时间部分,返回LocalTime对象。
plusYears(long years) / minusYears(long years):在现有的LocalDateTime对象上增加或减少指定年数。
plusMonths(long months) / minusMonths(long months):在现有的LocalDateTime对象上增加或减少指定月数。
plusDays(long days) / minusDays(long days):在现有的LocalDateTime对象上增加或减少指定天数。
plusHours(long hours) / minusHours(long hours):在现有的LocalDateTime对象上增加或减少指定小时数。
plusMinutes(long minutes) / minusMinutes(long minutes):在现有的LocalDateTime对象上增加或减少指定分钟数。
plusSeconds(long seconds) / minusSeconds(long seconds):在现有的LocalDateTime对象上增加或减少指定秒数。
getYear() / getMonthValue() / getDayOfMonth():获取LocalDateTime对象的年、月、日信息。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import java.time.LocalDate;import java.time.LocalDateTime;import java.time.LocalTime;import java.time.format.DateTimeFormatter;public class Test { public static void main (String[] args) { LocalDateTime currentDateTime = LocalDateTime.now(); System.out.println("当前日期和时间:" + currentDateTime); LocalDateTime customDateTime = LocalDateTime.of(2023 , 10 , 24 , 12 , 30 ); System.out.println("自定义日期和时间:" + customDateTime); String formattedDateTime = customDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" )); System.out.println("格式化后的日期和时间:" + formattedDateTime); LocalDateTime futureDateTime = customDateTime.plusYears(1 ).minusMonths(2 ).plusDays(15 ).minusHours(3 ).plusMinutes(10 ).plusSeconds(30 ); System.out.println("操作后的日期和时间:" + futureDateTime); LocalDate datePart = customDateTime.toLocalDate(); LocalTime timePart = customDateTime.toLocalTime(); System.out.println("日期部分:" + datePart); System.out.println("时间部分:" + timePart); int year = customDateTime.getYear(); int month = customDateTime.getMonthValue(); int dayOfMonth = customDateTime.getDayOfMonth(); System.out.println("年:" + year); System.out.println("月:" + month); System.out.println("日:" + dayOfMonth); } }
运行结果: 1 2 3 4 5 6 7 8 9 当前日期和时间:2023 -10 -25T13:19 :39.667325400 自定义日期和时间:2023 -10 -24T12:30 格式化后的日期和时间:2023 -10 -24 12 :30 :00 操作后的日期和时间:2024 -09-08T09:40 :30 日期部分:2023 -10 -24 时间部分:12 :30 年:2023 月:10 日:24
Duration(时间间隔)类 Duration类是Java 8引入的一个用于表示时间间隔的类。它可用于计算两个时间点之间的差异,以及在不同单位(如秒、分钟、小时等)之间进行转换。
常用方法: 以下是一些Duration类常用的方法:
ofDays(long days) / ofHours(long hours) / ofMinutes(long minutes):静态方法,创建一个持续时间,表示指定的天数、小时数或分钟数。
ofSeconds(long seconds) / ofMillis(long milliseconds) / ofNanos(long nanos):静态方法,创建一个持续时间,表示指定的秒数、毫秒数或纳秒数。
between(Temporal startInclusive, Temporal endExclusive):静态方法,创建一个持续时间,表示从起始时间到结束时间之间的差异。
plus(Duration duration) / minus(Duration duration):在现有的Duration对象上增加或减少另一个Duration对象的持续时间。
toDays() / toHours() / toMinutes():将持续时间转换为对应的天数、小时数或分钟数。
toSeconds() / toMillis() / toNanos():将持续时间转换为对应的秒数、毫秒数或纳秒数。
getSeconds() / getNano():获取持续时间中的秒数和纳秒数。
isNegative() / isZero():判断持续时间是否为负值或零值。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import java.time.Duration;public class Test { public static void main (String[] args) { Duration duration1 = Duration.ofHours(5 ).plusMinutes(30 ).plusSeconds(15 ); System.out.println("Duration 1: " + duration1); Duration duration2 = Duration.ofMinutes(1 ); System.out.println("Duration 2: " + duration2); Duration difference = duration1.minus(duration2); System.out.println("Difference: " + difference); long hours = difference.toHours(); long minutes = difference.toMinutesPart(); long seconds = difference.toSecondsPart(); System.out.println("Hours: " + hours); System.out.println("Minutes: " + minutes); System.out.println("Seconds: " + seconds); boolean isNegative = difference.isNegative(); boolean isZero = difference.isZero(); System.out.println("是负的? " + isNegative); System.out.println("是零吗? " + isZero); } }
运行结果: 1 2 3 4 5 6 7 8 Duration 1 : PT5H30M15S Duration 2 : PT1M Difference: PT5H29M15S Hours: 5 Minutes: 29 Seconds: 15 是负的? false 是零吗? false
Period(日期间隔)类 Period主要用于计算两个日期的间隔,与Duration相同,也是通过between计算日期间隔,并提供了获取年月日的三个常用方法,分别是 getYears()、getMonths()和getDays()。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import java.time.LocalDate;import java.time.Period;public class Test { public static void main (String[] args) { LocalDate startDate = LocalDate.of(2023 , 1 , 1 ); LocalDate endDate = LocalDate.of(2023 , 4 , 30 ); Period period = Period.between(startDate, endDate); System.out.println("日期间隔: " + period); int years = period.getYears(); int months = period.getMonths(); int days = period.getDays(); System.out.println("年: " + years); System.out.println("月: " + months); System.out.println("日: " + days); LocalDate newDate = startDate.plus(period); System.out.println("新日期: " + newDate); boolean isNegative = period.isNegative(); boolean isZero = period.isZero(); System.out.println("是否为负值? " + isNegative); System.out.println("是否为零值? " + isZero); } }
运行结果: 1 2 3 4 5 6 7 日期间隔: P3M29D 年: 0 月: 3 日: 29 新日期: 2023 -04 -30 是否为负值? false 是否为零值? false
Clock(获取时区)类 Clock类是Java中用于获取当前时间、日期和时区信息的抽象类。它提供了一种通用的方式来访问系统时钟,并以不同的时区获取当前时间。
常用方法:
systemDefaultZone():静态方法,返回使用系统默认时区的系统时钟。
systemUTC():静态方法,返回使用协调世界时(UTC)的系统时钟。
tick(Clock fixedClock, Duration tickDuration):静态方法,返回一个包装了指定时钟的”滴答”时钟,每次前进指定的时长。
fixed(Instant fixedInstant, ZoneId zone):静态方法,返回一个固定的时钟,始终返回指定的瞬间和时区。
offset(Clock baseClock, Duration offsetDuration):静态方法,返回一个相对于基准时钟偏移指定持续时间的时钟。
millis():实例方法,返回从1970年1月1日午夜开始的毫秒数。
instant():实例方法,返回当前时钟的当前瞬间。
getZone():实例方法,返回时钟的时区信息。
示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 import java.time.Clock;import java.time.Duration;import java.time.Instant;import java.time.ZoneId;public class Test { public static void main (String[] args) { Clock systemDefaultClock = Clock.systemDefaultZone(); System.out.println("系统默认时钟:" + systemDefaultClock); Clock systemUTCClock = Clock.systemUTC(); System.out.println("系统UTC时钟:" + systemUTCClock); Clock tickClock = Clock.tick(systemDefaultClock, Duration.ofSeconds(1 )); System.out.println("滴答时钟:" + tickClock); Instant fixedInstant = Instant.parse("2022-01-01T00:00:00Z" ); ZoneId fixedZone = ZoneId.of("Asia/Shanghai" ); Clock fixedClock = Clock.fixed(fixedInstant, fixedZone); System.out.println("固定时钟:" + fixedClock); Clock baseClock = Clock.systemDefaultZone(); Duration offsetDuration = Duration.ofSeconds(10 ); Clock offsetClock = Clock.offset(baseClock, offsetDuration); System.out.println("偏移时钟:" + offsetClock); long millis = systemDefaultClock.millis(); System.out.println("毫秒数:" + millis); Instant instant = systemDefaultClock.instant(); System.out.println("当前瞬间:" + instant); ZoneId zone = systemDefaultClock.getZone(); System.out.println("时区:" + zone); } }
运行结果: 1 2 3 4 5 6 7 8 系统默认时钟:SystemClock[Asia/Shanghai] 系统UTC时钟:SystemClock[Z] 滴答时钟:TickClock[SystemClock[Asia/Shanghai],PT1S] 固定时钟:FixedClock[2022 -01 -01T00:00 :00Z,Asia/Shanghai] 偏移时钟:OffsetClock[SystemClock[Asia/Shanghai],PT10S] 毫秒数:1698211710976 当前瞬间:2023 -10 -25T05:28 :30. 976562Z 时区:Asia/Shanghai