从Java版本1.0开始就支持日期和时间,主要通过java.util.Date类。 但是,Date类设计不佳。 例如,Date中的月份从1开始,但从日期却从0开始。在JDK 1.1中使用它的许多方法已经废弃,同时java.util.Calendar被引入来接管Date中的一些功能。 这两个是处理日期和时间的主要类,直到JDK 1.7,尽管他们被认为是不足够并且不容易处理,导致许多人诉诸第三方替代品,例如Joda Time(http://[joda.org](http://joda.org))。 JDK 1.8中的新日期和时间API解决了旧API中的许多问题,并且与Joda Time API类似。

这里介绍JDK 1.8中的日期 - 时间的API。

Overview

新的日期和时间API使得使用日期和时间非常容易。java.time包中包含API中的核心类。 另外,还有其他四个包,其成员使用较少:java.time.chronojava.time.formatjava.time.temporaljava.time.zone

java.time包中,Instant类表示时间线上的一个点,通常用于对时间进行操作。 LocalDate类为没有时间和时区部分的日期建模,例如,用于表示生日。

如果你需要日期和时间,那么LocalDateTime就是为你准备的。 例如,订单发货日期可能需要一个日期以外的时间来使订单更容易跟踪。 如果你需要一段时间但不关心日期,那么可以使用LocalTime

如果时区很重要,日期和时间API提供ZonedDateTime类。 顾名思义,这个类表示带有时区日期时间。 例如,你可以使用此类来计算位于不同时区的两个机场之间的飞行时间。

然后有两个类来测量时间总计,即Duration类和Period类。 这两个类是相似的,除了Duration是基于时间,但而Period是基于日期的Duration提供了纳秒精度的时间量。 例如,可以模拟飞行时间,因为它通常以小时数和分钟数表示。 另一方面,如果只关心天数,月数或年数,例如计算一个人的年龄,则Period更为适用。

java.time包也带有两个枚举DayOfWeekMonthDayOfWeek表示从一周的一天,从周一开始到周日。 Month枚举代表这一年的十二个月,从1月到12月。

处理日期和时间通常涉及解析和格式。 日期和时间API通过在所有主要类中提供parseformat方法来解决这两个问题。 另外,java.time.format包含一个用于格式化日期和时间的DateTimeFormatter类。


Instant类

Instant实例表示时间线上的一个点。 参考点是标准的Java纪元(epoch),即1970-01-01T00:00:00Z(1970年1月1日00:00 GMT)。 Instant类的EPOCH属性返回表示Java纪元的Instant`实例。 在纪元之后的时间是正值,而在此之前的时间即是负值。

Instant的静态now方法返回一个表示当前时间的Instant对象:

Instant now = Instant.now();

getEpochSecond方法返回自纪元以来经过的秒数。 getNano方法返回自上一秒开始以来的纳秒数。

Instant类的一个常用用途是用来操作时间,如以下代码所示。

import java.time.Duration;import java.time.Instant;public class InstantDemo1 {public static void main(String[] args) {Instant start = Instant.now();// do something hereInstant end = Instant.now();System.out.println(Duration.between(start, end).toMillis());}}

如上面代码所示,Duration类用于返回两个Instant之间时间数量的差异。


LocalDate类

LocalDate类只包括日期没有时间的部分。 它也没有时区。 下表显示了LocalDate中一些重要的方法。

方法 描述
now 静态方法,返回今天的日期
of  从指定年份,月份和日期创建LocalDate的静态方法
 getDayOfMonth, getMonthValue, getYear  以int形式返回此LocalDate的日,月或年
getMonth  以Month枚举常量返回此LocalDate的月份
 plusDays, minusDays  给LocalDate添加或减去指定的天数
plusWeeks, minusWeeks  给LocalDate添加或减去指定的星期数
plusMonths, minusMonths  给LocalDate添加或减去指定的月份数
 plusYears, minusYears  给LocalDate添加或减去指定的年数
 isLeapYear  检查LocalDate指定的年份是否为闰年
 isAfter, isBefore  检查此LocalDate是在给定日期之后还是之前
 lengthOfMonth  返回此LocalDate中月份的天数
 withDayOfMonth  返回此LocalDate的拷贝,将月份中的某天设置为给定值
 withMonth  返回此LocalDate的拷贝,其月份设置为给定值
 withYear  返回此LocalDate的拷贝,并将年份设置为给定值

LocalDate提供了各种创建日期的方法。 例如,要创建代表今天日期的LocalDate,使用静态now方法。

LocalDate today = LocalDate.now();

要创建代表特定年,月和日的LocalDate,使用of方法,该方法也是静态的。 例如,以下代码创建了一个代表2018年3月7日的LocalDate实例。

LocalDate date = LocalDate.of(2018, 3, 7);

还有一个接受java.time.Month枚举的常量作为第二个参数的of方法。 例如,下面是使用第二种方法重载构造相同日期的代码。

LocalDate date = LocalDate.of(2018, Month.MARCH, 7);

还有获取LocalDate的日,月或年的方法,例如getDayOfMonthgetMonthgetMonthValuegetYear。 他们都没有任何参数,并返回一个int或Month的枚举常量。 另外,还有一个get方法,它接受一个TemporalField并返回这个LocalDate的一部分。 例如,传递ChronoField.YEAR以获取LocalDate的年份部分。

int year = localDate.get(ChronoField.YEAR);

ChronoField是一个实现TemporalField接口的枚举,因此可以传递一个ChronoField常量来获取。 TemporalFieldChronoField都是java.time.temporal包的一部分。 但是,并非ChronoField中的所有常量都可以get获取,因为并非所有常量都受支持。 例如,传递ChronoField.SECOND_OF_DAY以引发异常。 因此,取而代之,最好使用getMonthgetYear或类似方法来获取LocalDate的组件。

此外,还有拷贝LocalDate的方法,例如plusDaysplusYearsminusMonths等等。 例如,要获取表示明天的LocalDate,可以创建一个代表今天的LocalDate,然后调用其plusDays方法。

LocalDate tomorrow = LocalDate.now().plusDays(1);

要获取昨天表示的LocalDate,可以使用minusDays方法。

LocalDate yesterday = LocalDate.now().minusDays(1);

另外,还有plusminus方法以更通用的方式获得LocalDate的拷贝。 两者都接受一个int参数和一个TemporalUnit参数。 这些方法的签名如下。

public LocalDate plus(long amountToAdd,java.time.temporal.TemporalUnit unit)public LocalDate minus(long amountToSubtract,java.time.temporal.TemporalUnit unit)

例如,获得一个从今天开始前20年的LocalDate,可以使用这段代码。

LocalDate pastDate = LocalDate.now().minus(2, ChronoUnit.DECADES);

ChronoUnit是一个实现TemporalUnit的枚举,因此可以将ChronoUnit常量传递给plusminus方法。

LocalDate是不可变的,因此无法更改。 任何返回LocalDate的方法都返回LocalDate的新实例。

以下是使用LocalDate的例子。

import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;public class LocalDateDemo1 {public static void main(String[] args) {LocalDate today = LocalDate.now();LocalDate tomorrow = today.plusDays(1);LocalDate oneDecadeAgo = today.minus(1, ChronoUnit.DECADES);System.out.println("Day of month: " + today.getDayOfMonth());System.out.println("Today is " + today);System.out.println("Tomorrow is " + tomorrow);System.out.println("A decade ago was " + oneDecadeAgo);System.out.println("Year : " + today.get(ChronoField.YEAR));System.out.println("Day of year:" + today.getDayOfYear());}
}

Period类

Period类基于日期的时间数量构建,例如五天,一周或三年。 下面列出了一些重要的方法。

方法 描述
 between  在两个LocalDates之间创建一个Period示例
 ofDays, ofWeeks, ofMonths, ofYears  创建代表给定天数/周/月/年的Period实例
 of  根据给定的年数,月数和天数创建一个Period实例
 getDays, getMonths, getYears  以int形式返回此Period的天数/月/年
isNegative  如果此Period的三个部分中的任何一个为负数,则返回true。 否则返回false
 isZero  如果此Period的所有三个部分均为零,则返回true。 否则,返回false
plusDays, minusDays  在此Period上添加或减去给定的天数
 plusMonths, minusMonths  在此Period上增加或减去给定的月数
 plusYears, minusYears  在此Period增加或减去给定的年数
 withDays  以指定的天数返回此Period的拷贝
 withMonths  以指定的月数返回此Period的拷贝
 withYears  以指定的年数返回此Period的拷贝

创建一个Period很简单,这要感谢between,of,ofDays / ofWeeks / ofMonths / ofYears等静态工厂方法。 例如,以下是如何创建代表两周的Period实例。

Period twoWeeks = Period.ofWeeks(2);

要创建代表一年两个月三天的Period实例,请使用of方法。

Period p = Period.of(1, 2, 3);

要获取某个期间的年/月/日组件,调用其getYears / getMonths / getDays方法。 例如,以下代码中的howManyDays变量的值是14。

Period twoWeeks = Period.ofWeeks(2);int howManyDays = twoWeeks.getDays();

最后,可以使用plusXXXminusXXX方法以及withXXX方法来创建Period的拷贝。 Period是不可变的,所以这些方法返回新的Period实例。

例如,下面的代码显示了一个计算个人年龄的年龄计算器。 它从两个LocalDate创建一个Period并调用它的getDaysgetMonthsgetYears方法。

import java.time.LocalDate;
import java.time.Period;public class PeriodDemo1 {public static void main(String[] args) {LocalDate dateA = LocalDate.of(1978, 8, 26);LocalDate dateB = LocalDate.of(1988, 9, 28);Period period = Period.between(dateA, dateB);System.out.printf("Between %s and %s"+ " there are %d years, %d months"+ " and %d days%n", dateA, dateB,period.getYears(),period.getMonths(),period.getDays());}
}

运行PeriodDemo1类打印下面字符串。

Between 1978-08-26 and 1988-09-28 there are 10 years, 1 months and 2 days

LocalDateTime类

LocalDateTime类是一个没有时区的日期时间的构建。 下表显示了LocalDateTime中一些重要的方法。 这些方法类似于LocalDate的方法,以及用于修改时间部分的一些其他方法,例如在LocalDate中不可用的plusHoursplusMinutesplusSeconds

方法 描述
now  返回当前日期和时间的静态方法。
of  从指定年份,月份,日期,小时,分钟,秒和毫秒创建LocalDateTime的静态方法。
 getYear, getMonthValue, getDayOfMonth, getHour, getMinute, getSecond  以int形式返回此LocalDateTime的年,月,日,小时,分钟或秒部分。
 plusDays, minusDays  给当前LocalDateTime添加或减去指定的天数。
 plusWeeks, minusWeeks  给当前LocalDateTime添加或减去指定的周数。
 plusMonths, minusMonths  给当前LocalDateTime添加或减去指定的月数。
plusYears, minusYears  给当前LocalDateTime添加或减去指定的年数。
 plusHours, minusHours  给当前LocalDateTime添加或减去指定的小时数
 plusMinutes, minusMinutes  给当前LocalDateTime添加或减去指定的分钟数
 plusSeconds, minusSeconds  给当前LocalDateTime添加或减去指定的秒数
 IsAfter, isBefore  检查此LocalDateTime是否在指定的日期时间之后或之前
 withDayOfMonth  返回此LocalDateTime的拷贝,并将月份中的某天设置为指定值
 withMonth, withYear  返回此LocalDateTime的拷贝,其月或年设置为指定值
 withHour, withMinute, withSecond  返回此LocalDateTime的拷贝,其小时/分钟/秒设置为指定值

LocalDateTime提供了各种静态方法来创建日期时间。 该方法现在带有三个重载方法返回当前的日期时间。 无参的方法是最容易使用的:

LocalDateTime now = LocalDateTime.now();

要创建具有特定日期和时间的LocalDateTime,请使用of方法。 此方法有多个重载,并允许传递日期时间或LocalDateLocalTime的单个部分。 以下是一些方法的签名。

public static LocalDateTime of(int year, int month, int dayOfMonth,int hour, int minute)public static LocalDateTime of(int year, int month, int dayOfMonth,int hour, int minute)public static LocalDateTime of(int year, Month month,int dayOfMonth, int hour, int minute)public static LocalDateTime of(int year, Month month,int dayOfMonth, int hour, int minute)public static LocalDateTime of(LocalDate date, LocalTime time)

例如,下面的代码段创建一个LocalDateTime,代表2015年12月31日早上八点。

LocalDateTime endOfYear = LocalDateTime.of(2015, 12, 31, 8, 0);

可以使用plusXXXminusXXX方法创建LocalDateTime的拷贝。 例如,此代码创建一个LocalDateTime,它表示明天的同一时间。

LocalDateTime now = LocalDateTime.now();LocalDateTime sameTimeTomorrow = now.plusHours(24);

Time Zones

互联网数字分配机构(IANA)维护一个可从此网页下载的时区数据库:

[http://www.iana.org/time-zones](http://www.iana.org/time-zones)

但为了便于查看,可以访问此Wikipedia页面:
http://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Java日期和时间API也适用于时区。 抽象类ZoneId(在java.time包中)表示一个区域标识符。 它有一个名为getAvailableZoneIds的静态方法,它返回所有区域标识符。 下面展示了如何使用这种方法打印所有时区的排序列表。

import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;public class TimeZoneDemo1 {public static void main(String[] args) {Set<String> allZoneIds = ZoneId.getAvailableZoneIds();List<String> zoneList = new ArrayList<>(allZoneIds);Collections.sort(zoneList);      for (String zoneId : zoneList) {System.out.println(zoneId);}// alternatively, you can use this line of code to// print a sorted list of zone ids// ZoneId.getAvailableZoneIds().stream().sorted().//        forEach(System.out::println);}
}

getAvailableZoneIds返回字符串的Set集合。 可以使用Collections.sort()或更优雅地通过调用它的stream方法对Set进行排序。 可以编写此代码对区域标识符进行排序。

ZoneId.getAvailableZoneIds().stream().sorted().forEach(System.out::println);

getAvailableZoneIds返回586个区域标识符的Set集合。 以下是上述代码中的一部分区域标识符。

Africa/Cairo
Africa/Johannesburg
America/Chicago
America/Los_Angeles
America/Mexico_City
America/New_York
America/Toronto
Antarctica/South_Pole
Asia/Hong_Kong
Asia/Shanghai
Asia/Tokyo
Australia/Melbourne
Australia/Sydney
Canada/Atlantic
Europe/Amsterdam
Europe/London
Europe/Paris
US/Central
US/Eastern
US/Pacific

ZonedDateTime

ZonedDateTime类以一个时区为日期时间的构建。例如,以下是一个时区的日期时间:

2015-12-31T10:59:59+01:00 Europe/Paris

ZonedDateTime始终是不可变的,时间分量的存储精度为纳秒。

ZonedDateTIme中一些重要方法的使用与LocalDateTime类似,只是多了一个时区的概念。可自行查阅API。

LocalDateTime一样,ZonedDateTime类现在提供静态nowof方法,并构造一个ZonedDateTime实例。 now方法创建一个ZonedDateTime代表执行的日期和时间。 无参now方法会使用计算机的默认时区创建ZonedDateTime

ZonedDateTime now = ZonedDateTime.now();

now的另一个重载方法允许传递区域标识符:

ZonedDateTime parisTime =ZonedDateTime.now(ZoneId.of("Europe/Paris"));

of方法也有好几个重载的方法。在所有情况下,都需要传递区域标识符。 第一个重载方法允许传递时区日期时间的每个部分,从年份到纳秒。

public static ZonedDateTime of(int year, int month, int dayOfMonth,int hour, int minute, int second, int nanosecond,ZoneId zone)

of方法的第二个重载方法需要LocalDateLocalTimeZoneId参数:

public static ZonedDateTime of(LocalDate date, LocalTime time,ZoneId zone)

of方法的最后一个重载方法需要LocalDateTimeZoneId参数。

public static ZonedDateTime of(LocalDateTime datetime, ZoneId zone)

LocalDateLocalDateTime一样,ZonedDateTime提供了使用plusXXXminusXXXwithXXX方法创建实例拷贝的方法。

例如,下面代码行创建一个带默认时区的ZonedDateTime,并调用它的minusDays方法以在三天前创建相同的ZonedDateTime

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime threeDaysEarlier = now.minusDays(3);

Duration

Duration类是基于时间的持续时间的构建。 它与Period类似,不同之处在于Duration的时间分量为纳秒精度,并考虑了ZonedDateTime实例之间的时区。 下表显示了Duration中重要的方法。

方法 描述
between  在两个时差的对象之间创建一个Duration实例,例如在两个LocalDateTime或两个ZonedDateTime之间。
 ofYears, ofMonths, ofWeeks, ofDays, ofHours, ofMinutes, ofSeconds, ofNano  创建给定年数/月/周/天/小时/分钟/秒/纳秒的Duration实例
 of  根据指定数量的时间单位创建Duration实例
 toDays, toHours, toMinutes  以int形式返回此Duration的天数/小时/分钟数
 isNegative  如果此Duration为负,则返回true。 否则返回false。
 isZero  如果此Duration长度为零,则返回true。 否则,返回false
 plusDays, minusDays  在此Duration内添加或减去指定的天数。
 plusMonths, minusMonths  在此Duration内添加或减去指定的月数。
 plusYears, minusYears  在Duration内添加或减去指定的年数
 withSeconds  以指定的秒数返回此Duration的拷贝。

可以通过调用静态方法betweenof来创建Duration。 下面的代码会在2015年1月26日11:10至2015年1月26日12:40之间创建两个LocalDateTimeDuration

import java.time.Duration;
import java.time.LocalDateTime;public class DurationDemo1 {public static void main(String[] args) {LocalDateTime dateTimeA = LocalDateTime.of(2015, 1, 26, 8, 10, 0, 0);LocalDateTime dateTimeB = LocalDateTime.of(2015, 1, 26, 11, 40, 0, 0);Duration duration = Duration.between(dateTimeA, dateTimeB);System.out.printf("There are %d hours and %d minutes.%n",duration.toHours(),duration.toMinutes() % 60);}
}

运行DurationDemo1类的结果是这样的。

There are 3 hours and 30 minutes.

下面的代码在两个ZoneDateTime之间创建一个Duration,具有相同的日期和时间,但时区不同。

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;public class DurationDemo2 {public static void main(String[] args) {ZonedDateTime zdt1 = ZonedDateTime.of(LocalDateTime.of(2015, Month.JANUARY, 1,8, 0),ZoneId.of("America/Denver"));ZonedDateTime zdt2 = ZonedDateTime.of(LocalDateTime.of(2015, Month.JANUARY, 1,8, 0),ZoneId.of("America/Toronto"));Duration duration = Duration.between(zdt1, zdt2);System.out.printf("There are %d hours and %d minutes.%n",duration.toHours(),duration.toMinutes() % 60);}
}

运行DurationDemo2类在控制台上打印如下结果。

There are -2 hours and 0 minutes.

这是预料之中的,因为时区America/DenverAmerica/Toronto之间有两个小时的差异。

作为一个更复杂的例子,下面的代码显示了一个公交车旅行时间计算器。 它有一个方法calculateTravelTime,它需要一个离开的ZonedDateTime实例和一个到达的ZonedDateTime实例。 该代码调用calculateTravelTime方法两次。 这两次公交车都在丹佛早上8点从科罗拉多州丹佛出发,并于多伦多时间第二天早上8点抵达多伦多。 公交车首次于2014年3月8日启程,第二次于2014年3月18日启程。

两种情况下的旅行时间是多少?

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;public class TravelTimeCalculator {public Duration calculateTravelTime(ZonedDateTime departure, ZonedDateTime arrival) {return Duration.between(departure, arrival);}public static void main(String[] args) {TravelTimeCalculator calculator =new TravelTimeCalculator();ZonedDateTime departure1 = ZonedDateTime.of(LocalDateTime.of(2014, Month.MARCH, 8,8, 0),ZoneId.of("America/Denver"));ZonedDateTime arrival1 = ZonedDateTime.of(LocalDateTime.of(2014, Month.MARCH, 9,8, 0),ZoneId.of("America/Toronto"));Duration travelTime1 = calculator.calculateTravelTime(departure1, arrival1);System.out.println("Travel time 1: "+ travelTime1.toHours() + " hours");ZonedDateTime departure2 = ZonedDateTime.of(LocalDateTime.of(2014, Month.MARCH, 18,8, 0),ZoneId.of("America/Denver"));ZonedDateTime arrival2 = ZonedDateTime.of(LocalDateTime.of(2014, Month.MARCH, 19,8, 0),ZoneId.of("America/Toronto"));Duration travelTime2 = calculator.calculateTravelTime(departure2, arrival2);System.out.println("Travel time 2: "+ travelTime2.toHours() + " hours");}
}

运行结果为:

Travel time 1: 21 hoursTravel time 2: 22 hours

为什么有这个区别? 因为2014年的夏令时从3月9日星期日凌晨2点开始。 因此,在2014年3月8日至2014年3月9日之间“失去”了一小时。


Formatting A Date-Time

可以使用java.time.format.DateTimeFormatter格式化本地或时区日期时间。LocalDateLocalDateTimeLocalTimeZoneDateTime类提供具有以下签名的格式方法。

public java.lang.String format(java.time.format.DateTimeFormatterformatter)

很明显,要格式化日期或时间,必须首先创建DateTimeFormatter实例。

下面的代码使用两个格式化实例格式化当前日期。

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;public class DateTimeFormatterDemo1 {public static void main(String[] args) {DateTimeFormatter formatter1 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);LocalDateTime example = LocalDateTime.of(2000, 3, 19, 10, 56, 59);System.out.println("Format 1: " + example.format(formatter1));       DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MMMM dd, yyyy HH:mm:ss");System.out.println("Format 2: " +example.format(formatter2));}
}

运行结果如下:(第一个结果取决于你的区域设置)。

Format 1: 19-Mar-2000 10:56:59 AMFormat 2: March 19, 2000 10:56:59

Parsing A Date-Time

在Java Date和Time API的许多类中有两种parse方法。第一个需要格式化实例,第二个则不需要。后一个方法会根据默认模式解析日期时间。要使用自己的格式化模式,请使用DateTimeFormatter。如果传递的字符串不能被解析,那么解析方法将抛出一个DateTimeParseException

import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Scanner;public class AgeCalculator {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M-d");public Period calculateAge(LocalDate birthday) {LocalDate today = LocalDate.now();return Period.between(birthday, today);}public LocalDate getBirthday() {Scanner scanner = new Scanner(System.in);LocalDate birthday;while (true) {System.out.println("Please enter your birthday "+ "in yyyy-MM-dd format (e.g. 1980-9-28): ");String input = scanner.nextLine();try {birthday = LocalDate.parse(input, formatter);return birthday;} catch(DateTimeParseException e) {System.out.println("Error! Please try again");}}}public static void main(String[] args) {AgeCalculator ageCalculator = new AgeCalculator();LocalDate birthday = ageCalculator.getBirthday();Period age = ageCalculator.calculateAge(birthday);System.out.printf("Today you are %d years, %d months"+ " and %d days old%n",age.getYears(), age.getMonths(), age.getDays());}
}

AgeCalculator类有两个方法,getBirthdaycalculateAgegetBirthday方法使用Scanner类来读取用户输入,并使用DateTimeFormatter类将输入解析到LocalDate中。 getBirthday方法一直请求一个日期,直到用户输入正确格式的日期,在这种情况下,方法返回。 calculateAge方法需要一个生日,并在生日和今天的日期之间创建一个Period实例。

如果运行这个例子,会在控制台上看到这个。

Please enter your birthday in yyyy-MM-dd format (e.g. 1980-9-28):

如果以正确的格式输入日期,则程序将打印计算的年龄,如下所示。

Today you are 79 years, 0 months and 15 days old

Summary

Java 8带来了全新的Date-Time API来替代以java.util.Date类为中心的旧的API。 通过本篇文章,学习如何使用新API中的核心类,如InstantLocalDateLocalDateTimeZonedDateTimePeriodDuration,以及学习如何格式化和解析日期时间。

Java 8 Date-Time API 详解相关推荐

  1. java docur,JavaDoc生成API详解

    一.综述 1.1 简介 Javadoc 是 Java 自带的一种工具,其可以从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档.也就是说,只要在编写程序时以一套特定的标记[Ta ...

  2. java中通物流api详解

    前言:中通一共有2种类型的物流接口,分别是总对总.预约寄件接口.刚开始普通公司都是用我下面这套预约寄件接口的:只有等你寄件数量达到某一个数量就会有中通工作人员联系你切换物流接口,也就是让你用总对总的接 ...

  3. mahout java api_Mahout推荐算法API详解

    前言 用Mahout来构建推荐系统,是一件既简单又困难的事情.简单是因为Mahout完整地封装了"协同过滤"算法,并实现了并行化,提供非常简单的API接口:困难是因为我们不了解算法 ...

  4. java 调用foxmail_JavaMail(JAVA邮件服务) API详解

    5.回复邮件回复邮件的方法很简单:使用Message类的reply()方法,通过配置回复邮件的收件人地址和主题(如果没有提供主题的话,系统将默认将"Re:"作为邮件的主体),这里不 ...

  5. Java8 Date API 详解 - LocalDate,LocalDateTime,Instant

    转载来源:https://www.journaldev.com/2800/java-8-date-localdate-localdatetime-instant Java8 Date API 详解 - ...

  6. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java 8引入 ...

  7. EXT核心API详解(二)-Array/Date/Function/Number/String

    EXT核心API详解(二)-Array/Date/Function/Number/String Array类 indexOf( Object o )  Number object是否在数组中,找不到返 ...

  8. java nio详解,Java NIO API详解

    Java NIO API详解 在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API.对于大多数应用来说,这样的API使用很方 便,然而,一些对 ...

  9. Java 8 Stream API详解

    Java 8 Stream API详解 一.Stream API介绍 Java 8引入了全新的Stream API,此Stream与Java I/O包里的InputStream和OutputStrea ...

  10. Java 11中的新功能和API详解系列1

    Java 11中的新功能和API详解系列1 2018.9.27 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. JDK 11在语言语法方面有一个小改动,增加了相当数量的新API,以及 ...

最新文章

  1. C语言 · 分糖果
  2. Hibernate中通过annotaion配置SQLServer的存储过程
  3. 软件测试实验4白盒测试,软件测试实验报告白盒测试
  4. STM32F407 CubeMx使用定时器测量信号频率 分辨率0.001Hz
  5. [超详细] Apache网页优化:网页压缩与网页缓存超详细
  6. tomcat是什么_为什么开发者放弃了Tomcat,选择了Undertow?
  7. orCAD导入AD库 连不上线 更改元件库 出现Unable To Save Part
  8. Manjaro下Opencv4+CMake安装和编译指南(完整版)
  9. ARCH模型的R语言实现
  10. Android逆向分析——得到SO基址的方法
  11. java调用腾讯云的乐固加固给apk进行加固处理。
  12. 微信公众号主体注销了,如何办理账号迁移?
  13. css记录div渐变背景设置border-radius圆角显示不完整
  14. redis value最大值_Redis value的5种类型及常见操作
  15. matlab读数据写入excel文件路径,MATLAB读取和写入Excel文件
  16. MVG读书笔记——相机模型
  17. 查看某端口的占用情况
  18. 【重识云原生】第六章容器基础6.4.5.3节——Deployment实现原理解析
  19. 计算机组成原理运算器数据,计算机组成原理-运算器实验
  20. 带章节自动化的编号标题文档排版

热门文章

  1. css3属性box-sizing:border-box 用法解析
  2. 微信小程序购物商城系统开发系列-工具篇
  3. 获得WebApi用Post方法获得新增数据的信息
  4. Expressions are not allowed at the top level
  5. smartarm3250 performance
  6. 写一个函数DeleteRange删除单链表中结点的值在low 和high之间的结点
  7. UVA11388GCD LCM
  8. 【Android Protobuf 序列化】Protobuf 服务器与客户端通信 ( TCP 通信中使用 Protobuf )
  9. 【Android 热修复】运行 Tinker 官方示例 ( 处理 TINKER_ID 问题 | 编译 debug 包 | 修改 Gradle 脚本 | 生成 patch 包 | 热修复 )
  10. 【组合数学】递推方程 ( 递推方程示例 1 | 列出递推方程 )