如Java8的LocalDate与Date相互转换、ZonedDateTime等常用操作包含多个使用示例、Java8时区ZoneId的使用方法、Java8时间字符串解析成类

本文详细介绍了Java8时间API的使用,包括Date转LocalDate、LocalDateTime,LocalDate的常见操作,如获取当前日期、计算日期差、获取月份天数等。此外,还探讨了时区ZoneId的应用,解析不同时间字符串为Instant、LocalDateTime、ZonedDateTime,并展示了如何将LocalDateTime转化为带有时区的ZonedDateTime。
摘要由CSDN通过智能技术生成

下面将依次介绍

Date转Java8时间类操作 ,Java8时间类LocalDate常用操作(如获得当前日期,两个日期相差多少天,下个星期的日期,下个月第一天等)
解析不同时间字符串成对应的Java8中的类,如Instant、LocalDateTime、ZonedDateTime
时区ZoneId的使用场景、方式(根据ZoneId可将普通日期时间转化带有时区的日期时间,如2018-12-07T09:33:38Z,2018-10-08T18:12:38.547+08:00[Asia/Shanghai])。
java.time包中的是类是不可变且线程安全的。

新的时间及日期API位于java.time中,下面是一些关键类

●Instant——它代表的是时间戳,注意这里默认的Instant是0时区,比北京少8个时区,例子:2018-10-08T09:50:21.852Z,相当于当天北京时间的17:50:21.852

●LocalDate——不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。

●LocalTime——它代表的是不含日期的时间

●LocalDateTime——它包含了日期及时间,不过还是没有偏移信息或者说时区。

●ZonedDateTime——这是一个包含时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的,如:2018-10-08T18:12:38.547+08:00[Asia/Shanghai]。

一个例子:给出一个时间段,计算该时间范围由哪些日期(天)和月份组成。
一 、先主要是Java8中LocalDate日期的操作

  1. Date转LocalDate、LocalDateTime
    Date转化为Instant时间戳,然后instant和系统默认时区转化成LocalDate
Date转LocalDate: Date -> Instant + System default time zone = LocalDate
     */
    @Test
    public void dateToLocalDateAndLocalDateTime(){
        Date date = new Date();
        Instant instant = date.toInstant();
        /**
         * instant : 2018-10-08T09:50:21.852Z
         * Zone : UTC+0
         * 注意这里默认的Instant是比北京少8个时区
         */


        //获得本地默认时区
        ZoneId defaultZoneId = ZoneId.systemDefault();

        LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate();
        System.out.println(localDate);
     //2018-10-08
    }

Date转化成本地系统时区的LocalDateTime

@Test
    public void dateToLocalDateTime(){
        Date date = new Date();
        Instant instant = date.toInstant();
        //系统默认的时区
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
        System.out.println(localDateTime);
    }
  1. 13位long类型转LocalDate
    long -> Instant +System default time zone = LocalDate
public LocalDate longToLocalDate(Long time){

        //System Default TimeZone : Asia/Shanghai
        ZoneId defaultZoneId = ZoneId.systemDefault();

        //2018-01-04T16:00:00Z
        //时间戳
        Instant instant = Instant.ofEpochMilli(time);

        //2018-01-05
        LocalDate localDate = instant.atZone(defaultZoneId).toLocalDate();

        return localDate;
    }
  1. 获取现在的日期
    Java8中有个叫LocalDate的类,能用来表示日期。这个类与java.util.Date略有不同,因为它只包含日期,没有时间。
    在这里插入图片描述
  2. 获取年月日在这里插入图片描述
  3. 判断两个日期之间相差多少天
/**
     * 判断两个日期相差多少天
     */
    @Test
    public void localDateDiff(){
        LocalDate date1 = LocalDate.of(2018,9,20);
        LocalDate date2 = LocalDate.of(2018,10,3);
        long l = date2.toEpochDay() - date1.toEpochDay();
        System.out.println(l);
    }
  1. 获得某个日期所在月的第一天、最后一天
/**
     * 获得某个日期所在月的第一天、最后一天
     */
    @Test
    public void firstLastDay(){

        LocalDate localDate = LocalDate.of(2018, 2, 22);
        LocalDate firstDay = localDate.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println("firstDay: "+firstDay+"  lastDay: "+lastDay);
        //firstDay: 2018-02-01  lastDay: 2018-02-28
    }
  1. 某个月有多少天
    先获取该月的最后一天的LocalDate,再调用getDayOfMonth()方法
 /**
     * 某个月有多少天
     */
    @Test
    public void getDayOfMonth(){
        LocalDate localDate = LocalDate.of(2018, 2, 22);
        LocalDate lastDay = localDate.with(TemporalAdjusters.lastDayOfMonth());
        int dayOfMonth = lastDay.getDayOfMonth();
        System.out.println(dayOfMonth);
        //28
    }
  1. 比较两个LocalDate的大小
/**
     * 比较两个LocalDate的大小
     */
    @Test
    public void localDateCompareTo(){
        LocalDate date1 = LocalDate.of(2018,9,20);
        LocalDate date2 = LocalDate.of(2018,10,3);
        int i = date1.compareTo(date2);
        System.out.println(i);
        //-1 小

        int i1 = date2.compareTo(date1);
        System.out.println(i1);
        //1 大

        int i2 = date1.compareTo(date1);
        System.out.println(i2);
        //0 等于
    }
  1. 获取下一周的该星期、下个月的这天、下个月的1号
/**
     * 获取下一周的该星期、下个月的这天、下个月的1号
     */
    @Test
    public void nextMonth(){

        LocalDate localDate = LocalDate.of(2018, 2, 12);

        //下一周的该星期
        LocalDate localDate1 = localDate.minusWeeks(-1);
        System.out.println(localDate1);
        //2018-02-19

        //获取下个月的这天
        LocalDate localDate2 = localDate.minusMonths(-1);
        System.out.println(localDate2);
        //2018-03-12

        //下个月的1号
        LocalDate localDate3 = LocalDate.of(localDate.getYear(), localDate.getMonthValue()+1, 1);
        System.out.println(localDate3);
        //2018-03-01
    }
  1. 比较两个LocalDate相差多少年、月、天
    Period这个类,这里比较的是两个日期,相差多少年、多少个月、多少天;

比如下面的这个例子中,2018.10.9 比 2019.4.1相差 0年 5个月 23天

/**
     * 比较两个LocalDate相差多少年、月、日
     */
    @Test
    public void localDatePeriod(){
        LocalDate date1 = LocalDate.of(2018,10,9);
        LocalDate date2 = LocalDate.of(2019,4,1);
        Period period = Period.between(date1, date2);
        int years = period.getYears();
        int months = period.getMonths();
        int days = period.getDays();
        System.out.println("years:"+years+", months:"+months+", days:"+days);
        //years:0, months:5, days:23
    }
  1. 通过10位或13位时间戳构建Instant
    ofEpochSecond()参数是10位时间戳,精确到秒;

ofEpochMilli()参数是13位时间戳,精确到毫秒。

@Test
    public void ofEpochSecond(){
        Instant now = Instant.now();
        System.out.println(now);
        //2019-03-13T06:41:32.865Z

        //去除毫秒
        long l = now.toEpochMilli() / 1000;
        //通过秒构建Instant对象
        Instant instant = Instant.ofEpochSecond(l);
        System.out.println(instant);
        //2019-03-13T06:41:32Z
    }

二、 将特殊格式的字符串解析成对应的时间类
由下面例子总结:

Instant只能解析"TZ”这种格式的时间,即UTC字符串;

ZonedDateTime解析的时间字符串必须是要有年月日时分秒以及时区;

LocalDateTime解析的时间字符串必须要有年月日时分秒,但是不能有时区,例如末尾有"Z"的时间表示UTC的0时区就不能解析;

LocalDate解析的时间字符串必须只能有年月日,格式如"2018-12-07",多任何其他字符都不能解析。

1.格式:2018-12-07T09:33:38+00:00

/**
     * 解析字符串:2018-12-07T09:33:38+00:00
     * ZonedDateTime必须解析有时区的时间
     */
    @Test
    public void stringToZonedDateTime(){
        final String string ="2018-12-07T09:33:38+00:00";
        ZonedDateTime parse = ZonedDateTime.parse(string);
        System.out.println(parse.toString());
        //结果是2018-12-07T09:33:38Z
        ZoneId zone = parse.getZone();
        System.out.println(zone);
    }

2.2018-12-07T09:33:38Z

/**
     * 解析字符串:2018-12-07T09:33:38Z,无法解析2018-12-07T09:33:38+00:00
     * Instant只能解析"**T**Z”这种格式的时间
     */
    @Test
    public void stringToInstant(){
        final String string ="2018-12-07T09:33:38Z";
        Instant parse = Instant.parse(string);
        System.out.println(parse);
        //2018-12-07T09:33:38Z
    }
/**
     * 解析字符串:2018-12-07T09:33:38Z
     * 表示的是0时区的时间
     */
    @Test
    public void stringToZonedDateTime1(){
        final String string ="2018-12-07T09:33:38Z";
        ZonedDateTime parse = ZonedDateTime.parse(string);
        System.out.println(parse.toString());
        //结果是2018-12-07T09:33:38Z
        ZoneId zone = parse.getZone();
        System.out.println(zone);
    }

3.2018-12-07T09:33:38,末尾无Z,没有时区

 /**
     * 解析字符串:2018-12-07T09:33:38,末尾不能有Z,有T有Z代表了UTC 0时区的时间,还必须要有"T时分秒"这一截字符串
     * LocaDateTime无法解析带有时区的字符串时间
     */
    @Test
    public void stringToLocalDateTime(){
        final String string ="2018-12-07T09:33:38";
        LocalDateTime parse = LocalDateTime.parse(string);
        System.out.println(parse.toString());
        //结果是2018-12-07T09:33:38
    }

4.2018-12-07

/**
     * 解析字符串:2018-12-07,只能解析该格式字符串
     * LocaDate无法解析带有时区的字符串时间
     */
    @Test
    public void stringToLocalDate(){
        final String string ="2018-12-07";
        LocalDate parse = LocalDate.parse(string);
        System.out.println(parse.toString());
        //结果是2018-12-07

    }

三、 时区ZoneID相关操作
ZoneID.of(String zoneId) 时区参数
这里的zoneId字符串可以传入"Asia/Shanghai",字符串如下:

EST - -05:00
HST - -10:00
MST - -07:00
ACT - Australia/Darwin
AET - Australia/Sydney
AGT - America/Argentina/Buenos_Aires
ART - Africa/Cairo
AST - America/Anchorage
BET - America/Sao_Paulo
BST - Asia/Dhaka
CAT - Africa/Harare
CNT - America/St_Johns
CST - America/Chicago
CTT - Asia/Shanghai
EAT - Africa/Addis_Ababa
ECT - Europe/Paris
IET - America/Indiana/Indianapolis
IST - Asia/Kolkata
JST - Asia/Tokyo
MIT - Pacific/Apia
NET - Asia/Yerevan
NST - Pacific/Auckland
PLT - Asia/Karachi
PNT - America/Phoenix
PRT - America/Puerto_Rico
PST - America/Los_Angeles
SST - Pacific/Guadalcanal
VST - Asia/Ho_Chi_Minh
将不带时区LocalDateTime转化为带时区的ZonedDateTime

/**
     * 把无时区的时间LocaDateTime解析成有时区的ZonedDateTime
     */
    @Test
    public void localDateTimeToZonedDateTime(){
        final String string ="2018-12-07T09:33:38";
        LocalDateTime parse = LocalDateTime.parse(string);
        ZonedDateTime z1 = ZonedDateTime.of(parse, ZoneId.of("Asia/Shanghai"));
        System.out.println(z1.toString());
        //2018-12-07T09:33:38+08:00[Asia/Shanghai]

        ZonedDateTime z2 = ZonedDateTime.of(parse, ZoneId.of("Z"));
        System.out.println(z2.toString());
        //2018-12-07T09:33:38Z

        ZonedDateTime z3 = ZonedDateTime.of(parse, ZoneId.of("UTC"));
        System.out.println(z3.toString());
        //2018-12-07T09:33:38Z[UTC]

        ZonedDateTime z4 = ZonedDateTime.of(parse, ZoneId.of("UTC+08:00"));
        System.out.println(z4.toString());
        //2018-12-07T09:33:38+08:00[UTC+08:00]

        ZonedDateTime z5 = ZonedDateTime.of(parse, ZoneId.of("+08:00"));
        System.out.println(z5.toString());
        //2018-12-07T09:33:38+08:00

        ZonedDateTime z6 = ZonedDateTime.of(parse, ZoneId.of("+00:00"));
        System.out.println(z6.toString());
        //2018-12-07T09:33:38Z

    }

由结果可知,String zoneId的字符串值,如果为:

“Asia/Shanghai"例子为"2018-12-07T09:33:38+08:00[Asia/Shanghai]” ;

“Z"和”+00:00"表示的是"2018-12-07T09:33:38Z"这种格式的时间;

“UTC"表示的是"2018-12-07T09:33:38Z[UTC]” ;

“UTC+08:00” 例子:“2018-12-07T09:33:38+08:00[UTC+08:00]” ;

“+08:00” 例子:“2018-12-07T09:33:38+08:00”
四.或者根据下列来

SimpleDateFormat formatter =new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String dateValues = "2022-07-07T16:00:00.000Z";
                    if (dateValues != ""){
                        try {
                            dateValues = dateValues.replace("Z","UTC");
                            dateValue = formatter.parse(dateValues);
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        System.out.println(dateValue);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值