广东网站建站系统哪家好网站建设违法行为
广东网站建站系统哪家好,网站建设违法行为,代刷开通建设网站,广告策划书包括哪些内容转载自 Java 8 日期和时间解读现在#xff0c;一些应用程序仍然在使用java.util.Date和java.util.Calendar API和它们的类库#xff0c;来使我们在生活中更加轻松的处理日期和时间#xff0c;比如#xff1a;JodaTime。然而#xff0c;Java 8 引进的新的类库来处理日期和时…转载自 Java 8 日期和时间解读现在一些应用程序仍然在使用java.util.Date和java.util.Calendar API和它们的类库来使我们在生活中更加轻松的处理日期和时间比如JodaTime。然而Java 8 引进的新的类库来处理日期和时间这可以使我们更加精细的控制时间的表示可以管理不可变的时间对象同时不需要使用其它的类库更加流畅的API在大多数情况下对性能也有很大的提升。下面我们来了解一下Java 8 日期和时间的一些基础知识
LocalDate/LocalTime/LocalDateTime让我们从与 java.util.Date最相关的新的API开始 LocalDate:表示日期不表示时间。 LocalTime:表示时间不表示日期。 LocalDateTime:上面两者的组合。 所有的这些日期和时间表示类型都表示某个区域的日期或者时间。但是就像java.util.Date中的零区域信息一样只是表示当前区域的日期和时间。首先这些API支持一个简单的实例
LocalDate date LocalDate.of(2018,2,13);
// Uses DateTimeformatter.ISOLOCALDATE for which the format is: yyyy-MM-dd
LocalDate date LocalDate.parse(2018-02-13);
LocalTime time LocalTime.of(6,30);
// Uses DateTimeFormatter.ISO_LOCAL_TIME for which the format is: HH:mm[:ss[.SSSSSSSSS]]
// this means that both seconds and nanoseconds may optionally be present.
LocalTime time LocalTime.parse(06:30);LocalDateTime dateTime LocalDateTime.of(2018,2,13,6,30);
// Uses DateTimeFormatter.ISO_LOCAL_DATE_TIME for which the format is the
// combination of the ISO date and time format, joined by T: yyyy-MM-ddTHH:mm[:ss[.SSSSSSSSS]]
LocalDateTime dateTime LocalDateTime.parse(2018-02-13T06:30);在它们之间转换时比较简单的// LocalDate to LocalDateTime
LocalDateTime dateTime LocalDate.parse(2018-02-13).atTime(LocalTime.parse(06:30));// LocalTime to LocalDateTime
LocalDateTime dateTime LocalTime.parse(06:30).atDate(LocalDate.parse(2018-02-13));// LocalDateTime to LocalDate/LocalTime
LocalDate date LocalDateTime.parse(2018-02-13T06:30).toLocalDate();
LocalTime time LocalDateTime.parse(2018-02-13T06:30).toLocalTime();除此之外使用“加”“减”法来进行我们的日期和时间操作像其它公用功能一样简单的难以置信
LocalDate date LocalDate.parse(2018-02-13).plusDays(5);
LocalDate date LocalDate.parse(2018-02-13).plus(3, ChronoUnit.MONTHS);LocalTime time LocalTime.parse(06:30).minusMinutes(30);
LocalTime time LocalTime.parse(06:30).minus(500, ChronoUnit.MILLIS);LocalDateTime dateTime LocalDateTime.parse(2018-02-13T06:30).plus(Duration.ofHours(2));// using TemporalAdjusters, which implements a few useful cases:
LocalDate date LocalDate.parse(2018-02-13).with(TemporalAdjusters.lastDayOfMonth());现在我们该如何从java.util.Date转换到LocalDateTime呢它们又有哪些不同好吧这很简单我们可以把一个时间类型转换为一个实例类型这是从1970年1月1日开始的然后我们可以在当前区域使用这个实例来实例化一个LocalDateTime。
LocalDateTime dateTime LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());为了转换日期我们可以简单的使用java8时间类型的实例。需要注意的一点是虽然LocalDateLocalTime和LocalDateTime不包含任何区域和偏移信息它们代表了一个特定区域的日期和/或时间同样的它们带有该区域的偏移。因此为了正确的将特定类型转换为实例我们需要提供一个偏移。
// represents Wed Feb 28 23:24:43 CET 2018
Date now new Date();// represents 2018-02-28T23:24:43.106
LocalDateTime dateTime LocalDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault());// represent Wed Feb 28 23:24:43 CET 2018
Date date Date.from(dateTime.toInstant(ZoneOffset.ofHours(1)));
Date date Date.from(dateTime.toInstant(ZoneId.systemDefault().getRules().getOffset(dateTime)));
时间差异-持续时间和日期段就像你所注意到的一样在上面的一个例子中我们使用了一个Duration对象。Duration和Period是两个日期之间时间的两种表示方法前者用秒和纳秒来区分时间后者使用年月日。它们应该在哪些情况下使用呢如果你需要知道两个LocalDate表示的时间之间日期段的时候你可以选择使用Period
Period period Period.between(LocalDate.parse(2018-01-18), LocalDate.parse(2018-02-14));当你想要找出两个日期之差即时间间隔的时候你可以选择使用Duration。
Duration duration Duration.between(LocalDateTime.parse(2018-01-18T06:30),LocalDateTime.parse(2018-02-14T22:58));当我们使用toString方法输出Period和Duration的时候将会用到基于ISO-8601标准的一种特定格式。Period的模式是PnYnMnD日期中n定义了当前的年月日。P1Y2D3意思就是1年2个月3天。模式中的‘P’表示日期标识符它告诉我们接下来的格式表示的是日期。使用这种模式我们同样可以创建一个基于使用parse方法的string的日期。
// represents a period of 27 days
Period period Period.parse(P27D);使用Duration的时候我们稍微偏离了ISO-8601标准因为Java8不使用同样的模式。ISO-8601定义的模式是PnYnMnDTnHnMn.nS它是建立在Period的模式基础上并对其进行了拓展的一种时间表示。在这个模式中T是时间标识符所以它后面定义的是时分秒。Java8中Duration使用了两种模式当把一个String解析为一个Duration的时候使用PnDTnHnMn.nS模式当在一个Duration实例中调用toString方法的时候使用PTnHnMn.nS模式。最后同样重要的是我们可以使用相应的方法类型来检索一个时期或者时间中的任何一部分。各种类型的日期时间通过使用ChronoUnit枚举类型也同样支持。让我们来看下面的例子
// represents PT664H28M
Duration duration Duration.between(LocalDateTime.parse(2018-01-18T06:30),LocalDateTime.parse(2018-02-14T22:58));// returns 664
long hours duration.toHours();// returns 664
long hours LocalDateTime.parse(2018-01-18T06:30).until(LocalDateTime.parse(2018-02-14T22:58),ChronoUnit.HOURS);
时区时间和偏移时间到目前为止我们已经展示了新日期时间API如何使事情变的更加简单。但是真正不同的是在时区环境下更加简单的使用日期和时间。Java8为我们提供了ZonedDateTime和OffsetDateTime前者是LocalDateTime针对特定区域例如法国/巴黎的信息后者LocalDateTime的偏移。两者有什么不同呢OffsetDateTime使用UTC/格林威治和制定日期之间的固定时差ZonedDateTime制定了表示时间的区域并且考虑到了夏令时。转换为这些类型是很简单的
OffsetDateTime offsetDateTime LocalDateTime.parse(2018-02-14T06:30).atOffset(ZoneOffset.ofHours(2));
// Uses DateTimeFormatter.ISO_OFFSET_DATE_TIME for which the default format is
// ISO_LOCAL_DATE_TIME followed by the offset (HH:mm:ss).
OffsetDateTime offsetDateTime OffsetDateTime.parse(2018-02-14T06:3006:00);ZonedDateTime zonedDateTime LocalDateTime.parse(2018-02-14T06:30).atZone(ZoneId.of(Europe/Paris));
// Uses DateTimeFormatter.ISO_ZONED_DATE_TIME for which the default format is
// ISO_OFFSET_DATE_TIME followed by the the ZoneId in square brackets.
ZonedDateTime zonedDateTime ZonedDateTime.parse(2018-02-14T06:3008:00[Asia/Macau]);
// note that the offset does not matter in this case.
// The following example will also return an offset of 08:00
ZonedDateTime zonedDateTime ZonedDateTime.parse(2018-02-14T06:3006:00[Asia/Macau]);当在它们之间转换的时候你必须要记住把ZoneDateTime转换为OffsetDateTime的时候需要考虑到夏令时反而言之当把OffsetDateTime转换为ZonedDateTime的时候意味着你将不会获得区域的信息也不适用夏令时的规则。应为偏移没有定义任何时区规则也不会绑定到任何区域。
ZonedDateTime winter LocalDateTime.parse(2018-01-14T06:30).atZone(ZoneId.of(Europe/Paris));
ZonedDateTime summer LocalDateTime.parse(2018-08-14T06:30).atZone(ZoneId.of(Europe/Paris));// offset will be 01:00
OffsetDateTime offsetDateTime winter.toOffsetDateTime();
// offset will be 02:00
OffsetDateTime offsetDateTime summer.toOffsetDateTime();OffsetDateTime offsetDateTime zonedDateTime.toOffsetDateTime();OffsetDateTime offsetDateTime LocalDateTime.parse(2018-02-14T06:30).atOffset(ZoneOffset.ofHours(5));
ZonedDateTime zonedDateTime offsetDateTime.toZonedDateTime();现在如果我们想要知道相对于我们所在时区特定区域的时间和偏移量该怎么办这里同样定义了一些方便的功能
// timeInMacau represents 2018-02-14T13:3008:00[Asia/Macau]
ZonedDateTime timeInMacau LocalDateTime.parse( 2018-02-14T13:30 ).atZone( ZoneId.of( Asia/Macau ) );
// timeInParis represents 2018-02-14T06:3001:00[Europe/Paris]
ZonedDateTime timeInParis timeInMacau.withZoneSameInstant( ZoneId.of( Europe/Paris ) );OffsetDateTime offsetInMacau LocalDateTime.parse( 2018-02-14T13:30 ).atOffset( ZoneOffset.ofHours( 8 ) );
OffsetDateTime offsetInParis offsetInMacau.withOffsetSameInstant( ZoneOffset.ofHours( 1 ) );如果在任何时候你都必须手动在两种类型之间转换的话将会很麻烦。在这方面Spring Framework给我们提供了帮助。Spring为我们提供了一些开箱即用的日期时间转换器这些转换器注册在ConversionRegistry在org.springframework.format.datetime.standard.DateTimeConverters类中可以找到。这使用这些转换器的时候重要的是要知道在区域和偏移之间是不会转换的。比如说ZonedDateTimeToLocalDateTimeConverter将会返回它所指定的区域的LocalDateTime而不是你应用程序中所代表的。
ZonedDateTime zonedDateTime LocalDateTime.parse(2018-01-14T06:30).atZone(ZoneId.of(Asia/Macau));
// will represent 2018-01-14T06:30, regardless of the region your application has specified
LocalDateTime localDateTime conversionService.convert(zonedDateTime, LocalDateTime.class);最后重要的是你可以检索ZonId.getAvailableZoneIds来查找所有可用的时区或者使用ZoneId.SHORT_IDS,它包含了一些简写版本的时区例如EST,CST等等。
格式化—使用DateTimeFormatter当然世界上不同的区域使用不同的格式来指定时间。一个应用程序可能使用MM-dd-yyyy另一个可能会使用dd/MM/yyyy.一些应用程序想要解决这些不一致的格式统一用yyyy-MM-dd来表示日期。使用java.util.Date的时候我们很快的就会转向使用多个格式化器。但是DateTimeFormatter类为我们提供了操作模式使我们可以使用单一的格式化器来处理多种格式让我们通过一些例子来看一下。
// Let’s say we want to convert all of patterns mentioned above.
// 09-23-2018, 23/09/2018 and 2018-09-23 should all convert to the same LocalDate.
DateTimeFormatter formatter DateTimeFormatter.ofPattern([yyyy-MM-dd][dd/MM/yyyy][MM-dd-yyyy]);
LocalDate.parse(09-23-2018, formatter);
LocalDate.parse(23/09/2018, formatter);
LocalDate.parse(2018-09-23, formatter);方括号中的内容定义了模式中的可操作部分通过使我们的各种格式可选匹配string的第一个模式将会被用来转换我们表示的日期。当我们使用混合模式的时候阅读起来将会非常困难所以让我们使用builder模式来创建我们的DateTimeFormatter。
DateTimeFormatter formatter new DateTimeFormatterBuilder().appendOptional( DateTimeFormatter.ofPattern( yyyy-MM-dd ) ).optionalStart().appendPattern( dd/MM/yyyy ).optionalEnd().optionalStart().appendPattern( MM-dd-yyyy ).optionalEnd().toFormatter();这些是包含多种模式的基础知识但是如果我们的模式仅仅是略有不同该怎么办呢让我们来看一下yyy-MM-dd和yyyy-MMM-dd。
// 2018-09-23 and 2018-Sep-23 should convert to the same LocalDate.
// Using the ofPattern example we’ve used above will work:
DateTimeFormatter formatter DateTimeFormatter.ofPattern([yyyy-MM-dd][yyyy-MMM-dd] );
LocalDate.parse( 2018-09-23, formatter );
LocalDate.parse( 2018-Sep-23, formatter );// Using the ofPattern example where we reuse the common part of the pattern
DateTimeFormatter formatter DateTimeFormatter.ofPattern( yyyy-[MM-dd][MMM-dd] );
LocalDate.parse( 2018-09-23, formatter );
LocalDate.parse( 2018-Sep-23, formatter );但是当转换为String的时候不可以使用支持多种格式的格式化器因为当我们使用格式化器把我们的日期转换为string表示的时候它也将使用可选模式。
LocalDate date LocalDate.parse(2018-09-23);
// will result in 2018-09-232018-Sep-23
date.format(DateTimeFormatter.ofPattern([yyyy-MM-dd][yyyy-MMM-dd] ));
// will result in 2018-09-23Sep-23
date.format(DateTimeFormatter.ofPattern( yyyy-[MM-dd][MMM-dd] ));21世纪以来很明显的我们必须要考虑到全球化所以我们想要为我们的用户提供本地化的日期。为了确保你的DateTimeFormatter返回一个指定的本地日期你可以简单的做以下一些工作
DateTimeFormatter formatter DateTimeFormatter.ofPattern( EEEE, MMM dd, yyyy ).withLocale(Locale.UK);DateTimeFormatter formatter new DateTimeFormatterBuilder().appendPattern(yyyy-MMM-dd ).toFormatter(Locale.UK);可以使用Locale.getAvailableLocales()方法来找出可用的区域设置。现在你接受到日期模式可能比你使用的带有更多的信息。一旦提供的日期表示不符合模式DateTimeFormatter就会抛出异常。让我们更进一步的来探讨这个问题及其处理方法。
// The issue: this will throw an exception.
LocalDate date LocalDate.parse(2018-02-15T13:45);
// We provide a DateTimeFormatter that can parse the given date representation.
// The result will be a LocalDate holding 2018-02-15.
LocalDate date LocalDate.parse(2018-02-15T13:45, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
让我们来创建一个可以处理ISO日期、时间和日期时间模式的格式化器。
DateTimeFormatter formatter new DateTimeFormatterBuilder().appendOptional( DateTimeFormatter.ISO_LOCAL_DATE ).optionalStart().appendLiteral( T ).optionalEnd().appendOptional( DateTimeFormatter.ISO_LOCAL_TIME ).toFormatter();现在我们可以完美的执行以下内容
// results in 2018-03-16
LocalDate date LocalDate.parse( 2018-03-16T06:30, formatter );
LocalDate date LocalDate.parse( 2018-03-16, formatter );
// results in 06:30
LocalTime time LocalTime.parse( 2018-03-16T06:30, formatter );
LocalTime time LocalTime.parse( 06:30, formatter );
LocalDateTime localDateTime LocalDateTime.parse( 2018-03-16T06:30, formatter );下一个问题是什么呢如果您试图解析LocalDateTime的日期模式该怎么办?反之如果您期望通过一个日期表示得到一个LocalTime该怎么办
// will throw an exception
LocalDateTime localDateTime LocalDateTime.parse(2018-03-16, formatter);
LocalDate localDate LocalDate.parse(06:30, formatter);最后的这两个问题并没有单一的正确解决方法但是它依据你需要什么或者是这些日期和时间表示的是什么或者可以表示什么这种魔法般的方法可以在TemporalQuery的使用中找到你也可以使用TemporalQuery为模式的一部分来创建缺省值。如果我们开始使用的是LocalDateTime但是你只是想要一个LocalTime或者是一个LocalTime,你将会接受到LocalDateTime的对应部分。为了创建一个LocalDateTime我们需要它所持有的日期和时间的默认值。日入说如果你没有提供日期的信息我们将会得到一个当前日期的返回值如果你没有提供时间信息我么会认为这是一天的起始。由于我们正在返回一个LocalDateTime它不会被解析为一个LocalDate或者是LocalTime所以让我们使用ConversionService来得到 一个正确的格式。
TemporalQueryTemporalAccessor myCustomQuery new MyCustomTemporalQuery();
// results in 2018-03-16
LocalDateTime localDateTime conversionService.convert( formatter.parse( 2018-03-16, myCustomQuery ), LocalDateTime.class );
// results in 00:00
LocalTime localTime conversionService.convert( formatter.parse( 2018-03-16, myCustomQuery ), LocalTime.class );class MyCustomTemporalQuery implements TemporalQueryTemporalAccessor
{Overridepublic TemporalAccessor queryFrom( TemporalAccessor temporal ) {LocalDate date temporal.isSupported( ChronoField.EPOCH_DAY )? LocalDate.ofEpochDay( temporal.getLong( ChronoField.EPOCH_DAY ) ) : LocalDate.now();LocalTime time temporal.isSupported( ChronoField.NANO_OF_DAY )? LocalTime.ofNanoOfDay( temporal.getLong( ChronoField.NANO_OF_DAY ) ) : LocalTime.MIN;return LocalDateTime.of( date, time );}
}
使用TemporalQuery我们可以检查哪些信息是当前的并且可以为许多丢失的信息提供缺省值这使我们可以很简单的在我们的应用程序中使用合理的逻辑转换为我们所需要的类型。
结论
大多数新功能都需要时间来理解和习惯Java8 Date/Time API也不例外。新的API为我们提供了访问所需要的更好的正确格式为我们提供了使用日期时间操作的更加标准、更具可读性的方式。使用这些技巧和窍门我们几乎可以涵盖我们所有的用例。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91918.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!