Java8 日期和时间API
localdate、localtime、instant、duration、period
1.1使用localdate和localtime
1.1.1localdate的创建方式和相关方法使用示例
@test public void localdate() { localdate date = localdate.of(2019, 11, 1); int year = date.getyear();// 2019 month month = date.getmonth();// november int day = date.getdayofmonth();// 1 dayofweek dow = date.getdayofweek();// friday int len = date.lengthofmonth();// 30 boolean leap = date.isleapyear();// false system.out.println(year + ", " + month + ", " + day + ", " + dow + ", " + len + ", " + leap); localdate date2 = localdate.now(); int year2 = date2.get(chronofield.year);//2019 int month2 = date2.get(chronofield.month_of_year);// 12 int day2 = date2.get(chronofield.day_of_month);// 14 int dow2 = date2.get(chronofield.day_of_week);// 6 system.out.println(year2 + ", " + month2 + ", " + day2 + ", " + dow2); //不可以写成2019-11-1 会报datetimeparseexception localdate date3 = localdate.parse("2019-11-01"); int year3 = date3.get(chronofield.year);//2019 int month3 = date3.get(chronofield.month_of_year);// 11 int day3 = date3.get(chronofield.day_of_month);// 1 int dow3 = date3.get(chronofield.day_of_week);// 5 system.out.println(year3 + ", " + month3 + ", " + day3 + ", " + dow3); }
1.1.1localtime对象的创建方式以及相关方法示例
@test public void localtime() { localtime time = localtime.of(11, 06, 23); int hour = time.gethour(); int minute = time.getminute(); int second = time.getsecond(); system.out.println(hour + ":" + minute + ":" + second);// 11:6:23 localtime time2 = localtime.now(); int hour2 = time2.get(chronofield.hour_of_day); int minute2 = time2.get(chronofield.minute_of_hour); int second2 = time2.get(chronofield.second_of_minute); system.out.println(hour2 + ":" + minute2 + ":" + second2);//当前时间 // 写13:9:22会报错,datetimeparseexception异常,可以传一个datetimeformatter自定义格式 localtime time3 = localtime.parse("13:09:22"); int hour3 = time3.get(chronofield.hour_of_day); int minute3 = time3.get(chronofield.minute_of_hour); int second3 = time3.get(chronofield.second_of_minute); system.out.println(hour3 + ":" + minute3 + ":" + second3);// 13:9:22 }
1.1.3localdatetime对象3种创建方式以及相关方法示例
test public void localdatetime() { localdate date = localdate.now(); localtime time = localtime.now(); // 创建localdatetime localdatetime datetime = localdatetime.of(2019, 11, 1, 13, 32, 28); localdatetime datetime2 = localdatetime.of(date, time); localdatetime datetime3 = date.attime(13, 32, 28); localdatetime datetime4 = date.attime(time); localdatetime datetime6 = time.atdate(date); // 转化 localdate date2 = datetime2.tolocaldate(); localtime time2 = datetime2.tolocaltime(); }
1.1.4 机器的日期和时间格式
你可以通过向静态工厂方法ofepochsecond传递一个代表秒数的值创建一个该类的实例。静态工厂方法ofepochsecond还有一个增强的重载版本,它接收第二个以纳秒为单位的参数值,对传入作为秒数的参数进行调整。重载的版本会调整纳秒参数,确保保存的纳秒分片在0到999 999999之间。这意味着下面这些对ofepochsecond工厂方法的调用会返回几乎同样的instant对象:
instant.ofepochsecond(3); instant.ofepochsecond(3, 0); // 2 秒之后再加上100万纳秒(1秒) instant.ofepochsecond(2, 1_000_000_000); // 4秒之前的100万纳秒(1秒) instant.ofepochsecond(4, -1_000_000_000);
正如你已经在localdate及其他为便于阅读而设计的日期-时间类中所看到的那样,instant类也支持静态工厂方法now,它能够帮你获取当前时刻的时间戳。我们想要特别强调一点,instant的设计初衷是为了便于机器使用。它包含的是由秒及纳秒所构成的数字。所以,它无法处理那些我们非常容易理解的时间单位。比如下面这段语句:
int day = instant.now().get(chronofield.day_of_month);
它会抛出下面这样的异常:
exception in thread "main" java.time.temporal.unsupportedtemporaltypeexception: unsupported field: dayofmonth
你可以通过duration和period类使用instant
1.1.5 定义duration和period(时间间隔对象)
-
duration
:可以传2个localtime对象,localdatetime对象或者instant对象 -
period
:用年,月,日建模,可以传2个localdate对象
duration d1 = duration.between(time1, time2); duration d2 = duration.between(datetime1, datetime2); duration d3 = duration.between(instant1, instant2);
由 于localdatetime和instant是为不同的目的而设计的,一个是为了便于人阅读使用,另一个是为了便于机器处理,所以你不能将二者混用。如果你试图在这两类对象之间创建duration,会触发一个datetimeexception异常 。 如果你需要以年、月或者日的方式对多个时间单位建模,可以使用period类。使用该类的工厂方法between,你可以使用得到两个localdate之间的时长,如下所示 :
period period = period.between(localdate.of(2019, 11, 07), localdate.of(2019, 11, 07));
duration和period类都提供了很多非常方便的工厂类,直接创建对应的实例;换句话说,就像下面这段代码那样,不再是只能以两个temporal对象的差值的方式来定义它们的对象。
duration threeminutes = duration.ofminutes(3); duration fourminutes = duration.of(4, chronounit.minutes); period tenday = period.ofdays(10); period threeweeks = period.ofweeks(3); period twoyearssixmonthsoneday = period.of(2, 6, 1);
1.2 操纵 解析和格式化日期
1.2.1
以比较直观的方式操纵localdate的属性
下面的这段代码中所有的方法都返回一个修改了属性的对象。它们都不会修改原来的对象!
localdate date1 = localdate.of(2019, 11, 1);//2019-11-01 localdate date2 = date1.withyear(2020);//2020-11-01 localdate date3 = date2.withdayofmonth(25);//2020-11-25 localdate date4 = date3.with(chronofield.month_of_year, 9);//2020-09-25
- 以相对方式修改localdate的属性
@test public void editdatetime() { localdate date1 = localdate.of(2019, 11, 01);// 2019-11-01 localdate date2 = date1.plusweeks(1);// 2019-11-08 localdate date3 = date2.minusyears(2);// 2017-11-08 localdate date4 = date3.plus(6, chronounit.months);// 2018-05-08 }
1.2.3 temporaladjuster
@test public void adjust() { localdate date1 = localdate.of(2019, 11, 01);// 2019-11-01 localdate date2 = date1.with(temporaladjusters.nextorsame(dayofweek.sunday));// 2019-11-03 localdate date3 = date2.with(temporaladjusters.lastdayofmonth());// 2019-11-30 }
temporaladjuster类的工厂方法
1.2.4自定义格式化输出日期
新版本,我们拥有一个线程安全的类:datetimeformatter
来看代码
@test public void formatprint() { localdate date = localdate.of(2019, 11, 01); string s1 = date.format(datetimeformatter.basic_iso_date);// 20191101 string s2 = date.format(datetimeformatter.iso_local_date);// 2019-11-01 localdate date1 = localdate.parse("20191101", datetimeformatter.basic_iso_date); localdate date2 = localdate.parse("2019-11-01", datetimeformatter.iso_local_date); // 自定义格式 datetimeformatter formatter = datetimeformatter.ofpattern("dd/mm/yyyy"); string formatteddate = date.format(formatter); system.out.println(formatteddate);// 01/11/2019 localdate date3 = localdate.parse(formatteddate, formatter); // 带时区的日期(本地化) datetimeformatter italianformatter = datetimeformatter.ofpattern("d. mmmm yyyy", locale.italian); string formatteddate2 = date.format(italianformatter); localdate date4 = localdate.parse(formatteddate2, italianformatter); }