美文网首页
java8系列-06 时间相关API

java8系列-06 时间相关API

作者: 这个人的昵称有点酷 | 来源:发表于2019-03-09 23:22 被阅读0次
    image

    用过旧版java时间类库的都清楚,其实用起来的感觉是非常糟糕的。比如java.sql.Date与java.util.Date除了包名以外类名都是一样的。(sql.Date是继承util.Date重写的)这种设计其实是非常差的,很容易搞混淆。再比如,当你在并发情景下用java.util.Date是很容易出问题的,因为java.util.Date是属于线程不安全的。针对这些问题,java8推出了一系列新的API. PS: 新的时间相关API都在java.time.*包下

    时间日期类

    表示时间戳的instant

    instant是用来表示时间戳的,等价于System.currentTimeMillis(),instant类被设计成单例模式,使用起来也是极其方便的。

    Instant类构建的几种方法以及他们的作用

    public class InstantDemo {
    
        public static void main(String[] args) {
            Instant now = Instant.now(); // return Clock.systemUTC().instant(); 也就是说默认的是格林时区的时间
            System.out.println(now.toEpochMilli());
    
            // 相对于格林时区偏移八小时,就是中国的上海时区啦
            Instant now2 = Instant.now(Clock.offset(Clock.systemUTC(), Duration.ofHours(8)));
            System.out.println(now2.toEpochMilli());
    
            Instant from = Instant.from(ZonedDateTime.now()); // 从时态对象(TemporalAccessor接口)获取Instant的实例
            System.out.println(from.toEpochMilli());
    
            Instant milli = Instant.ofEpochMilli(System.currentTimeMillis()); // 通过毫秒数值直接构建Instant实例
            System.out.println(milli.getEpochSecond());
    
            Instant second = Instant.ofEpochSecond(60); // 通过传入一个标准时间的偏移值来构建Instant实例
            System.out.println(second);
    
            Instant second2 = Instant.ofEpochSecond(60,60); // 第二个参数:纳秒调整到秒数,正或负
            System.out.println(second2);
    
            System.out.println(System.currentTimeMillis());
        }
    }
    

    输出

    1552128157932
    1552156957932
    1552128158057
    1552128158
    1970-01-01T00:01:00Z
    1970-01-01T00:01:00.000000060Z
    1552128158073
    

    由上可知,Instant默认是基于格林时区的,它可以通过.toEpochMilli()来转换成跟System.currentTimeMillis()一样效果的时间戳格式,当然它也可以直接通过.getEpochSecond()来直接转换成秒的时间戳格式

    表示日期的LocalDate

    以前的Date类在并发情境下做处理是很容易出现许多问题的(可以开多个线程来玩一下),而LocalDate可以更好的处理这种情况。从源码可以看到这一点: 如final class LocalDate,private LocalDate(){}...,有一点点并发基础的一定懂这些含义。

    LocalDate类构建的几种方法以及他们的作用

    public class LocalDateDemo {
        public static void main(String[] args) {
            LocalDate now = LocalDate.now(); // 和Instance一样默认的是格林时区
            System.out.println(now);
    
            LocalDate now2 = LocalDate.now(Clock.offset(Clock.systemUTC(), Duration.ofHours(24))); // 偏移格林时区24小时
            System.out.println(now2);
    
            LocalDate now3 = LocalDate.now(ZoneId.systemDefault()); // java.time.ZoneId是原有的java.util.TimeZone的替代品
            System.out.println(now3);
    
            LocalDate from = LocalDate.from(ZonedDateTime.now()); // 从时态对象(TemporalAccessor接口)获取LocalDate的实例
            System.out.println(from);
    
            LocalDate of = LocalDate.of(2017,5,21); // 参数分别为:year,month,dayOfMonth
            System.out.println(of);
    
            LocalDate epochDay = LocalDate.ofEpochDay(1800); // 比1970-01-01大多少天
            System.out.println(epochDay);
    
            LocalDate ofY = LocalDate.ofYearDay(2018,122); // 参数分别为 year , dayOfYear
            System.out.println(ofY);
    
            LocalDate parse = LocalDate.parse("2018-06-09"); // 字符串转换成LocalDate对象
            System.out.println(parse);
        }
    }
    

    输出

    2019-03-09
    2019-03-10
    2019-03-09
    2019-03-09
    2017-05-21
    1974-12-06
    2018-05-02
    2018-06-09
    

    LocalDate类一些比较有用的方法

    • public int getYear():获取年份信息
    • public int getMonthValue():获取月份信息
    • public int getDayOfMonth():获取当前日是这个月的第几天
    • public int getDayOfYear():获取当前日是这一年的第几天
    • public boolean isLeapYear():是否是闰年
    • public int lengthOfYear():获取这一年有多少天
    • public DayOfWeek getDayOfWeek():返回星期信息
    • public String format(DateTimeFormatter formatter): 格式化LocalDate
    • public LocalDate minusYears(long yearsToSubtract):返回此LocalDate对象,并减去指定的年数。
    • public LocalDate plusDays(long daysToAdd):返回此LocalDate对象,并添加指定的天数。

    太多了,这里就不一一列出来了...

    时间LocalTime

    LocalTime其实与上面的LocalDate类似,只不过LocalTime是来表示时间,而LocalDate是用作日期

    LocalTime类构建

    public class LocalTimeDemo {
        public static void main(String[] args) {
            LocalTime now = LocalTime.now();
            System.out.println(now); // 输出19:54:31.010
        }
    }
    
    • static LocalTime now():在默认时区中从系统时钟获取当前时间。
    • static LocalTime now(Clock clock):从指定的时钟获得当前时间。
    • static LocalTime now(ZoneId zone):从指定时区的系统时钟获取当前时间。
    • static LocalTime ofNanoOfDay(long nanoOfDay):从一天的纳米值获得LocalTime的实例。
    • static LocalTime from(TemporalAccessor temporal):从temporal对象获取LocalTime的实例。
    • static LocalTime of(int hour, int minute): 从指定小时分钟获得LocalTime的实例。
    • static LocalTime of(int hour, int minute, int second):从指定小时,分钟和秒钟获取LocalTime的实例。
    • static LocalTime of(int hour, int minute, int second, int nanoOfSecond):从指定小时,分钟,秒和纳秒获得LocalTime的实例。
    • static LocalTime parse(CharSequence text):从文本字符串中获取LocalTime的实例。

    localTime类的一些方法

    public class LocalTimeDemo {
        public static void main(String[] args) {
            LocalTime now = LocalTime.now();
            String minute = now.getMinute()<10?"0"+now.getMinute():String.valueOf(now.getMinute());
            String second = now.getSecond()<10?"0"+now.getSecond():String.valueOf(now.getSecond());
            System.out.println("当前时间:"+now.getHour()+":"+minute+":"+second); //当前时间:20:09:13
            // 获取纳秒字段的值。
            System.out.println(now.getNano()); // 434000000
            // 与另一个时间比较。
            System.out.println(now.compareTo(LocalTime.MAX)); // -1
            // 将日期装换成String
            System.out.println(now.toString()); // 20:09:13.434
            // 将此时间与日期相结合以创建LocalDateTime。
            System.out.println(now.atDate(LocalDate.now())); // 2019-03-09T20:09:13.434
            // 创建一个新的LocalTime,并更改日期。
            System.out.println(now.withHour(8)); // 08:09:13.434
            // 创建一个此时间的偏移时间的LocalTime
            System.out.println(now.atOffset(ZoneOffset.ofHours(8))); // 20:09:13.434+08:00
            // 创建一个此时间加上8小时的Localtime
            System.out.println(now.plusHours(8)); // 04:09:13.434
        }
    }
    

    关于LocalTime还有一些其他的方法,请自行研究~~

    时区相关的日期时间ZonedDateTime

    上面讲的LocalDate、LocalTime还有未讲到的LocalDateTime都是与时区无关的,都只是用的默认时区,而类的本身并没有存储时区。而上面的类要用到时区的话,还需要此类来协助。

    public class ZonedDateTimeDemo {
        public static void main(String[] args) {
            ZonedDateTime zdt = ZonedDateTime.now();
            System.out.println(zdt); // 2019-03-09T23:14:48.560+08:00[Asia/Shanghai]
    
            ZonedDateTime zdt2 = ZonedDateTime.of(LocalDate.now(), LocalTime.now(), ZoneId.of("America/Chicago"));
            System.out.println(zdt2); // 2019-03-09T23:14:48.560-06:00[America/Chicago]
    
            ZonedDateTime zdt3 = ZonedDateTime.ofInstant(Instant.now(),ZoneId.of("Africa/Cairo"));
            System.out.println(zdt3); // 2019-03-09T17:14:48.591+02:00[Africa/Cairo]
        }
    }
    

    解释一下,第一个输出系统默认时区。第二个输出的是没过芝加哥时区,两个参数,第一个是LocalDate,第二个是LocalTime(上面说过这两个类默认是没有任何时区的,想要时区还的结合ZonedDateTime类)。第二个输出是非洲开罗时区,这里传入的参数是时间戳Instant

    关于时间的工具类

    日期时间格式化

    上面讲LocalDate的时候有讲到一个format方法,里面传入的参数是DateTimeFormatter,那这里就讲一下这个类吧。其实也没什么很多要讲的,毕竟它用起来真的太方便啦。一起来看看

    public class DateTimeFormatterDemo {
    
        public static void main(String[] args) {
            LocalDateTime currentTime = LocalDateTime.now();
    
            // DateTimeFormatter默认规范有很多,这里只列举出了三个
            System.out.println(currentTime.format(DateTimeFormatter.BASIC_ISO_DATE)); // 20190309
    
            System.out.println(currentTime.format(DateTimeFormatter.ISO_DATE_TIME)); // 2019-03-09T23:39:02.261
    
            System.out.println(currentTime.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2019-03-09
    
            System.out.println(currentTime.format(DateTimeFormatter.ofPattern("yyyyMMdd"))); // 20190309
        }
    }
    

    真的使用起来太简单了,并且你想要的格式它基本都有

    时间差 Period\Duration

    1. Period

    Period是以年月日来衡量一个时间段,比如几年几月几日

    public class PeriodDemo {
    
        public static void main(String[] args) {
            Period period = Period.of(2018,8,22);
            System.out.println(period);
    
            System.out.println(Period.between(LocalDate.of(2018,3,5), LocalDate.now()));
        }
    }
    

    输出

    P2018Y8M22D
    P1Y4D
    
    • P:标识开头
    • Y:年
    • M:月
    • D:日

    2. Duration

    Duration也是表示一个时间段。不知道各位有没有注意到,其实上面例子中有用到过这个类 Duration.ofHours(8) 向后推迟8小时

    public class DurationDemo {
        public static void main(String[] args) {
            LocalDateTime from = LocalDateTime.of(2018,Month.DECEMBER,22,22,33);//2018-12-22T22:33
            LocalDateTime to = LocalDateTime.now(); // 2019-03-10T00:05:42.443
            Duration duration = Duration.between(from, to); // PT1849H33M20.732S
    
            long days = duration.toDays();              // 这段时间的总天数
            long hours = duration.toHours();            // 这段时间的小时数
            long minutes = duration.toMinutes();        // 这段时间的分钟数
            long seconds = duration.getSeconds();       // 这段时间的秒数
            long milliSeconds = duration.toMillis();    // 这段时间的毫秒数
            long nanoSeconds = duration.toNanos();      // 这段时间的纳秒数
        }
    }
    

    其实使用多了这些类你会发现,这些类都有许多的共用。这些我这里就没有总结,请多动手,习惯成自然。

    相关文章

      网友评论

          本文标题:java8系列-06 时间相关API

          本文链接:https://www.haomeiwen.com/subject/smcepqtx.html