企业免费做网站,h5游戏网站开发,简单网站建设软件有哪些方面,低代码平台开发一#xff1a;时间日期API的演进#xff0c;及存在的问题 
JDK 1.0 时期#xff1a; 
对于日期和时间的支持只能依赖于java.util.Date类。它的最小精度是毫秒起始年份为1900年#xff0c;起始月份为0。20180822表示为new Date (118,7,22)返回值使用JVM默认时区#xff1a;…一时间日期API的演进及存在的问题 
JDK 1.0 时期 
对于日期和时间的支持只能依赖于java.util.Date类。它的最小精度是毫秒起始年份为1900年起始月份为0。20180822表示为new Date (118,7,22)返回值使用JVM默认时区CST。但是并不支持时区 
JDK 1.1 时期 
废弃了java.util.Date的一些方法转而用java.util.Calendar替代Calendar的起始月份依旧是0格式化及解析时间使用DateFormat方法非线程安全Date、Calendar类都是可变的 
JDK 1.8 时期 Java 8在java.time包中整合了很多Joda-Time的特性使得API更加好用。API主要包含类 LocalDate、LocalTime、Instant、Duration和Period 
二新的日期时间API 
LocalDate、LocalTime、Instant、Duration和Period 
LocalDate日期 该类的实例是一个不可变对象它只提供简单的日期不包含当天的时间也不包含时区相关信息。可以使用静态工厂创建LocalDate实例。 
LocalDate常见用法 LocalDate date  LocalDate.of(2019, 4, 10);System.out.println(date.getYear());//2019System.out.println(date.getMonthValue());//4System.out.println(date.getDayOfYear());//100System.out.println(date.getDayOfMonth());//10System.out.println(date.getDayOfWeek());//WEDNESDAYSystem.out.println(date.isLeapYear());//falseSystem.out.println(date.lengthOfMonth());//30System.out.println(date.lengthOfYear());//365System.out.println(LocalDate.now().atStartOfDay());//2019-04-10T00:00LocalTime时间 
与LocalDate类似LocalTime表示时间同样可以使用of方法创建LocalTime实例。 另外LocalDate、LocalTime都支持从字符串创建 
//LocalDate、LocalTime都是final的
LocalDatelocalDate  LocalDate.parse(2019-04-10);
LocalTime localTime  LocalTime.parse(10:48:33);LocalTime localTime2  LocalTime.of(10, 48, 33);
System.out.println(localTime2.getHour());//10
System.out.println(localTime2.getMinute());//48
System.out.println(localTime2.getSecond());//33
System.out.println(localTime2.getNano());//当前LocalTime的秒的纳秒数0LocalDateTime日期和时间 System.out.println(LocalDateTime.now());//2019-04-10T11:00:05.627System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.now()));//2019-04-10T11:00:05.628System.out.println(LocalDateTime.parse(2019-04-10T10:58:01));//2019-04-10T10:58:01System.out.println(LocalDateTime.of(2019, 4, 10, 10, 58, 00, 19999));//2019-04-10T10:58:00.000019999//可以把LocalDateTime拆分为LocalDate和LocalTimeLocalDateTime l1  LocalDateTime.now();System.out.println(l1.toLocalDate());//2019-04-10System.out.println(l1.toLocalTime());//11:02:34.827Instant机器的日期和时间 Instant设计初衷是便于机器使用包含的是秒及纳秒所组成的数字。所以一般编程不会用到此API。 java.time.Instant类对时间的建模方式是以Unix元年时间UTC时区1970-01-01 00:0000开始进行计算 
System.out.println(Instant.ofEpochMilli(763883333l));//1970-01-09T20:11:23.333Z//参数1秒参数2纳秒参数2对参数1进行调整System.out.println(Instant.ofEpochSecond(1, 8999999999999999999l));//2255-03-14T16:00:00.999999999ZDuration、Period时间段 
由于LocalDateTime和Instant是为不同的目的而设计的一个是为了人阅读的一个是为了机器处理的所以不能将二者混用。此外由于Duration类主要用于以秒和纳秒衡量时间的长短所以不能向between方法传递LocalDate 
Duration和Period类都提供了很多非常方便的工厂类直接创建对应的实例 
//计算日期时间差使用这两个类
LocalDateTime l1  LocalDateTime.parse(2019-04-01T15:10:10);
LocalDateTime l2  LocalDateTime.now();//2019-04-10T11:40:10
System.out.println(Duration.between(l1, l2).toDays());//8
System.out.println(Period.between(l1.toLocalDate(), l2.toLocalDate()).getDays());//9Duration threeMinutes  Duration.ofMinutes(3);
Duration threeMinutes  Duration.of(3, ChronoUnit.MINUTES);Period tenDays  Period.ofDays(10);
Period threeWeeks   Period.ofWeeks(3);
Period twoYearsSixMothsOneDay  Period.of(2,6,1); 
操作、解析和格式化日期 
LocalDate l1  LocalDate.of(2019, 4, 10);
LocalDate l2  l1.withYear(2020);
LocalDate l3  l2.withMonth(5);
LocalDate l4  l3.withDayOfMonth(20);
System.out.println(l1);//2019-04-10,with方法会创建对象的副本,原对象不变
System.out.println(l4);//2020-05-20像LocalDate、LocalTime、LocalDateTime以及Instant这些表示日期和时间的类提供了大量的通用方法 1、from 静态方法 依据传入的Temporal对象创建是实例 
2、now 静态方法 依据系统时钟创建Temporal对象 
3、of 静态方法 由Temporal对象的某个部分创建对象的实例 
4、 parse 静态方法 由字符串创建Temporal对象的实例 
5、atOffset 将Temporal对象和某个时区偏移相结合 
6、atZone 将Temporal 对象和某个时区相结合 
7、format 使用某个指定的格式将Temporal对象转换为字符串Instant类不提供此方法 
8、get 读取Temporal对象的某一部分的值 
9、minus 创建对象的一个副本然后将当前的Temporal对象的值减去一定的时长创建该副本 
10、plus 创建对象的一个副本然后将当前Temporal对象的值加上一定的时长创建该副本 
11、with 以该对象为模板对某些状态进行修改创建该对象的副本。 
TemporalAdjuster精细化操作 
操纵更复杂的日期比如将日期调整到下个周日、下个工作日或者是本月的最后一天。这时可以使用with的重载版本向其传递一个提供了更多定制化选择的TemporalAdjuster对象更加灵活的处理日期。 
import static java.time.temporal.TemporalAdjusters.*;LocalDate dd  LocalDate.of(2018,8,23);LocalDate dd1  dd.with(dayOfWeekInMonth(2,DayOfWeek.FRIDAY)); //同一个月中第二个星期五 2018-08-10LocalDate dd2  dd.with(firstDayOfMonth()); //当月的第一天 2018-08-01
LocalDate dd3  dd.with(firstDayOfNextMonth()); //下月的第一天 2018-09-01
LocalDate dd4  dd.with(firstDayOfNextYear()); //明年的第一天 2019-01-01
LocalDate dd5  dd.with(firstDayOfYear()); //当年的第一天 2018-01-01
LocalDate dd6  dd.with(firstInMonth(DayOfWeek.MONDAY)); //当月第一个星期一 2018-08-06LocalDate dd7  dd.with(lastDayOfMonth()); //当月的最后一天 2018-08-31
LocalDate dd8  dd.with(lastDayOfYear()); //当年的最后一天 2018-12-31
LocalDate dd9  dd.with(lastInMonth(DayOfWeek.SUNDAY)); //当月最后一个星期日 2018-08-26LocalDate dd10  dd.with(previous(DayOfWeek.MONDAY)); //将日期向前调整到第一个符合星期一 2018-08-20
LocalDate dd11  dd.with(next(DayOfWeek.MONDAY)); //将日期向后调整到第一个符合星期一 2018-08-27LocalDate dd12  dd.with(previousOrSame(DayOfWeek.FRIDAY)); //将日期向前调整第一个符合星期五如果该日期已经符合直接返回该对象 2018-08-17
LocalDate dd13  dd.with(nextOrSame(DayOfWeek.FRIDAY)); //将日期向后调整第一个符合星期五如果该日期已经符合直接返回该对象 2018-08-24打印输出及解析日期 
处理日期和时间对象时格式化以及解析日期-时间对象是另一个非常重要的功能。新的java.time.format包就是为了这个目的而设计的。这个包中最重要的类是DateTimeFormatter创建格式器最简单的方式是通过他的静态工厂方法及常量。 
String s1  next.format(DateTimeFormatter.BASIC_ISO_DATE); //20180824
String s2  next.format(DateTimeFormatter.ISO_LOCAL_DATE); //2018-08-24 
除了解析为字符串外还可以通过解析代表日期或时间的字符串重新创建该日期对象。 
LocalDate date1  LocalDate.parse(20180901,DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2  LocalDate.parse(2018-09-02,DateTimeFormatter.ISO_LOCAL_DATE); 
与老的java.util.DateFormat想比较所有的DateTimeFormatter实例都是线程安全的。DateTimeFormatter类还支持一个静态工厂方法它按照某个特定的模式创建格式器。 
DateTimeFormatter formatter  DateTimeFormatter.ofPattern(dd/MM/yyyy);
LocalDate now  LocalDate.now();
String formatterDate  now.format(formatter);
LocalDate nowparse  LocalDate.parse(formatterDate,formatter); 
ofPattern可以按照指定的格式进行解析成字符串然后又调用了parse方法的重载 将该格式的字符串转换成了 LocalDate对象。 ofPattern也提供了重载版本使用它可以创建某个Locale的格式器 
DateTimeFormatter formatter2  DateTimeFormatter.ofPattern(yyyy年MMMMd号, Locale.CHINA);
LocalDate chinaDate  LocalDate.parse(2018-08-21);
String formatterDate2  chinaDate.format(formatter2); //2018年八月21号
LocalDate chinaDate2  LocalDate.parse(formatterDate2,formatter2);DateFormatterBuilder类还提供了更复杂的格式器和更强大的解析功能 
DateTimeFormatter chinaFormatter  new DateTimeFormatterBuilder().appendText(ChronoField.YEAR).appendLiteral(年).appendText(ChronoField.MONTH_OF_YEAR).appendText(ChronoField.DAY_OF_MONTH).appendLiteral(号).parseCaseInsensitive().toFormatter(Locale.CHINA);处理不同的时区和历法 之前所看到的日期和时间种类都不包含时区信息。时区的处理是新版日期和时间API新增加的重要功能新的 java.time.ZoneId 类是老版 java.util.TimeZone 的替代品。 
时区是按照一定的规则将区域划分成的标准时间相同的区间。在ZoneRules这个类中包含了40个这样的实例。你可以使用ZoneId的getRules()得到指定时区的规则。每个特定的ZoneId对象都由一个地区标识 
ZoneId romeZone  ZoneId.of(Europe/Rome); //格式 欧洲/罗马 
地区ID都为 “{区域}/{城市}”的格式这些地区集合的设定都由英特网编号分配机构IANA的时区数据库提供。你可以通过java 8的新方法toZoneId将一个老的时区对象转换为ZoneId 
ZoneId zoneId  TimeZone.getDefault().toZoneId(); 
一旦得到一个ZoneId对象就可以将它与LocalDate、LocalDateTIme或者是Instant对象整合起来构造为一个ZonedDateTime实例它代表了相对于指定时区的时间点 
LocalDate date  LocalDate.of(2018,8,22);
ZonedDateTime zdt1  date.atStartOfDay(romeZone);LocalDateTime dateTime  LocalDateTime.of(2018,8,23,13,48,00);
ZonedDateTime zdt2  dateTime.atZone(romeZone);Instant instant  Instant.now();
ZonedDateTime zdt3  instant.atZone(romeZone); 
ZonedDateTime  LocalDateTime(LocalDate  LocalTime)  ZoneId 
通过ZoneId你还可以将LocalDateTime转换为Instant 
LocalDateTime dateTime  LocalDateTime.of(2018,8,23,13,48,00);
Instant instantFromDateTime  dateTime.toInstant(romeZone);Instant instant1  Instant.now();
LocalDateTime timeFromInstant  LocalDateTime.ofInstant(romeZone); 
利用和 UTC/格林尼治时间的固定偏差计算时区 
另一种比较常用的表达时区的方式就是利用当前时区和 UTC/格林尼治 的固定偏差比如纽约落后伦敦5小时。这种情况下你可以使用ZoneOffset类它是ZoneId的一个子类表示的是当前时间和伦敦格林尼治子午时间的差异 
ZoneOffset newYorkOffset  ZoneOffset.of(-05:00); 
这种方式不推荐使用因为 -0500 的偏差实际上是对应的美国东部标准时间并未考虑任何日光时的影响。 
LocalDateTime dateTime1  LocalDateTime.now();
OffsetDateTime dateTimeInNewYork1  OffsetDateTime.of(dateTime1,newYorkOffset);它使用ISO-8601的历法系统以相对于UTC时间的偏差方式表示日期时间。 
使用别的日历系统 
ISO-8601日历系统是世界文明日历系统的事实标准。但是java 8 中另外提供了4种其他的日历系统。这些日历系统中的每一个都有一个对应的日志类分别是ThaiBuddhistDate、MinguoDate、JapaneseDate以及HijrahDate。所有这些类以及LocalDate都实现了ChronoLocalDate接口能够对公历的日期进行建模。利用LocalDate对象可以创建这些类的实例。 
小结 
Java 8之前的java.util.Date类以及其他用于建模日期时间的雷有很多不一致及设计上的缺陷包括易变性以及糟糕的偏移值、默认值和命名新版的日期和时间API中日期-时间对象是不可变的操纵的日期不会影响老值而是新生成一个实例新的API提供了两种不同的时间表示方式有效地区分了运行时人和机器的不同需求TemporalAdjuster可以更精确的操纵日期还可以自定义日期转换器他们都是线程安全的 
参考 新API的用法 https://www.cnblogs.com/baidawei/p/9519747.html https://blog.csdn.net/zsx157326/article/details/80887673 https://blog.csdn.net/w592376568/article/details/80408742 
旧API https://blog.csdn.net/quxing10086/article/details/80032713 https://www.cnblogs.com/CSU-PL/p/4430787.html