JDK8版本时间和日期API简介

在Java8之前的版本中,Java处理日期、日历和时间的方式一直为社区所诟病,将Java.util.Date设定为可变类型,以及SimpleDateFormat的非线程安全使其应用非常受限。所以Java8引入了全新的处理时间日期的API。全新API的好处之一是明确了日期时间概念,例如:瞬时(Instant)、长短(duration)、日期、时间、时区和周期。不同于老版本,新API基于ISO标准日历系统,java.time包下所有类都是不可变类型而线程安全。下面是新版本中的一些关键类:

Instant-代表时间戳。
LocalDate-不带时间的日期,只有年月日。
LocalTime-不带日期的时间,只有时分秒。
LocalDateTime-包含了日期和时间(不含时区信息)。
ZonedDateTime-包含时区的完整的日期时间,偏移量以UTC/格林威治时间为基准的。
MonthDay-只有月日的日期,如04-19。

常用方法

//获取当前日期。
LocalDate today = LocalDate.now();
System.out.println(today); 

//获取当前时间
LocalTime localTime = LocalTime.now();
System.out.println(localTime);

//获取年月日
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();

//获取指定日期
LocalDate dateOfBirth = LocalDate.of(2018,04,19); 
System.out.println(dateOfBirth); 

//判断两个日期是否相同
today.equals(dateOfBirth);
  
//判断是否是特定日期(如生日)
MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(today);
currentMonthDay.equals(birthDay);

//在当前时间的基础上往前和往后若干小时
localTime.plusHours(2); //该方法返回一个新的实例引用,因为LocalTime是不可变的。

//在当前日期的基础上往后推一周
today.plus(1, ChronoUnit.WEEKS);

//往前推一年
today.minus(1, ChronoUnit.YEARS);

//当前毫秒数与时区
Clock clock = Clock.systemUTC();
System.out.println(clock.millis()); //
System.out.println(Clock.systemDefaultZone());

//判断日期的前后顺序
LocalDate tommorow = today.plus(1, ChronoUnit.DAYS);
System.out.println(tommorow.isAfter(today));
System.out.println(tommorow.isBefore(today));
System.out.println(tommorow.isEqual(today));

//处理不同时区(输出:2018-04-28T13:25:30.129+09:30[Australia/Darwin])
LocalDateTime localDateTime = LocalDateTime.now();
ZoneId zone = ZoneId.of(ZoneId.SHORT_IDS.get("ACT"));
ZonedDateTime zonedDateTimeInNewYork = ZonedDateTime.of(localDateTime, zone);
System.out.println(zonedDateTimeInNewYork);

//月份的天数
YearMonth currentYeanMonth = YearMonth.now();
System.out.println(currentYeanMonth + "有" + currentYeanMonth.lengthOfMonth() + "天");
YearMonth theYearMonth = YearMonth.of(2018, Month.FEBRUARY);
System.out.println("2018年2月份有:" + theYearMonth.lengthOfMonth() + "天");

//闰年检查
System.out.println(today.isLeapYear());

//两个日期的间隔(输出:两个日期之间相差:0月, 相差-14天)
LocalDate date1 = LocalDate.of(2016, Month. APRIL, 14);
LocalDate date2 = LocalDate.of(2018, Month. APRIL, 21);
Period period = Period.between(date1, date2);
System.out.println("两个日期之间相差:" + period.getMonths() + "月, 相差" + period.getDays() + "天");

/**
* 当前时间戳 格式如:2018-04-28T05:27:00.867Z
* Instant与Date类似,实际上也是用来替换Date的,可用
* Date.from(instant)和date.toInstant()方法互相转换
*/
Instant instant = Instant.now();
System.out.println(instant);
Date.from(instant);
new Date().toInstant();

//格式转换
/**
* 日期和字符串的相互转换
*/
String date = "20180427";
System.out.println(LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyyMMdd")));
System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));

注意:要想使用Java8中的类,编译器level必须设置为1.8,如果仍然无法正确编译,可在pom.xml中build-plugins节点下加上(终极解决方法):

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${java_source_version}</source>
                    <target>${java_target_version}</target>
                </configuration>
            </plugin>

虽然使用JDK1.8中的时间和日期类更方便,但实际上目前还是老的日期类使用居多。而老的日期类处理中最频繁的一个问题就是日期格式化为字符串时使用的SimpleDateFormat对象。这个格式化类是线程不安全的(内部使用了Calendar,多线程时不安全,具体的这里就不详细说了),一般的处理方式有两种,一是每次用到就生成一个格式化对象,但这种处理方法在高并发的情况下会有大量对象的创建和销毁,浪费资源。推荐使用第二种方式,使用ThreadLocal来存储SimpleDateFormat对象。这样每个线程就拥有了一个格式化对象副本,互不影响。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值