一、简介
在Java8之前,日期时间API一直被开发者诟病,包括:java.util.Date是可变类型,SimpleDateFormat非线程安全等问题。故此,Java8引入了一套全新的日期时间处理API,新的API基于ISO标准日历系统。
Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:
1、非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
2、设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
3、时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:
Local(本地) − 简化了日期时间的处理,没有时区的问题。
Zoned(时区) − 通过制定的时区处理日期时间。
新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。
本地化日期时间 API
LocalDate/LocalTime 和 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
39
40
41
42
|
import java.time.LocalDate; import java.time.LocalTime; import java.time.LocalDateTime; import java.time.Month; public class Java8Tester { public static void main(String args[]){ Java8Tester java8tester = new Java8Tester(); java8tester.testLocalDateTime(); } public void testLocalDateTime(){ // 获取当前的日期时间 LocalDateTime currentTime = LocalDateTime.now(); System.out.println( "当前时间: " + currentTime); LocalDate date1 = currentTime.toLocalDate(); System.out.println( "date1: " + date1); Month month = currentTime.getMonth(); int day = currentTime.getDayOfMonth(); int seconds = currentTime.getSecond(); System.out.println( "月: " + month + ", 日: " + day + ", 秒: " + seconds); LocalDateTime date2 = currentTime.withDayOfMonth( 10 ).withYear( 2012 ); System.out.println( "date2: " + date2); // 12 december 2014 LocalDate date3 = LocalDate.of( 2014 , Month.DECEMBER, 12 ); System.out.println( "date3: " + date3); // 22 小时 15 分钟 LocalTime date4 = LocalTime.of( 22 , 15 ); System.out.println( "date4: " + date4); // 解析字符串 LocalTime date5 = LocalTime.parse( "20:15:30" ); System.out.println( "date5: " + date5); } } |
执行以上脚本,输出结果为:
$ javac Java8Tester.java
$ java Java8Tester
当前时间: 2016-04-15T16:55:48.668
date1: 2016-04-15
月: APRIL, 日: 15, 秒: 48
date2: 2012-04-10T16:55:48.668
date3: 2014-12-12
date4: 22:15
date5: 20:15:30
使用时区的日期时间API
如果我们需要考虑到时区,就可以使用时区的日期时间API:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import java.time.ZonedDateTime; import java.time.ZoneId; public class Java8Tester { public static void main(String args[]){ Java8Tester java8tester = new Java8Tester(); java8tester.testZonedDateTime(); } public void testZonedDateTime(){ // 获取当前时间日期 ZonedDateTime date1 = ZonedDateTime.parse( "2015-12-03T10:15:30+05:30[Asia/Shanghai]" ); System.out.println( "date1: " + date1); ZoneId id = ZoneId.of( "Europe/Paris" ); System.out.println( "ZoneId: " + id); ZoneId currentZone = ZoneId.systemDefault(); System.out.println( "当期时区: " + currentZone); } } |
执行以上脚本,输出结果为:
$ javac Java8Tester.java
$ java Java8Tester
date1: 2015-12-03T10:15:30+08:00[Asia/Shanghai]
ZoneId: Europe/Paris
当期时区: Asia/Shanghai
二、日期初识
示例1: 获取当天日期
Java 8中的 LocalDate 用于表示当天日期。和java.util.Date不同,它只有日期,不包含时间。
1
2
3
4
|
public static void main(String[] args) { LocalDate date = LocalDate.now(); System.out.println( "当前日期=" + date); } |
示例2: 构造指定日期
调用工厂方法LocalDate.of()创建任意日期, 该方法需要传入年、月、日做参数,返回对应的LocalDate实例。这个方法的好处是没再犯老API的设计错误,比如年度起始于1900,月份是从0开始等等
1
2
3
4
|
public static void main(String[] args) { LocalDate date = LocalDate.of( 2000 , 1 , 1 ); System.out.println( "千禧年=" + date); } |
示例3: 获取年月日信息
1
2
3
4
|
public static void main(String[] args) { LocalDate date = LocalDate.now(); System.out.printf( "年=%d, 月=%d, 日=%d" , date.getYear(), date.getMonthValue(), date.getDayOfMonth()); } |
示例4: 比较两个日期是否相等
1
2
3
4
5
|
public static void main(String[] args) { LocalDate now = LocalDate.now(); LocalDate date = LocalDate.of( 2018 , 9 , 24 ); System.out.println( "日期是否相等=" + now.equals(date)); } |
三、时间初识
示例: 获取当前时间
Java 8中的 LocalTime 用于表示当天时间。和java.util.Date不同,它只有时间,不包含日期。
1
2
3
4
|
public static void main(String[] args) { LocalTime time = LocalTime.now(); System.out.println( "当前时间=" + time); } |
四、比较与计算
示例1: 日期时间计算
Java8提供了新的plusXxx()方法用于计算日期时间增量值,替代了原来的add()方法。新的API将返回一个全新的日期时间示例,需要使用新的对象进行接收。
1
2
3
4
5
6
7
8
9
10
11
|
public static void main(String[] args) { // 时间增量 LocalTime time = LocalTime.now(); LocalTime newTime = time.plusHours( 2 ); System.out.println( "newTime=" + newTime); // 日期增量 LocalDate date = LocalDate.now(); LocalDate newDate = date.plus( 1 , ChronoUnit.WEEKS); System.out.println( "newDate=" + newDate); } |
示例2: 日期时间比较
Java8提供了isAfter()、isBefore()用于判断当前日期时间和指定日期时间的比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static void main(String[] args) { LocalDate now = LocalDate.now(); LocalDate date1 = LocalDate.of( 2000 , 1 , 1 ); if (now.isAfter(date1)) { System.out.println( "千禧年已经过去了" ); } LocalDate date2 = LocalDate.of( 2020 , 1 , 1 ); if (now.isBefore(date2)) { System.out.println( "2020年还未到来" ); } } |
五、时区
示例: 创建带有时区的日期时间
Java 8不仅分离了日期和时间,也把时区分离出来了。现在有一系列单独的类如ZoneId来处理特定时区,ZoneDateTime类来表示某时区下的时间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static void main(String[] args) { // 上海时间 ZoneId shanghaiZoneId = ZoneId.of( "Asia/Shanghai" ); ZonedDateTime shanghaiZonedDateTime = ZonedDateTime.now(shanghaiZoneId); // 东京时间 ZoneId tokyoZoneId = ZoneId.of( "Asia/Tokyo" ); ZonedDateTime tokyoZonedDateTime = ZonedDateTime.now(tokyoZoneId); DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); System.out.println( "上海时间: " + shanghaiZonedDateTime.format(formatter)); System.out.println( "东京时间: " + tokyoZonedDateTime.format(formatter)); } |
六、格式化
示例1: 使用预定义格式解析与格式化日期
1
2
3
4
5
6
7
8
9
10
11
12
|
public static void main(String[] args) { // 解析日期 String dateText = "20180924" ; LocalDate date = LocalDate.parse(dateText, DateTimeFormatter.BASIC_ISO_DATE); System.out.println( "格式化之后的日期=" + date); // 格式化日期 dateText = date.format(DateTimeFormatter.ISO_DATE); System.out.println( "dateText=" + dateText); } |
示例2: 日期和字符串的相互转换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public static void main(String[] args) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); // 日期时间转字符串 LocalDateTime now = LocalDateTime.now(); String nowText = now.format(formatter); System.out.println( "nowText=" + nowText); // 字符串转日期时间 String datetimeText = "1999-12-31 23:59:59" ; LocalDateTime datetime = LocalDateTime.parse(datetimeText, formatter); System.out.println(datetime); } |
七、相关类说明
Instant 时间戳
Duration 持续时间、时间差
LocalDate 只包含日期,比如:2018-09-24
LocalTime 只包含时间,比如:10:32:10
LocalDateTime 包含日期和时间,比如:2018-09-24 10:32:10
Peroid 时间段
ZoneOffset 时区偏移量,比如:+8:00
ZonedDateTime 带时区的日期时间
Clock 时钟,可用于获取当前时间戳
java.time.format.DateTimeFormatter 时间格式化类
java8时间使用小结
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
//LocalDate代表一个IOS格式(yyyy-MM-dd)的日期 获取当前的日期: LocalDate localDate = LocalDate.now(); //LocalDate: 表示没有时区的日期, LocalDate是不可变并且线程安全的 System.out.println( "localDate: " + localDate); //localDate: 2017-08-24 //LocalDate可以指定特定的日期,调用of或parse方法返回该实例: System.out.println(LocalDate.of( 2017 , 07 , 20 )); //2017-07-20 System.out.println(LocalDate.parse( "2017-07-20" )); //2017-07-20 //为今天添加一天,也就是获取明天 System.out.println(LocalDate.now().plusDays( 1 )); //2017-08-25 //为今天添加7天,也就是获取一个礼拜之后的今天 System.out.println(LocalDate.now().plusWeeks( 1 )); //2017-08-31 //为今天添加一个月,也就是获取一个月后的今天 System.out.println(LocalDate.now().plusMonths( 1 )); //2017-09-24 //为今天添加一年,也就是获取一年后的今天 System.out.println(LocalDate.now().plusYears( 1 )); //2018-08-24 //从今天减去一个月 (跟加同理 可获取减去1天、 1个礼拜、 1年之后的时间) System.out.println(LocalDate.now().minus( 1 , ChronoUnit.MONTHS)); //2017-07-24 System.out.println(LocalDate.now().minusMonths( 1 )); //2017-07-24 //解析日期 2017-07-20,获取每周中的星期和每月中的日 等 System.out.println( "周四: " +LocalDate.parse( "2017-07-20" ).getDayOfWeek()); //THURSDAY System.out.println( "日: " +LocalDate.parse( "2017-07-20" ).getDayOfMonth()); //20 System.out.println( "月: " +LocalDate.parse( "2017-07-20" ).getMonthValue()); //7 System.out.println( "年: " +LocalDate.parse( "2017-07-20" ).getYear()); //2017 System.out.println( "月: " +LocalDate.parse( "2017-07-20" ).getMonth()); //JULY //今年是不是闰年(闰年判断) System.out.println(LocalDate.now().isLeapYear()); //false //判断是否在日期之前或之后: System.out.println(LocalDate.parse( "2017-07-20" ).isAfter(LocalDate.parse( "2017-07-21" ))); //false System.out.println(LocalDate.parse( "2017-07-20" ).isBefore(LocalDate.parse( "2017-07-21" ))); //true System.out.println(LocalDate.parse( "2217-07-20" ).isBefore(LocalDate.parse( "2017-07-21" ))); //false //获取这个月的第一天: System.out.println(LocalDate.parse( "2017-07-20" ).with(TemporalAdjusters.firstDayOfMonth())); //2017-07-01 //获取下个月的第一天,等等。。 System.out.println(LocalDate.parse( "2017-07-20" ).with(TemporalAdjusters.firstDayOfNextMonth())); //2017-08-01 System.out.println(LocalDate.parse( "2017-07-20" ).with(TemporalAdjusters.lastDayOfMonth())); //2017-07-31 System.out.println(LocalDate.parse( "2017-07-20" ).with(TemporalAdjusters.firstDayOfNextYear())); //2018-01-01 System.out.println(LocalDate.parse( "2017-07-20" ).with(TemporalAdjusters.firstDayOfYear())); //2017-01-01 //判断今天是否是我的生日,例如我的生日是 2006-07-20 LocalDate birthday = LocalDate.of( 2006 , 07 , 20 ); MonthDay birthdayMd = MonthDay.of(birthday.getMonth(),birthday.getDayOfMonth()); MonthDay today=MonthDay.from(LocalDate.now()); System.out.println( "今天是否是我的生日: " + today.equals(birthdayMd)); //false System.out.println( "=======LocalTime表示一个时间,而不是日期===========" ); //获取现在的时间 09:52:19.446 System.out.println( "现在的时间: " +LocalTime.now()); //将一个字符串时间解析为LocalTime System.out.println( LocalTime.parse( "15:02" )); //15:02 //使用静态方法of创建一个时间 System.out.println(LocalTime.of( 16 , 02 )); //16:02 //使用解析字符串的方式并添加一小时,输出16:02 System.out.println(LocalTime.parse( "15:02" ).plus( 1 , ChronoUnit.HOURS)); //16:02 System.out.println(LocalTime.parse( "15:02" ).plus( 10 , ChronoUnit.MINUTES)); //15:12 //获取时间的小时、分钟 System.out.println(LocalTime.parse( "15:02" ).getHour()); //15 System.out.println(LocalTime.parse( "15:02" ).getMinute()); //2 //检查一个时间是否在另一个时间之前、之后 System.out.println(LocalTime.parse( "15:02" ).isAfter(LocalTime.parse( "14:02" ))); //true System.out.println(LocalTime.parse( "15:02" ).isBefore(LocalTime.parse( "14:02" ))); //false //每天的开始与结束时间 System.out.println(LocalTime.MAX); //23:59:59.999999999 System.out.println(LocalTime.MIN); //00:00 System.out.println( "=======LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一===========" ); System.out.println( "现在: " +LocalDateTime.now()); //2017-08-24T10:31:03.600 //LocalDateTime也提供了相关API来对日期和时间进行增减操作 System.out.println( "明天的现在: " +LocalDateTime.now().plusDays( 1 )); //2017-08-25T10:33:05.363 //获取当前月份等等 System.out.println(LocalDateTime.now().getMonthValue()); //8 System.out.println(LocalDateTime.now().getMonth()); //AUGUST System.out.println(LocalDateTime.now().getYear()); //2017 //日期格式化 System.out.println( "======日期格式化=======" ); LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ); System.out.println( "默认格式化: " + now); System.out.println( "自定义格式化: " + now.format(dateTimeFormatter)); LocalDateTime localDateTime = LocalDateTime.parse( "2017-07-20 15:27:44" , dateTimeFormatter); System.out.println( "字符串转LocalDateTime: " + localDateTime.format(dateTimeFormatter)); DateTimeFormatter dateTimeFormatter_s = DateTimeFormatter.ofPattern( "yyyy-MM-dd" ); String dateString = dateTimeFormatter_s.format(LocalDate.now()); System.out.println( "日期转字符串: " + dateString); //日期和周期 Period类用于修改给定日期或获得的两个日期之间的区别。 LocalDate initialDate = LocalDate.parse( "2017-07-20" ); LocalDate finalDate = initialDate.plus(Period.ofDays( 5 )); //给初始化的日期添加5天 System.out.println( "初始化日期: " + initialDate); //2017-07-20 System.out.println( "加日期之后: " + finalDate); //2017-07-25 //周期(Period)API中提供给我们可以比较两个日期的差别,像下面这样获取差距天数:(同理可以获取两个时间相差的小时、周、月、年) long between = ChronoUnit.DAYS.between(initialDate, finalDate); System.out.println( "差距天数: " + between); //5 //如何将Date类转换为Java8中的时间类 //Date和Instant互相转换 Date date = Date.from(Instant.now()); Instant instant = date.toInstant(); //Date转换为LocalDateTime<br><br>ZoneId zoneId = ZoneId.systemDefault(); |
LocalDateTime localDateTime = new Date().toInstant().atZone(zoneId).toLocalDateTime();
System.out.println("LocalDateTime = " + localDateTime);
//LocalDateTime转Date Date date_s = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); System.out.println(date_s); //LocalDate转Date Date date_t = Date.from(LocalDate.now().atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); System.out.println(date_t);
到此这篇关于Java8 日期、时间操作代码的文章就介绍到这了,更多相关Java8 日期、时间内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://www.cnblogs.com/ark-blog/p/9694950.html