如果我们可以对别人说:“我们下午见面,别迟到!”那就再简单不过了。但是我们希望时间与昼夜和季节相关,所以事情变得复杂了。Java1.0包含一个Date类,但在Java1.1引入Calendar类后,它的大部分方法已被弃用。而Calendar也不比Date好多少。他们面临的问题是:可变性:日期和时间等类应该是不可变的。可以使用Calendar类中的三种方法更改日历字段:set()、add()和roll()。Offset:Date中的年份从1900开始,月份从0开始。Formatting:格式化只对Date有用,对Calendar没有用。此外,它们不是线程安全的,不能处理闰秒等。Date的API:尽管Date类旨在反映协调世界时(UTC),但它不能准确地做到这一点,具体取决于Java虚拟机的主机环境。几乎所有当前的操作系统都假定1天=24×60×60=86400秒。但是对于UTC,每两年多一秒,称为“闰秒”。闰秒总是在一天的最后一秒递增,并且总是在12月31日或6月30日递增。比如1995年的最后一分钟,因为加了闰秒,所以是61秒。大多数计算机时钟不是特别准确,因此不能反映闰秒的差异。在接受或返回年、月、日、小时、分钟和秒值的所有Date类方法中,将使用以下表示法:ly年由整数y–1900表示。l月份由整数表示从0到11;0为一月,1为二月,以此类推;因此11是十二月。l日期(一个月中的几天)按照通常的方式用整数1到31表示。l小时用0到23的整数表示。因此,从午夜到凌晨1点的时间是0点,从中午到下午1点的时间是0点。12点了。l分钟按照通常的方式用0到59的整数表示。秒用0到61的整数表示;值60和61仅出现在闰秒中,即便如此,也仅在实际正确跟踪闰秒的Java实现中使用。由于当前引入闰秒的方式,同一分钟内出现两个闰秒的可能性极小,但此规范遵循ISOC日期和时间约定。在所有情况下,为这些目的提供给方法的参数不必在指定范围内;例如,一个日期可能被指定为1月32日,并被解释为与2月1日相同的意义。Datedate=newDate(2017-1900,8-1,28);System.out.println(date);//MonAug2800:00:00CST2017可以说,日期和时间的操作一直是Java程序员最痛苦的地方之一。第三次引入的API是成功的,java8中引入的java.timeAPI纠正了以往的不足,将在未来很长一段时间内为我们服务。Java8吸取了Joda-Time的精华,重新开始为Java创建出色的API。time-包含值对象的基本包time.chrono-提供对不同日历系统的访问。time.format-格式化和解析时间和日期time.temporal-包括底层框架和扩展功能time.zone-包含时区支持API的类。新的java.time包含有关Clock、LocalDate、LocalTime、LocalDateTime、ZonedDateTime和Duration的所有类。历史悠久的Date类有一个新的toInstant()方法,用于将Date转换为新的表示形式。这些新的本地化时间和日期API大大简化了日期时间和本地化的管理。注意:大多数开发者只会使用基本包和格式包,也可能会使用临时包。因此,虽然有68种新的公开类型,但大多数开发人员可能只会使用其中的大约三分之一。java.time注:ISO-8601日历系统是国际标准化组织制定的现代公民日期和时间的表示,即公历。java.time.chronojava.time1,本地日期(LocalDate),本地时间(LocalTime),本地日期时间(LocalDateTime)LocalDate表示IOS格式的日期(yyyy-MM-dd),可以存储生日,纪念日等日期.LocalTime表示时间,而不是日期。LocalDateTime用于表示日期和时间,是最常用的类之一。描述now()/now(ZoneIdzone)静态方法,根据当前时间创建对象/指定时区的对象of()静态方法,根据指定日期/时间创建对象getDayOfMonth()/getDayOfYear()获取该月的天数(1-31)/获取该年的天数(1-366)getDayOfWeek()获取星期几(返回一个DayOfWeek枚举值)getMonth()获取month,返回一个Month枚举值getMonthValue()/getYear()获取月份(1-12)/获取年份getHours()/getMinute()/getSecond()获取当前对象对应的时分秒对于指定的值并返回一个新对象with(TemporalAdjustert)将当前日期和时间设置为仲裁器指定的日期和时间plusDays(),plusWeeks(),plusMonths(),plusYears(),plusHours()添加几个当前对象的时间Days,Weeks,Months,Years,HoursminusMonths()/minusWeeks()/minusDays()/minusYears()/minusHours()/minus(TemporalAmountt)加上或减去一个Duration或PeriodisBefore()/isAfter()比较两个LocalDateisLeapYear()以确定是否是闰年(在LocalDate类中声明)format(DateTimeFormattert)format本地日期和时间,返回一个字符串parse(Charsequencetext)将指定格式的字符串解析成日期时间//now()@TestpublicvoidtestLocalDateTime(){LocalDatedate=LocalDate.now();LocalTimetime=LocalTime.now();LocalDateTime日期时间=LocalDayteTime.now();}//of()或parse@TestpublicvoidtestLocalDate(){//LocalDatedate=LocalDate.now();//LocalDatedate=LocalDate.of(2017,3,20);LocalDatedate=LocalDate.parse("2017-03-12");}publicstaticvoidmain(String[]args){LocalDateTimet=LocalDateTime.now();System.out.println("这一天是年初一几天:"+t.getDayOfYear());System.out.println("年份:"+t.getYear());System.out.println("月份:"+t.getMonth());系统。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("second:"+t.getSecond());System.out.println(t.getMonthValue());}@TestpublicvoidtestLocalDate2(){LocalDatedate=LocalDate.now();//withXxx()方法,不改变原来的日期对象,返回一个新的对象,不可变//LocalDatedate2=date.withDayOfMonth(1);//获取月份的第一天LocalDatedate2=date.with(TemporalAdjusters.firstDayOfMonth());//获取月份的第一天第一天System.out.println(date2);//获取月份的最后一天LocalDatedate3=date.with(TemporalAdjusters.lastDayOfMonth());System.out.println(date3);//45天后的日期LocalDatedate4=date.plusDays(45);System.out.println(date4);//20天前的日期LocalDatedate5=date.minusDays(20);System.out.println(date5);之前的布尔值=date.isBefore(date5);System.out.println(date+"早于"+date5+"+之前);System.out.println(date+"是否闰年:"+date.isLeapYear());}MonthDaymonth=MonthDay.of(8,14);MonthDaytoday=MonthDay.from(date);System.out.println("今天是生日吗:"+month.equals(today));2.瞬时:InstantInstant:时间轴上的一个瞬时点这个在应用中可能用来记录事件的时间戳,在处理时间和日期的时候,我们通常会想到年月日时分秒,但是这只是时间的一种模型,对于人类来说,秒一般模型是面向机器的,或者说是连续的。在这个模型中,时间轴上的一个点被表示为一个很大的数字,便于计算机处理。在UNIX中,这个数字是自1970年以来的秒数;同样,在Java中,也是在自1970年以来的毫秒数。java.time包通过值类型Instant提供机器视图。Instant表示时间轴上的一个点,没有任何上下文信息(例如时区)。从概念上讲,它只是表示自1970年1月1日0:00:00(UTC)以来的秒数。因为java.time包是按纳秒计算的,所以Instant的精度可以达到纳秒级别。时间戳:指从北京时间1970年1月1日00:00:00(北京时间1970年1月1日08:00:00)到现在的总秒数。publicstaticvoidmain(String[]args){Instantt=Instant.now();System.out.println(t);//偏移8小时OffsetDateTimeatOffset=t.atOffset(ZoneOffset.ofHours(8));System.out.println(atOffset);longmilli=t.toEpochMilli();System.out.println(milli);Instantin2=Instant.ofEpochSecond(10000000);System.out.println(in2);}3、处理带时区的日期和时间作为一名开发人员,如果您不必处理时区以及随之而来的复杂性,那么您是幸运的。java.time包下的LocalDate、LocalTime、LocalDateTime、Instant基本可以满足要求。当时区不可避免时,ZonedDateTime等类可以满足我们的需求。ZonedDateTime:ISO-8601日历系统时区中的日期时间,例如2007-12-03T10:15:30+01:00Europe/Paris。每个时区对应一个ID,区域ID格式为“{region}/{city}”,例如:Asia/Shanghai等。now():使用系统时间获取当前ZonedDateTimenow(ZoneId):返回指定的时区ZonedDateTimeZoneId:该类包含所有时区信息,一个时区ID,如Europe/ParisgetAvailableZoneIds():静态方法,可以获取所有时区信息(Stringid):静态方法,使用指定的时区信息获取ZoneId对象Clock:使用时区提供对当前时刻、日期和时间的访问的时钟。publicstaticvoidmain(String[]args){Set
