Java 8 Date/Time API

1.为什么需要新的java date api

先看下java8之前的date api有哪些问题?

  • 在 java.util 和 java.sql 包中都有日期类
  • java.util.Date 包含日期和时间值,而 java.sql.Date 仅包含日期值。这两个类具有相同的名称,这本身就是一个非常糟糕的设计
  • 没有明确定义的时间、时间戳、格式和解析类。我们有用于解析和格式化需要的 java.text.DateFormat 抽象类。通常,SimpleDateFormat 类用于解析和格式化。
  • 所有 Date 类都是可变的,因此它们不是线程安全的,这是 Java Date 和 Calendar 类的最大问题之一。
  • Date 类不提供国际化,不支持时区。

2.Java 8 Date Time设计原则

  • 不可变性:新的 Date-Time API 中的所有类都是不可变的,并且适用于多线程环境。
  • 关注点分离:新的 API 清楚地区分了人类可读的日期时间和机器时间(Unix 时间戳)。它为 Date、Time、DateTime、Timestamp、Timezone 等定义了单独的类。
  • 明确性:所有方法被明确定义并在所有类中执行相同的操作。例如,要获取当前实例,我们有 now() 方法。所有这些类中都定义了 format() 和 parse() 方法,而不是为它们创建一个单独的类。
  • 有效的操作:新的Date-Time API 中有诸如plus, minus, format, parsing, getting的有效操作
  • 扩展性:新的日期时间 API 适用于 ISO-8601 日历系统,但我们也可以将其与其他非 ISO 日历一起使用。

3.Java 8 Date Time API包

  1. java.time:新的Date Time API的基础包,包含LocalDate LocalDateTime Instant等等。所有的类都是线程安全的,足够满足大多数情况的需求。
  2. java.time.chrono:定义了通用的非 ISO 日历系统的API
  3. java.time.format:这个包主要是一些关于解析和格式化的类
  4. java.time.temporal:用于找到一些特定日期和时间的包,比如本月第一天这种
  5. java.time.zone Package:时区相关的包

4.Java 8 Date Time API简介和一些例子

4.1 LocalDate

//今天
LocalDate today = LocalDate.now();

//明天
LocalDate tomorrow = LocalDate.now().plusDays(1);
//上个月的今天 特定枚举
LocalDate previousMonthSameDay = LocalDate.now().minus(1, ChronoUnit.MONTHS);

//DayOfWeek为枚举类,返回周几的枚举值 SATURDAY
DayOfWeek saturday = LocalDate.parse("2022-07-30").getDayOfWeek();

//当月的第几天
int twelve = LocalDate.parse("2022-07-30").getDayOfMonth();

//是否闰年
boolean leapYear = LocalDate.now().isLeapYear();


boolean notBefore = LocalDate.parse("2022-07-30")
                .isBefore(LocalDate.now());

boolean isAfter = LocalDate.parse("2022-07-30")
                .isAfter(LocalDate.now());

//当前天的开头即0点0分0秒
LocalDateTime beginningOfDay = LocalDate.parse("2022-07-30").atStartOfDay();
//月初
LocalDate firstDayOfMonth = LocalDate.parse("2022-07-30")
  .with(TemporalAdjusters.firstDayOfMonth());


//指定年月日
LocalDate specialDay = LocalDate.of(2022, Month.JULY, 9);

LocalDate.parse("2015-02-20");

//1970-01-01之后的时间
LocalDate epochDay = LocalDate.ofEpochDay(1L);

//某年的第几天
LocalDate thisYearDay = LocalDate.ofYearDay(2022, 2);

//相隔时间
LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));
int five = Period.between(initialDate, finalDate).getDays();
long five = ChronoUnit.DAYS.between(initialDate, finalDate);

4.2 LocalTime

        //当前的时分秒
        LocalTime now = LocalTime.now();
        //指定时间
        LocalTime sixThirty = LocalTime.parse("06:30");
        LocalTime ofTime = LocalTime.of(14, 9, 20);


        LocalTime sevenThirty = LocalTime.parse("06:30").plus(1, ChronoUnit.HOURS);

        //获取小时
        int six = LocalTime.parse("06:30").getHour();
        
        //比较前后
        boolean isbefore =     
        LocalTime.parse("06:30").isBefore(LocalTime.parse("07:30"));
        //今天的结尾
        LocalTime maxTime = LocalTime.MAX;

        //指定时区的时间
        LocalTime timeKolkata = LocalTime.now(ZoneId.of("Asia/Kolkata"));

        //今天开始的第几秒的时间
        LocalTime secondOfDayTime = LocalTime.ofSecondOfDay(1L);

4.3 LocalDateTime

        //当前的年月日时分秒 yyyy-MM-ddTHH-mm-ss.zzz
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime nowTime = LocalDateTime.of(LocalDate.now(), LocalTime.now());
        //特定枚举
        LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30);
        LocalDateTime.parse("2015-02-20T06:30:00");
        LocalDateTime ofDateTime = LocalDateTime.of(2022, 7, 15, 20, 00);

        //时区
        LocalDateTime todayKolkata = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
        
        //时间的加减
        LocalDateTime.now().plusDays(1);
        LocalDateTime.now().minusHours(2);
        //月份
        LocalDateTime.now().getMonth();

        //date from BaseTime
        LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0,     
        ZoneOffset.UTC);

4.4 ZoneId

//时区相关
//所有时区 java.time.ZoneId#SHORT_IDS
ZoneId zoneId = ZoneId.of("Europe/Paris");

Set<String> allZoneIds = ZoneId.getAvailableZoneIds();

//2022-07-26T14:57:50.381+02:00[Europe/Paris]
ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.now(), zoneId);

ZonedDateTime parse = ZonedDateTime.parse("2015-05-03T10:15:30+01:00[Europe/Paris]");

4.5.Instant

        //Instant class is used to work with machine readable time format. 
        //Instant stores date time in unix timestamp.
        Instant now = Instant.now();
        System.out.println(now);

        //Instant from timestamp 
        // epochMilli – the number of milliseconds from 1970-01-01T00:00:00Z
        Instant specificTime = Instant.ofEpochMilli(now.toEpochMilli());
        System.out.println("Specific Time = "+specificTime);

        //Duration:A time-based amount of time, such as '34.5 seconds'.
        Duration thirtyDay = Duration.ofDays(1);
        System.out.println(thirtyDay);

4.6 一些常见病的转换demo

//Date转localDateTime
Date date = new Date();
LocalDateTime nowByDate = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());

//LocalDateTime转Date
Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

Date.from(LocalDateTime.of(LocalDate.now(), LocalTime.now())
          .atZone(ZoneId.systemDefault()).toInstant());


//Calendar转LocalDateTime
Calendar calendar = Calendar.getInstance();
LocalDateTime nowByCalendar = LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault());

//localDateTime转string
String format = localDateTime.format(DateTimeFormatter.ofPattern("YYYY-MM-DD HH:mm:ss"));
String format = localDateTime.format(DateTimeFormatter.ISO_DATE);

//当前周
LocalDate today = LocalDate.now();
LocalDate monday = today.with(TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY));
LocalDate sunday = today.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY ));

//localdate转date
public Date convertDate(LocalDate localDate){
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

以上是对java8Date/Time API的总结和拙见,希望能对你有所帮助。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lima1995

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值