这周在阅读《阿里巴巴Java开发手册》时,在并发处理一节的日期处理中,其强调SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果
定义为 static,必须加锁,或者使用 DateUtils 工具类。并且建议如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter
代替 SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。但是,这些JDK1.8新的特性以前都没有用过,因此,学习了下。
一、介绍
Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的。
因此,Java 8引入了一套全新的时间日期API。关于这个新的时间日期库的最大的优点就在于它定义清楚了时间日期相关的一些概念,比方说,瞬时时间(Instant),
持续时间(duration),日期(date),时间(time),时区(time-zone)以及时间段(Period)。同时它也借鉴了Joda库的一些优点,比如将人和机器对时间日期的
理解区分开的。Java 8仍然延用了ISO的日历体系,并且与它的前辈们不同,java.time包中的类是不可变且线程安全的。
二、重要的类介绍
新的时间及日期API位于java.time包中,下面是里面的一些关键的类:
(1)Instant:它代表的是时间戳
(2)LocalDate:不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。
(3)LocalTime:它代表的是不含日期的时间
(4)LocalDateTime:它包含了日期及时间,不过还是没有偏移信息或者说时区。
(5)ZonedDateTime:这是一个包含时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的。
(6)Period:包含的是两个日期之间的天、月、年数差值
(7)Duration:包含是两个日期时间间隔的秒以及纳秒数
下面分别对每个类给出一些小例子,进行介绍。
三、例子
(1)Instant类
/*
Instant学习
*/
Instant now = Instant.now();
System.out.println(now.toString());
//毫秒
System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
// 微秒
System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
// 纳秒
System.out.println(now.get(ChronoField.NANO_OF_SECOND));
// 毫秒转Instant
LocalDateTime localDateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
// 2018-01-14T11:03:35.002
System.out.println(localDateTime);
(2)LocalDate类
/*
LocalDate学习
*/
LocalDate now = LocalDate.now();
System.out.println(now.toString()); //日期加上1天
LocalDate plusDay = now.plusDays(1);
System.out.println(plusDay.toString()); //日期加上一周
LocalDate plusWeek = now.plusWeeks(1);
System.out.println(plusWeek.toString()); //计算当年前的第52天是几月几号
System.out.println("今年的第52天是:" + now.withDayOfYear(52)); //字符串转日期
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
TemporalAccessor dateTempora = dateTimeFormatter.parse("2018-01-14");
LocalDate date = LocalDate.from(dateTempora);
System.out.println(date); //格式化日期
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyyMMdd");
String dateStr = dateTimeFormatter1.format(now);
System.out.println(dateStr);
(3)LocalTime类
/*
LocalTime学习
*/
LocalTime now = LocalTime.now();
System.out.println(now.toString()); //时间加上12个小时
System.out.println("plus 12 hours: " + now.plusHours(12));
(4)LocalDateTime类
/*
LocalDateTime学习
*/
// 获得当前日期时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 字符串转日期时间。
DateTimeFormatter strToDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
TemporalAccessor dateTemporal = strToDateFormatter.parse("2017-01-01 12:12:13");
LocalDate date = LocalDate.from(dateTemporal);
System.out.println(date); // 格式化日期时间
DateTimeFormatter dateToStrFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
String dateStr = dateToStrFormatter.format(now);
System.out.println(dateStr);
(5)Period类
/*
Period学习
*/
LocalDate startDate = LocalDate.now();
LocalDate endDate = startDate.plusDays(1); Period period = Period.between(startDate, endDate);
System.out.println("间隔的天数" + period.getDays());
System.out.println("间隔的月数:" + period.getMonths());
System.out.println("间隔的年数:" + period.getYears()); // 直接使用日期类中的方法计算日期间隔
long days = startDate.until(endDate, ChronoUnit.DAYS);
System.out.println("间隔的天数:" + days);
long weeks = startDate.until(endDate, ChronoUnit.WEEKS);
System.out.println("间隔的周数:" + weeks);
(6)Duration类
/*
Duration学习
*/
LocalDateTime start = LocalDateTime.now();
LocalDateTime end = start.plusDays(1);
Duration duration = Duration.between(start, end);
System.out.println("间隔的秒数:" + duration.get(ChronoUnit.SECONDS));
System.out.println("间隔的纳秒数:" + duration.get(ChronoUnit.NANOS));