Java 8 日期 - 本地日期、本地日期时间、即时

Java从一开始就缺少了日期和时间的一致方法,Java 8日期时间API是核心Java API的欢迎补充。

为什么我们需要新的Java Date Time API?

在我们开始研究 Java 8 Date Time API 之前,让我们看看为什么我们需要一个新的 API。

  • Java Date Time 类不一致地定义,我们在 java.util 和 java.sql 套件中都有 Date Class. 再次格式化和解析类在 java.text 套件中定义
  • java.util.Date 包含日期和时间值,而 java.sql.Date 仅包含日期值. 在 java.sql 套件中有这种格式化和解析类没有任何意义。 此外,两个类都有相同的名称,这本身就是一个非常糟糕的设计 *没有明确的定义日期和时间格式,格式化和解析等类。 我们有 java.text.DateFormat 抽象类用于解析和格式化。 通常, [Sim

与日期和日历类别中定义的方法存在一些其他问题,但上述问题清楚地表明,在Java中需要一个强大的日期时间API,这就是为什么Joda Time(https://www.joda.org/joda-time/)作为Java日期时间要求的质量替代品发挥了关键作用。

Java 8 日期时间设计原则

Java 8 Date Time API 是 JSR-310的实现,旨在克服传统日期时间实现的所有缺陷。

  1. 联合国 ** Immutable**:新日期-时间 API中的所有课程都是不可改变的,对多线性环境都有好处.
  2. ** 关注分离**:新的API明确区分了人可读的日期时间和机器时间(Unix timestamp). 它定义了日期、时间、日期、时间、时间戳、时区等不同的类别(_) (英语). ** Classary**:方法有明确的定义,在所有类别中执行相同的动作。 例如,为了获得当前实例,我们有_Now()方法。 所有这些类别中都有定义的格式()和剖析()方法,而不是为它们另设一个类别。 () ) 所有班级都使用事实图案战略图案来更好地处理. 一旦您在其中一个班级使用过这些方法, 与其他班级一起工作就不会有困难。 4。 ** 效用作业**: 所有新的 Date-Time API 类都带有执行共同任务的方法,比如加,减,格式,解析,在日期/时间中获得单独的部分等
  3. ** 可扩展**:新的日期时间API在ISO-8601日历系统上工作,但也可以与其他非ISO日历一起使用. ( (英语)

时间 API 包

Java 8 Date Time API 由以下套件组成。

  1. 联合国 java.time: 这是新的Java Date Time API的基础包. 所有主要的基班都是这个包的一部分,如"本地数据"(localDate),"本地时间"(localDate Time),"即时"(Instant),"时段"(perient),"持续"等. 所有这些课程都是不可改变和无线的。 在大多数情况下,这些课程将足以满足共同要求。 ( )2. **java.time.chrono **: . 这个包定义了非ISO日历系统的通用API. 我们可以扩展抽象纪事类来创建自己的日历系统.
  2. java.time.format: 此软件包包含用于格式化和解析日期- 时间对象的类 。 多数时候,我们不会直接使用它们,因为java中的原则课。 时间包提供格式和解析方法.
  3. java.time.timperal: 这个包包含了时间对象,我们可以利用它来找出与日期/时间对象相关的具体日期或时间. 例如,我们可以用这些来发现月份的第一天或最后一天. 您可以轻松识别这些方法,因为它们总是有"与XXX"的格式. (_) (英语). 5. java.time.zone (英语). 软件包: 本套件包含支持不同时区及其规则的类. ( (英语)

Java 8 日期时间 API 类示例

我们已经研究了Java Date Time API中的大多数重要部分,现在是时候用示例研究最重要的Date Time API类。

一、本地化

LocalDate 是一个不可变的类,它代表日期,默认格式为 yyyy-MM-dd. 我们可以使用 now() 方法获取当前日期. 我们还可以为年、月和日期提供输入参数,以创建 LocalDate 实例。

此类为 now() 提供了过载的方法,我们可以通过 ZoneId 获取特定时区的日期,此类提供与 java.sql.Date 相同的功能。

 1package com.journaldev.java8.time;
 2
 3import java.time.LocalDate;
 4import java.time.Month;
 5import java.time.ZoneId;
 6
 7/**
 8 * LocalDate Examples
 9 * @author pankaj
10 *
11 */
12public class LocalDateExample {
13
14    public static void main(String[] args) {
15    	
16    	//Current Date
17    	LocalDate today = LocalDate.now();
18    	System.out.println("Current Date="+today);
19    	
20    	//Creating LocalDate by providing input arguments
21    	LocalDate firstDay_2014 = LocalDate.of(2014, Month.JANUARY, 1);
22    	System.out.println("Specific Date="+firstDay_2014);
23    	
24    	
25    	//Try creating date by providing invalid inputs
26    	//LocalDate feb29_2014 = LocalDate.of(2014, Month.FEBRUARY, 29);
27    	//Exception in thread "main" java.time.DateTimeException: 
28    	//Invalid date 'February 29' as '2014' is not a leap year
29    	
30    	//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
31    	LocalDate todayKolkata = LocalDate.now(ZoneId.of("Asia/Kolkata"));
32    	System.out.println("Current Date in IST="+todayKolkata);
33
34    	//java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
35    	//LocalDate todayIST = LocalDate.now(ZoneId.of("IST"));
36    	
37    	//Getting date from the base date i.e 01/01/1970
38    	LocalDate dateFromBase = LocalDate.ofEpochDay(365);
39    	System.out.println("365th day from base date= "+dateFromBase);
40    	
41    	LocalDate hundredDay2014 = LocalDate.ofYearDay(2014, 100);
42    	System.out.println("100th day of 2014="+hundredDay2014);
43    }
44
45}

LocalDate 方法的解释是在评论中提供的. 当我们运行这个程序时,我们得到以下输出。

1Current Date=2014-04-28
2Specific Date=2014-01-01
3Current Date in IST=2014-04-29
4365th day from base date= 1971-01-01
5100th day of 2014=2014-04-10

2、本地时间

LocalTime 是一个不可变的类,其实例代表人类可读格式中的时间,其默认格式是 hh:mm:ss.zzz. 与 LocalDate 一样,这个类提供时区支持,并通过将小时、分钟和秒作为输入参数来创建实例。

 1package com.journaldev.java8.time;
 2
 3import java.time.LocalTime;
 4import java.time.ZoneId;
 5
 6/**
 7 * LocalTime Examples
 8 * @author pankaj
 9 *
10 */
11public class LocalTimeExample {
12
13    public static void main(String[] args) {
14    	
15    	//Current Time
16    	LocalTime time = LocalTime.now();
17    	System.out.println("Current Time="+time);
18    	
19    	//Creating LocalTime by providing input arguments
20    	LocalTime specificTime = LocalTime.of(12,20,25,40);
21    	System.out.println("Specific Time of Day="+specificTime);
22    	
23    	
24    	//Try creating time by providing invalid inputs
25    	//LocalTime invalidTime = LocalTime.of(25,20);
26    	//Exception in thread "main" java.time.DateTimeException: 
27    	//Invalid value for HourOfDay (valid values 0 - 23): 25
28    	
29    	//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
30    	LocalTime timeKolkata = LocalTime.now(ZoneId.of("Asia/Kolkata"));
31    	System.out.println("Current Time in IST="+timeKolkata);
32
33    	//java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
34    	//LocalTime todayIST = LocalTime.now(ZoneId.of("IST"));
35    	
36    	//Getting date from the base date i.e 01/01/1970
37    	LocalTime specificSecondTime = LocalTime.ofSecondOfDay(10000);
38    	System.out.println("10000th second time= "+specificSecondTime);
39
40    }
41
42}

出发点:**

1Current Time=15:51:45.240
2Specific Time of Day=12:20:25.000000040
3Current Time in IST=04:21:45.276
410000th second time= 02:46:40

第三节 时间

LocalDateTime 是一个不可变的日期时间对象,它代表一个日期时间,默认格式为 yyyy-MM-dd-HH-mm-ss.zzz. 它提供了使用 LocalDate 和 LocalTime 输入参数创建 LocalDateTime 实例的工厂方法。

 1package com.journaldev.java8.time;
 2
 3import java.time.LocalDate;
 4import java.time.LocalDateTime;
 5import java.time.LocalTime;
 6import java.time.Month;
 7import java.time.ZoneId;
 8import java.time.ZoneOffset;
 9
10public class LocalDateTimeExample {
11
12    public static void main(String[] args) {
13    	
14    	//Current Date
15    	LocalDateTime today = LocalDateTime.now();
16    	System.out.println("Current DateTime="+today);
17    	
18    	//Current Date using LocalDate and LocalTime
19    	today = LocalDateTime.of(LocalDate.now(), LocalTime.now());
20    	System.out.println("Current DateTime="+today);
21    	
22    	//Creating LocalDateTime by providing input arguments
23    	LocalDateTime specificDate = LocalDateTime.of(2014, Month.JANUARY, 1, 10, 10, 30);
24    	System.out.println("Specific Date="+specificDate);
25    	
26    	
27    	//Try creating date by providing invalid inputs
28    	//LocalDateTime feb29_2014 = LocalDateTime.of(2014, Month.FEBRUARY, 28, 25,1,1);
29    	//Exception in thread "main" java.time.DateTimeException: 
30    	//Invalid value for HourOfDay (valid values 0 - 23): 25
31
32    	
33    	//Current date in "Asia/Kolkata", you can get it from ZoneId javadoc
34    	LocalDateTime todayKolkata = LocalDateTime.now(ZoneId.of("Asia/Kolkata"));
35    	System.out.println("Current Date in IST="+todayKolkata);
36
37    	//java.time.zone.ZoneRulesException: Unknown time-zone ID: IST
38    	//LocalDateTime todayIST = LocalDateTime.now(ZoneId.of("IST"));
39    	
40    	//Getting date from the base date i.e 01/01/1970
41    	LocalDateTime dateFromBase = LocalDateTime.ofEpochSecond(10000, 0, ZoneOffset.UTC);
42    	System.out.println("10000th second time from 01/01/1970= "+dateFromBase);
43
44    }
45
46}

在这三个例子中,我们已经看到,如果我们为创建日期/时间提供无效的参数,那么它会扔 java.time.DateTimeException,这是一个 RuntimeException,所以我们不需要明确捕捉它。

我们还看到我们可以通过传输ZoneId获取日期/时间数据,您可以从其JavaDoc中获取支持的ZoneId值列表。

1Current DateTime=2014-04-28T16:00:49.455
2Current DateTime=2014-04-28T16:00:49.493
3Specific Date=2014-01-01T10:10:30
4Current Date in IST=2014-04-29T04:30:49.493
510000th second time from 01/01/1970= 1970-01-01T02:46:40

4、瞬间

Instant 类用于使用机器可读时间格式工作. Instant 将日期时间存储在 unix 时刻印中。

 1package com.journaldev.java8.time;
 2
 3import java.time.Duration;
 4import java.time.Instant;
 5
 6public class InstantExample {
 7
 8    public static void main(String[] args) {
 9    	//Current timestamp
10    	Instant timestamp = Instant.now();
11    	System.out.println("Current Timestamp = "+timestamp);
12    	
13    	//Instant from timestamp
14    	Instant specificTime = Instant.ofEpochMilli(timestamp.toEpochMilli());
15    	System.out.println("Specific Time = "+specificTime);
16    	
17    	//Duration example
18    	Duration thirtyDay = Duration.ofDays(30);
19    	System.out.println(thirtyDay);
20    }
21
22}

输出:

1Current Timestamp = 2014-04-28T23:20:08.489Z
2Specific Time = 2014-04-28T23:20:08.489Z
3PT720H

Java 8 日期 API 用途

大多数日期时间原理类提供各种实用方法,如加/减天,周,月,等等 有一些其他实用方法可以使用TemporalAdjuster来调整日期并计算两个日期之间的时间。

 1package com.journaldev.java8.time;
 2
 3import java.time.LocalDate;
 4import java.time.LocalTime;
 5import java.time.Period;
 6import java.time.temporal.TemporalAdjusters;
 7
 8public class DateAPIUtilities {
 9
10    public static void main(String[] args) {
11    	
12    	LocalDate today = LocalDate.now();
13    	
14    	//Get the Year, check if it's leap year
15    	System.out.println("Year "+today.getYear()+" is Leap Year? "+today.isLeapYear());
16    	
17    	//Compare two LocalDate for before and after
18    	System.out.println("Today is before 01/01/2015? "+today.isBefore(LocalDate.of(2015,1,1)));
19    	
20    	//Create LocalDateTime from LocalDate
21    	System.out.println("Current Time="+today.atTime(LocalTime.now()));
22    	
23    	//plus and minus operations
24    	System.out.println("10 days after today will be "+today.plusDays(10));
25    	System.out.println("3 weeks after today will be "+today.plusWeeks(3));
26    	System.out.println("20 months after today will be "+today.plusMonths(20));
27
28    	System.out.println("10 days before today will be "+today.minusDays(10));
29    	System.out.println("3 weeks before today will be "+today.minusWeeks(3));
30    	System.out.println("20 months before today will be "+today.minusMonths(20));
31    	
32    	//Temporal adjusters for adjusting the dates
33    	System.out.println("First date of this month= "+today.with(TemporalAdjusters.firstDayOfMonth()));
34    	LocalDate lastDayOfYear = today.with(TemporalAdjusters.lastDayOfYear());
35    	System.out.println("Last date of this year= "+lastDayOfYear);
36    	
37    	Period period = today.until(lastDayOfYear);
38    	System.out.println("Period Format= "+period);
39    	System.out.println("Months remaining in the year= "+period.getMonths());		
40    }
41}

输出:

 1Year 2014 is Leap Year? false
 2Today is before 01/01/2015? true
 3Current Time=2014-04-28T16:23:53.154
 410 days after today will be 2014-05-08
 53 weeks after today will be 2014-05-19
 620 months after today will be 2015-12-28
 710 days before today will be 2014-04-18
 83 weeks before today will be 2014-04-07
 920 months before today will be 2012-08-28
10First date of this month= 2014-04-01
11Last date of this year= 2014-12-31
12Period Format= P8M3D
13Months remaining in the year= 8

Java 8 日期解析和格式化

很常见地将日期格式格式化为不同的格式,然后对字符串进行解析以获取日期时间对象。

 1package com.journaldev.java8.time;
 2
 3import java.time.Instant;
 4import java.time.LocalDate;
 5import java.time.LocalDateTime;
 6import java.time.format.DateTimeFormatter;
 7
 8public class DateParseFormatExample {
 9
10    public static void main(String[] args) {
11    	
12    	//Format examples
13    	LocalDate date = LocalDate.now();
14    	//default format
15    	System.out.println("Default format of LocalDate="+date);
16    	//specific format
17    	System.out.println(date.format(DateTimeFormatter.ofPattern("d::MMM::uuuu")));
18    	System.out.println(date.format(DateTimeFormatter.BASIC_ISO_DATE));
19    	
20    	
21    	LocalDateTime dateTime = LocalDateTime.now();
22    	//default format
23    	System.out.println("Default format of LocalDateTime="+dateTime);
24    	//specific format
25    	System.out.println(dateTime.format(DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss")));
26    	System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE));
27    	
28    	Instant timestamp = Instant.now();
29    	//default format
30    	System.out.println("Default format of Instant="+timestamp);
31    	
32    	//Parse examples
33    	LocalDateTime dt = LocalDateTime.parse("27::Apr::2014 21::39::48",
34    			DateTimeFormatter.ofPattern("d::MMM::uuuu HH::mm::ss"));
35    	System.out.println("Default format after parsing = "+dt);
36    }
37
38}

输出:

1Default format of LocalDate=2014-04-28
228::Apr::2014
320140428
4Default format of LocalDateTime=2014-04-28T16:25:49.341
528::Apr::2014 16::25::49
620140428
7Default format of Instant=2014-04-28T23:25:49.342Z
8Default format after parsing = 2014-04-27T21:39:48

Java Date API 继承日期时间支持

传统日期/时间类几乎在所有应用中都使用,因此必须具备后向兼容性,这就是为什么我们可以将传统类转换为新类的几个实用方法,反之亦然。

 1package com.journaldev.java8.time;
 2
 3import java.time.Instant;
 4import java.time.LocalDateTime;
 5import java.time.ZoneId;
 6import java.time.ZonedDateTime;
 7import java.util.Calendar;
 8import java.util.Date;
 9import java.util.GregorianCalendar;
10import java.util.TimeZone;
11
12public class DateAPILegacySupport {
13
14    public static void main(String[] args) {
15    	
16    	//Date to Instant
17    	Instant timestamp = new Date().toInstant();
18    	//Now we can convert Instant to LocalDateTime or other similar classes
19    	LocalDateTime date = LocalDateTime.ofInstant(timestamp, 
20    					ZoneId.of(ZoneId.SHORT_IDS.get("PST")));
21    	System.out.println("Date = "+date);
22    	
23    	//Calendar to Instant
24    	Instant time = Calendar.getInstance().toInstant();
25    	System.out.println(time);
26    	//TimeZone to ZoneId
27    	ZoneId defaultZone = TimeZone.getDefault().toZoneId();
28    	System.out.println(defaultZone);
29    	
30    	//ZonedDateTime from specific Calendar
31    	ZonedDateTime gregorianCalendarDateTime = new GregorianCalendar().toZonedDateTime();
32    	System.out.println(gregorianCalendarDateTime);
33    	
34    	//Date API to Legacy classes
35    	Date dt = Date.from(Instant.now());
36    	System.out.println(dt);
37    	
38    	TimeZone tz = TimeZone.getTimeZone(defaultZone);
39    	System.out.println(tz);
40    	
41    	GregorianCalendar gc = GregorianCalendar.from(gregorianCalendarDateTime);
42    	System.out.println(gc);
43    	
44    }
45
46}

输出:

1Date = 2014-04-28T16:28:54.340
22014-04-28T23:28:54.395Z
3America/Los_Angeles
42014-04-28T16:28:54.404-07:00[America/Los_Angeles]
5Mon Apr 28 16:28:54 PDT 2014
6sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
7java.util.GregorianCalendar[time=1398727734404,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2014,MONTH=3,WEEK_OF_YEAR=18,WEEK_OF_MONTH=5,DAY_OF_MONTH=28,DAY_OF_YEAR=118,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=4,HOUR_OF_DAY=16,MINUTE=28,SECOND=54,MILLISECOND=404,ZONE_OFFSET=-28800000,DST_OFFSET=3600000]

正如你可以看到的那样,传统的TimeZoneGregorianCalendar类 toString() 方法过于语而不是用户友好。

结论

我非常喜欢这个新的日期时间API。 一些最常用的类将是LocalDate和LocalDateTime。 很容易与新类一起工作。 并且,使用类似的方法来完成某个特定的工作,很容易找到。

Published At
Categories with 技术
Tagged with
comments powered by Disqus