• 常用类(四)


    JDK1.8新增日期时间类型

    如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。Java1.0中包含了一个Date类,但是它的大多数方法已经在Java 1.1引入Calendar类之后被弃用了。而Calendar并不比Date好多少。它们面临的问题是:

    l  可变性:象日期和时间这样的类对象应该是不可变的。Calendar类中可以使用三种方法更改日历字段:set()、add() 和 roll()。

    l  偏移性:Date中的年份是从1900开始的,而月份都是从0开始的。

    l  格式化:格式化只对Date有用,Calendar则不行。

    l  此外,它们也不是线程安全的,不能处理闰秒等。

    Date的API:

    尽管 Date 类打算反映协调世界时 (UTC),但无法做到如此准确,这取决于 Java 虚拟机的主机环境。当前几乎所有操作系统都假定 1 天 = 24 × 60 × 60 = 86400 秒。但对于 UTC,大约每一两年出现一次额外的一秒,称为“闰秒”。闰秒始终作为当天的最后一秒增加,并且始终在 12 月 31 日或 6 月 30 日增加。例如,1995 年的最后一分钟是 61 秒,因为增加了闰秒。大多数计算机时钟不是特别的准确,因此不能反映闰秒的差别。

    在类 Date 所有可以接受或返回年、月、日期、小时、分钟和秒值的方法中,将使用下面的表示形式:

    l  年份 y 由整数 y - 1900 表示。

    l  月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。

    l  日期(一月中的某天)按通常方式由整数 1 至 31 表示。

    l  小时由从 0 至 23 的整数表示。因此,从午夜到 1 a.m. 的时间是 0 点,从中午到 1 p.m. 的时间是 12 点。

    l  分钟按通常方式由 0 至 59 的整数表示。

    l  秒由 0 至 61 的整数表示;值 60 和 61 只对闰秒发生,尽管那样,也只用在实际正确跟踪闰秒的 Java 实现中。于按当前引入闰秒的方式,两个闰秒在同一分钟内发生是极不可能的,但此规范遵循 ISO C 的日期和时间约定。

    在所有情形中,针对这些目的赋予方法的参数不需要在指定的范围内;例如,可以把日期指定为 1 月 32 日,并把它解释为 2 月 1 日的相同含义。

                       Date date = new Date(2017-1900,8-1,28);

                       System.out.println(date);//Mon Aug 28 00:00:00 CST 2017

    可以说,对日期和时间的操作一直是Java程序员最痛苦的地方之一。第三次引入的API是成功的,并且java 8中引入的java.time API 已经纠正了过去的缺陷,将来很长一段时间内它都会为我们服务。

    Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。

    l  java.time – 包含值对象的基础包

    l  java.time.chrono – 提供对不同的日历系统的访问。

    l  java.time.format – 格式化和解析时间和日期

    l  java.time.temporal – 包括底层框架和扩展特性

    l  java.time.zone – 包含时区支持的类

    Java 8 吸收了 Joda-Time 的精华,以一个新的开始为 Java 创建优秀的 API。新的 java.time 中包含了所有关于时钟(Clock),本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。这些新增的本地化时间日期 API 大大简化了了日期时间和本地化的管理。

    说明:大多数开发者只会用到基础包和format包,也可能会用到temporal包。因此,尽管有68个新的公开类型,大多数开发者,大概将只会用到其中的三分之一。

    java.time

    注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。

     java.time.chrono

     

    10.8.1 java.time

    1、本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)

    LocalDate代表IOS格式(yyyy-MM-dd)的日期,可以存储 生日、纪念日等日期。

    LocalTime表示一个时间,而不是日期

    LocalDateTime是用来表示日期和时间的,这是一个最常用的类之一。

     

    描述

    now() / now(ZoneId zone)

    静态方法,根据当前时间创建对象/指定时区的对象

    of()

    静态方法,根据指定日期/时间创建对象

    getDayOfMonth()/getDayOfYear()

    获得月份天数(1-31) /获得年份天数(1-366)

    getDayOfWeek()

    获得星期几(返回一个 DayOfWeek 枚举值)

    getMonth()

    获得月份, 返回一个 Month 枚举值

    getMonthValue() / getYear()

    获得月份(1-12) /获得年份

    getHours()/getMinute()/getSecond()

    获得当前对象对应的小时、分钟、秒

    withDayOfMonth()/withDayOfYear()/withMonth()/withYear()

    将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象

     with(TemporalAdjuster  t)

    将当前日期时间设置为校对器指定的日期时间

    plusDays(), plusWeeks(), plusMonths(), plusYears(),plusHours()

    向当前对象添加几天、几周、几个月、几年、几小时

    minusMonths() / minusWeeks()/minusDays()/minusYears()/minusHours()

    从当前对象减去几月、几周、几天、几年、几小时

    plus(TemporalAmount t)/minus(TemporalAmount t)

    添加或减少一个 Duration 或 Period

    isBefore()/isAfter()

    比较两个 LocalDate

    isLeapYear()

    判断是否是闰年(在LocalDate类中声明)

     format(DateTimeFormatter  t)

    格式化本地日期、时间,返回一个字符串

     parse(Charsequence text)

    将指定格式的字符串解析为日期、时间

        //now()

        @Test

             public void testLocalDateTime(){

                       LocalDate date = LocalDate.now();

                       LocalTime time = LocalTime.now();

                       LocalDateTime datetime = LocalDateTime.now();

        }

        //of()或parse

             @Test

             public void testLocalDate() {

                       // LocalDate date = LocalDate.now();

                       // LocalDate date = LocalDate.of(2017, 3, 20);

                       LocalDate date = LocalDate.parse("2017-03-12");

             }

             public static void main(String[] args) {

                       LocalDateTime t = LocalDateTime.now();

                       System.out.println("这一天是这一年的第几天:"+t.getDayOfYear());

                       System.out.println("年:"+t.getYear());

                       System.out.println("月:"+t.getMonth());

                       System.out.println("月份值:"+t.getMonthValue());

                       System.out.println("日:"+t.getDayOfMonth());

                       System.out.println("星期:"+t.getDayOfWeek());

                       System.out.println("时:"+t.getHour());

                       System.out.println("分:"+t.getMinute());

                       System.out.println("秒:"+t.getSecond());

                       System.out.println(t.getMonthValue());

             }

             @Test

             public void testLocalDate2() {

                       LocalDate date = LocalDate.now();

            //withXxx()方法,不改变原来的date对象,返回一个新的对象,不可变性

                       // LocalDate date2 = date.withDayOfMonth(1);//获取这个月的第一天

                       LocalDate date2 = date.with(TemporalAdjusters.firstDayOfMonth());// 获取这个月的第一天

                       System.out.println(date2);

                       // 获取这个月的最后一天

                       LocalDate date3 = date.with(TemporalAdjusters.lastDayOfMonth());

                       System.out.println(date3);

                       //45天后的日期

                       LocalDate date4 = date.plusDays(45);

                       System.out.println(date4);

                       //20天前的日期

                       LocalDate date5 = date.minusDays(20);

                       System.out.println(date5);

                      

                       boolean before = date.isBefore(date5);

                       System.out.println(date+"是否比"+date5+"早" + before);

                      

                       System.out.println(date+"是否是闰年:"+date.isLeapYear());

                      

             }

                       MonthDay month = MonthDay.of(8, 14);

                       MonthDay today = MonthDay.from(date);

                       System.out.println("今天是否是生日:" + month.equals(today));

    2、瞬时:Instant

    Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。

    在处理时间和日期的时候,我们通常会想到年,月,日,时,分,秒。然而,这只是时间的一个模型,是面向人类的。第二种通用模型是面向机器的,或者说是连续的。在此模型中,时间线中的一个点表示为一个很大的数,这有利于计算机处理。在UNIX中,这个数从1970年开始,以秒为的单位;同样的,在Java中,也是从1970年开始,但以毫秒为单位。

    java.time包通过值类型Instant提供机器视图。Instant表示时间线上的一点,而不需要任何上下文信息,例如,时区。概念上讲,它只是简单的表示自1970年1月1日0时0分0秒(UTC)开始的秒数。因为java.time包是基于纳秒计算的,所以Instant的精度可以达到纳秒级。

    时间戳:指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

             public static void main(String[] args) {

                       Instant t = Instant.now();

                       System.out.println(t);

                      

                       //偏移8个小时

                       OffsetDateTime atOffset = t.atOffset(ZoneOffset.ofHours(8));

                       System.out.println(atOffset);

                      

                       long milli = t.toEpochMilli();

                       System.out.println(milli);

                      

                       Instant in2 = Instant.ofEpochSecond(10000000);

                       System.out.println(in2);

             }

    3、带时区的日期、时间的处理

    作为一个开发者,如果不用去处理时区和它带来的复杂性,那是幸运的。java.time包下的LocalDate、LocalTime、LocalDateTime和Instant基本能满足需求。当你不可避免时区时,ZonedDateTime等类可以满足我们的需求。

    ZonedDateTime:一个在ISO-8601日历系统时区的日期时间,如 2007-12-03T10:15:30+01:00 Europe/Paris。

    l  其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式,例如:Asia/Shanghai等

    l  now():使用系统时间获取当前的ZonedDateTime

    l  now(ZoneId):返回指定时区的ZonedDateTime

    ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris

    l  getAvailableZoneIds():静态方法,可以获取所有时区信息

    l  of(String id):静态方法,用指定的时区信息获取ZoneId对象

    Clock:使用时区提供对当前即时、日期和时间的访问的时钟。

             public static void main(String[] args) {

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

                       for (String string : availableZoneIds) {

                                System.out.println(string);

                       }

                      

                       ZonedDateTime t = ZonedDateTime.now();

                       System.out.println(t);

                      

                       ZonedDateTime t1 = ZonedDateTime.now(ZoneId.of("America/New_York"));

                       System.out.println(t1);

    //               Clock clock = Clock.systemDefaultZone();

                       Clock c = Clock.system(ZoneId.of("America/New_York"));

                       System.out.println(c.getZone());

                       System.out.println(c.instant());

             }

    4、持续时间:Duration

    Duration:用于计算两个“时间”间隔

             public static void main(String[] args) {

                       LocalDateTime t1 = LocalDateTime.now();

                       LocalDateTime t2 = LocalDateTime.of(2017, 8, 29, 0, 0, 0, 0);

                       Duration between = Duration.between(t1, t2);

                       System.out.println(between);

                      

                       System.out.println("相差的总天数:"+between.toDays());

                       System.out.println("相差的总小时数:"+between.toHours());

                       System.out.println("相差的总分钟数:"+between.toMinutes());

                       System.out.println("相差的总秒数:"+between.getSeconds());

                       System.out.println("相差的总毫秒数:"+between.toMillis());

                       System.out.println("相差的总纳秒数:"+between.toNanos());

                       System.out.println("不够一秒的纳秒数:"+between.getNano());

             }

    5、日期间隔:Period

    Period:用于计算两个“日期”间隔

             public static void main(String[] args) {

                       LocalDate t1 = LocalDate.now();

                       LocalDate t2 = LocalDate.of(2018, 12, 31);

                       Period between = Period.between(t1, t2);

                       System.out.println(between);

                      

                       System.out.println("相差的年数:"+between.getYears());//1年

                       System.out.println("相差的月数:"+between.getMonths());//又7个月

                       System.out.println("相差的天数:"+between.getDays());//零25天

                       System.out.println("相差的总数:"+between.toTotalMonths());//总共19个月

             }

    10.8.2 java.time.temporal .TemporalAdjuster : 时间校正器

    TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。

    TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/nextXxx())提供了大量的常用 TemporalAdjuster 的实现。

             public static void main(String[] args) {

                       LocalDate now = LocalDate.now();

                       System.out.println("下一个周日:"+now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));

                       System.out.println("下周五" + now.with(TemporalAdjusters.next(DayOfWeek.FRIDAY)));

            System.out.println("本月最后一天:"+now.with(TemporalAdjusters.lastDayOfMonth()));//2017-08-31

                       LocalDate week = LocalDate.now().with(new TemporalAdjuster(){

                                @Override

                                public Temporal adjustInto(Temporal temporal) {

                                         LocalDate date = (LocalDate) temporal;

                                         if(date.getDayOfWeek().equals(DayOfWeek.MONDAY)){

                                                   return date.plusDays(7);

                                         }else if(date.getDayOfWeek().equals(DayOfWeek.TUESDAY)){

                                                   return date.plusDays(6);

                                         }else if(date.getDayOfWeek().equals(DayOfWeek.WEDNESDAY)){

                                                   return date.plusDays(5);

                                         }else if(date.getDayOfWeek().equals(DayOfWeek.THURSDAY)){

                                                   return date.plusDays(4);

                                         }else if(date.getDayOfWeek().equals(DayOfWeek.FRIDAY)){

                                                   return date.plusDays(3);

                                         }else if(date.getDayOfWeek().equals(DayOfWeek.SATURDAY)){

                                                   return date.plusDays(2);

                                         }else{

                                                   return date.plusDays(1);

                                         }

                                }

                       });

                       System.out.println("下一个工作日:" + week);

             }

    10.8.3 java.time.format.DateTimeFormatter 类

    该类提供了三种格式化方法:

    预定义的标准格式。如:ISO_DATE_TIME;ISO_DATE

    本地化相关的格式。如:ofLocalizedDate(FormatStyle.MEDIUM)

    自定义的格式。如:ofPattern(“yyyy-MM-dd hh:mm:ss”)

             public static void main(String[] args) {

                       System.out.println(DateTimeFormatter.ISO_DATE.format(LocalDate.now()));

                       System.out.println(DateTimeFormatter.ISO_DATE_TIME.format(LocalDateTime.now()));

                      

                       //FULL和SHORT适用于LocalDate和LocalTime

                       System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(LocalDate.now()));

                       System.out.println(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT).format(LocalTime.now()));

                      

                       //LONG和MEDIUM适用于LocalDateTime

                      System.out.println(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(LocalDateTime.now()));

            

                       DateTimeFormatter op = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

                       System.out.println(op.format(LocalDateTime.now()));

             }

    10.8.4 与传统日期处理的转换

    To 遗留类

    From 遗留类

    java.time.Instantjava.util.Date

    Date.from(instant)

    date.toInstant()

    java.time.Instantjava.sql.Timestamp

    Timestamp.from(instant)

    timestamp.toInstant()

    java.time.ZonedDateTimejava.util.GregorianCalendar

    GregorianCalendar.from(zonedDateTime)

    cal.toZonedDateTime()

    java.time.LocalDatejava.sql.Time

    Date.valueOf(localDate)

    date.toLocalDate()

    java.time.LocalTimejava.sql.Time

    Date.valueOf(localDate)

    date.toLocalTime()

    java.time.LocalDateTimejava.sql.Timestamp

    Timestamp.valueOf(localDateTime)

    timestamp.toLocalDateTime()

    java.time.ZoneIdjava.util.TimeZone

    Timezone.getTimeZone(id)

    timeZone.toZoneId()

    java.time.format.DateTimeFormatterjava.text.DateFormat

    formatter.toFormat()

  • 相关阅读:
    【6.29】数组和方法
    【6.28】判断和循环
    【6.27】两个数交换的4种方法
    NodeJS学习笔记
    准备使用马克飞象写博客
    前端基础
    学习笔记
    数据结构 — Java链表
    Java 日期类型与字符串的相互转换
    Scala(一)基础
  • 原文地址:https://www.cnblogs.com/sunpengblog/p/10321406.html
Copyright © 2020-2023  润新知