Java 8新增了一套全新的时间API,这些API让我们能够更方便地进行日期和时间的处理。在Java 8之前,日期和时间的操作大多是基于java.util.Date和java.util.Calendar类,但这些类存在很多问题,比如线程不安全、可变性等,同时也缺乏一些常见的操作。
优势
Java 8时间操作类的设计理念是围绕着不可变性、线程安全性和清晰易用性来展开的。Java 8时间操作类的主要优势如下:
不可变性:Java 8时间操作类中的所有类都是不可变的,即它们的方法都不会改变原实例的状态,而是返回一个新的实例。这种不可变性使得Java 8时间操作类线程安全,可以在多线程环境下使用。线程安全性:Java 8时间操作类的所有类都是线程安全的,因为它们是不可变的。在多线程环境下,多个线程可以同时读取同一个实例,而不需要担心数据竞争等线程安全问题。清晰易用性:Java 8时间操作类提供了丰富的API,可以完成各种常见的日期和时间操作。它们的方法名和参数都非常易懂,使得编写代码更加简洁易读。
主要类
Java 8时间操作类中主要包括如下几个类:
LocalDate:表示一个日期,例如2020-05-14。它提供了各种方法来操作日期,比如加减天数、月份和年份等。LocalTime:表示一个时间,例如23:59:59.999。它提供了各种方法来操作时间,比如加减小时、分钟和秒等。LocalDateTime:表示一个日期和时间,例如2019-11-03T23:59:59.999。它同时包含了日期和时间的信息,提供了各种方法来操作日期和时间。Instant:表示一个时间戳,即从1970年1月1日开始经过的秒数。它可以用来计算两个时间点之间的时间差,或者将时间戳转换为日期和时间格式。Duration:表示一个时间段,例如2小时30分钟。它提供了各种方法来操作时间段,比如加减时间、获取时间段的总秒数等。Period:表示一个日期段,例如3年2个月1天。它提供了各种方法来操作日期段,比如加减日期、获取日期段的总天数等。
使用示例
LocalDate
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
| public class LocalDateDemo { public static void main(String[] args) { LocalDate today = LocalDate.now(); System.out.println("当前日期是: " + today);
LocalDate date1 = LocalDate.of(2019, 10, 1); System.out.println("指定日期是: " + date1);
int year = today.getYear(); int month = today.getMonthValue(); int day = today.getDayOfMonth(); System.out.printf("今天是%d年%d月%d日%n", year, month, day);
LocalDate tomorrow = today.plusDays(1); LocalDate yesterday = today.minusDays(1); System.out.println("明天是:" + tomorrow); System.out.println("昨天是:" + yesterday);
boolean isLeapYear = today.isLeapYear(); System.out.println("今年是否是闰年:" + isLeapYear); } }
|
LocalTime
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
| public class LocalTimeDemo { public static void main(String[] args) { LocalTime now = LocalTime.now(); System.out.println("现在是: " + now);
LocalTime time1 = LocalTime.of(8, 30); System.out.println("指定时间是: " + time1);
int hour = now.getHour(); int minute = now.getMinute(); int second = now.getSecond(); int nano = now.getNano(); System.out.printf("现在是%d时%d分%d秒%d纳秒%n", hour, minute, second, nano);
LocalTime newTime1 = now.plusHours(2); LocalTime newTime2 = now.minusMinutes(30); System.out.println("两个小时后的时间是:" + newTime1); System.out.println("30分钟前的时间是:" + newTime2);
LocalTime time2 = LocalTime.parse("20:15:30"); System.out.println("解析后的时间是:" + time2); } }
|
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
| public class LocalDateTimeDemo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); System.out.println("现在是: " + now);
LocalDateTime dateTime1 = LocalDateTime.of(2020, 10, 1, 8, 30); System.out.println("指定日期时间是: " + dateTime1);
int year = now.getYear(); int month = now.getMonthValue(); int day = now.getDayOfMonth(); int hour = now.getHour(); int minute = now.getMinute(); int second = now.getSecond(); System.out.printf("现在是%d年%d月%d日%d时%d分%d秒%n", year, month, day, hour, minute, second);
LocalDateTime newDateTime1 = now.plusDays(1).minusHours(2); System.out.println("1天后减2小时的日期时间是:" + newDateTime1);
LocalDateTime dateTime2 = LocalDateTime.parse("2020-05-10T20:15:30"); System.out.println("解析后的日期时间是:" + dateTime2); } }
|
Instant
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
| public class InstantDemo { public static void main(String[] args) { Instant now = Instant.now(); System.out.println("当前时间戳是:" + now);
long epochSecond = now.getEpochSecond(); int nano = now.getNano(); System.out.printf("时间戳的值为%d秒%d纳秒%n", epochSecond, nano);
Instant instant1 = Instant.ofEpochSecond(1601510400); System.out.println("指定时间戳是:" + instant1);
Instant instant2 = Instant.ofEpochSecond(1651456800); long seconds = Duration.between(instant1, instant2).getSeconds(); System.out.printf("两个时间戳之间相差%d秒%n", seconds); / 创建一个 Instant 对象 Instant instant = Instant.now();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); System.out.println("LocalDateTime: " + localDateTime);
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault()); System.out.println("ZonedDateTime: " + zonedDateTime);
LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate(); System.out.println("LocalDate: " + localDate);
LocalTime localTime = instant.atZone(ZoneId.systemDefault()).toLocalTime(); System.out.println("LocalTime: " + localTime); } }
|
Period
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class PeriodDemo { public static void main(String[] args) { Period period1 = Period.of(3, 2, 1); System.out.println("指定日期段是:" + period1);
int year = period1.getYears(); int month = period1.getMonths(); int day = period1.getDays(); System.out.printf("指定日期段为%d年%d个月%d天%n", year, month, day);
LocalDate date1 = LocalDate.of(2021, 10, 1); LocalDate date2 = LocalDate.of(2022, 8, 25); Period period2 = Period.between(date1, date2); System.out.println("两个日期之间的日期段是:" + period2);
int days = period2.getDays() + period2.getMonths() * 30 + period2.getYears() * 365; System.out.printf("两个日期之间相差%d天%n", days); } }
|
Duration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class DurationDemo { public static void main(String[] args) { LocalDateTime dateTime1 = LocalDateTime.of(2019, 10, 1, 8, 30); LocalDateTime dateTime2 = LocalDateTime.of(2020, 8, 25, 14, 0); Duration duration1 = Duration.between(dateTime1, dateTime2); System.out.println("两个日期时间之间的时间段是:" + duration1);
long hours = duration1.toHours(); long minutes = duration1.toMinutes() % 60; long seconds = duration1.getSeconds() % 60; long millis = duration1.toMillis() % 1000; System.out.printf("两个日期时间之间相差%d小时%d分钟%d秒%d毫秒%n", hours, minutes, seconds, millis);
Duration duration2 = Duration.ofDays(3).plusHours(5).plusMinutes(20).plusSeconds(10); System.out.println("指定时间段是:" + duration2); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class DateTimeFormatterDemo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formattedDateTime1 = now.format(formatter1); System.out.println("格式化后的日期时间是:" + formattedDateTime1);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); LocalDateTime dateTime2 = LocalDateTime.parse("20200828092915", formatter2); System.out.println("解析后的日期时间是:" + dateTime2); } }
|
总结
Java 8时间操作类的设计理念是围绕着不可变性、线程安全性和清晰易用性来展开的。它们提供了丰富的API,可以完成各种常见的日期和时间操作,并且具有很好的性能和稳定性。使用Java 8时间操作类可以让我们更加便捷地进行日期和时间的处理,避免了之前旧版API中存在的一些问题。