在上篇文章Java中的时间和日期(上)里面,简单介绍了Java中的Date类,Calendar类以及用于格式化的SimpleDateFormater类。使用这些的时候我们会明显地感受到其中的不便之处,比如,Calendar类的月份是从0开始计数的;日期格式输出不够友好,很多情况下都需要使用SimpleDateFormater类来格式化;一些简单得日期计算也比较麻烦等等。所以就有了joda-time
这种第三方库来简化java对于时间和日期的操作。为了改变这种情况,java 8中对时间和日期对处理就吸收了joda-time
库的特性。那么新的时间日期处理会带来怎样的便捷呢?这便是本篇文章所要聊的内容。
Java8中,新的时间及日期API位于java.time包中,java.time包中的是类是不可变且线程安全的,主要类如下:
- Instant——它代表的是时间戳
- LocalDate——不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。
- LocalTime——它代表的是不含日期的时间
- LocalDateTime——它包含了日期及时间,不过还是没有偏移信息或者说时区。
- ZonedDateTime——这是一个包含时区的完整的日期时间还有时区,偏移量是以UTC/格林威治时间为基准的。
- Timezones——时区。在新API中时区使用ZoneId来表示。时区可以很方便的使用静态方法of来获取到。
- 时区定义了到格林威治时间(GMT)/UTC的时间差,在Instant时间点对象到本地日期对象之间转换的时候是极其重要的。
Java8中日期、时间API结构:
Java8常用的类介绍
1.月份的枚举类Monthjava.time.Month枚举类:表示月份
在以前使用Java的时候,你一定痛恨了月份的表示和计算,最主要的原因就是因为一月份是从0开始计数的。
在Java 8中为了改变这一现状,增加了一个Month
枚举类来表示月份。使用这个枚举类甚至还可以直接进行月份的加减运算!
-
of(int month) 这是一个静态方法,用于创建一个
Month
对象。传入的参数当然是从1开始计数啦,1表示一月,12表示十二月。当传入的参数小于1或者大于12时,就会抛出异常。 -
getValue() 返回该
Month
对象当前的值。一月份返回1,二月份返回2,依次类推。 -
minus(long months) 这个是用来做月份的减法计算的。传入的参数表示你想在该
Month
对象的基础上减去几个月。如果是1月份减去2个月,返回的当然是11月份。 -
plus(long months) 用来计算月份的加法。传入的参数表示你想在该
Month
对象的基础上增加几个月。比如12月加2个月就变成了二月份。 -
maxLength(), minLength()和length(boolean leapYear) 用来获取
Month
对象表示的该月的日期数。其中,length(boolean leapYear)
中的参数表示是否为闰年。其实这三个方法返回的结果在很多情况下都是一样的,返回的都是当月的日期数,30或者31。只有二月份除外,当Month
对象表示二月份时,maxLength()
和length(true)
返回29,minLength()
和length(false)
返回28。
下面用代码来说明上述方法的使用:
public static void main(String[] args) {
System.out.println(Month.DECEMBER); // DECEMBER
System.out.println(Month.of(2)); // FEBRUARY
Month month = Month.FEBRUARY;
System.out.println(month.getValue()); // 2
System.out.println(month.minus(3)); // NOVEMBER
System.out.println(month.plus(2)); // APRIL
System.out.println(month.length(false)); // 28
System.out.println(month.length(true)); // 29
System.out.println(month.maxLength()); //29
System.out.println(month.minLength()); //28
}
有时候希望返回月份是中文,而不是英文。毕竟程序员大多都比较懒,能少转化一次自然是很好的。又或者你需要显示的是月份的英文缩写?Java 8都为你想到了。
只要调用 month.getDisplayName(TextStyle, Locale)
方法就行:
第一个参数是文本类型,也就是说你想显示完整的名称还是缩写;
第二个参数表示地区,如果没有特殊要求,传入Locale.getDefault()
就行。就像下面的代码演示的那样:
2.星期的枚举类DayOfWeek
java.time.DayOfWeek枚举类:用来表示一个周的七天。常用的方法和 Month
枚举类的几乎一致,包括
of(int dayOfWeek)
静态方法用于创建DayOfWeek
对象;
getValue()
方法用来获取该对象的值;
plus(long days)
和minus(long days)
方法用来进行加减法计算。
getDisplayName(TextStyle style, Locale locale)
来格式化输出。代码演示如下:
public static void main(String[] args) {
System.out.println(DayOfWeek.FRIDAY); // FRIDAY
System.out.println(DayOfWeek.of(7)); // SUNDAY
DayOfWeek dayOfWeek = DayOfWeek.TUESDAY;
System.out.println(dayOfWeek.getValue()); // 2
System.out.println(dayOfWeek.plus(3)); // FRIDAY
System.out.println(dayOfWeek.minus(2)); // SUNDAY
Locale defaultLocal = Locale.getDefault();
System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, defaultLocal)); // 星期二
System.out.println(dayOfWeek.getDisplayName(TextStyle.SHORT, defaultLocal)); // 星期二
System.out.println(dayOfWeek.getDisplayName(TextStyle.NARROW, defaultLocal)); // 二
Locale locale = Locale.ENGLISH;
System.out.println(dayOfWeek.getDisplayName(TextStyle.FULL, locale)); // Tuesday
System.out.println(dayOfWeek.getDisplayName(TextStyle.SHORT, locale)); // Tue
System.out.println(dayOfWeek.getDisplayName(TextStyle.NARROW, locale)); // T
}
但是,在DayOfWeek
枚举类中,是没有maxLength(), minLength()和length(boolean leapYear)
这三个方法的,相信你们也知道是为什么。
最后说一句,由于Month
和DayOfWeek
只是枚举类,它们并不持有当前时间信息,所以就别妄想使用这两个枚举类来解决”今天是星期几”,”明天是几号”等问题了。
刚开始学Java的时候,计算月份/星期几乎是必备作业,不过当时用的是Date/Calendar类来计算,相当麻烦,
Java 8使用枚举来表示月份和星期之后,进行相应的加减法计算就变的相对简单了。
由于月份的计算和星期的计算原理是一样的,我们就只看Month
的加减法计算。
private static final Month[] ENUMS = Month.values();
public Month plus(long months) {
int amount = (int) (months % 12);
return ENUMS[(ordinal() + (amount + 12)) % 12];
}
public Month minus(long months) {
return plus(-(months % 12));
}
这里的处理方法很巧妙,减法直接调用加法的处理逻辑,当年我就没想到过,哈哈,值得学习。
3. LocalDate和LocalTime类
java.time.LocalDate java.time.LocalTime
重头戏来了,现在开始隆重介绍Java 8的常用的时间日期类:LocalDate
和LocalTime
。
使用 LocalDate
可以获取当前日期(注意只是日期,不包含时间),并可以进行相应处理。
使用 LocalTime
可以获取当前时间(注意只是时间,不包含日期)并进行相应处理。这样就更好的符合“单一职责原则”。
构造方法
根据不同的需求,提供了不同的创建方式,主要包括两个静态方法 now()
和of()
方法。其实,在后面我们会看到,在Java 8中,创建时间和日期几乎都会用的这两个方法。
public static void main(String[] args) {
LocalDate date1 = LocalDate.now();
LocalDate date2 = LocalDate.of(1998, 2, 4);
LocalDate date3 = LocalDate.ofEpochDay(180);
System.out.println(date1); // 2016-07-11
System.out.println(date2); // 1998-02-04
System.out.println(date3); // 1970-06-30
LocalTime time1 = LocalTime.now();
LocalTime time2 = LocalTime.now().withNano(0);
LocalTime time3 = LocalTime.of(12, 30);
LocalTime time4 = LocalTime.ofSecondOfDay(60 * 60 * 2);
System.out.println(time1); // 10:56:04.772
System.out.println(time2); // 10:56:04
System.out.println(time3); // 12:30
System.out.println(time4); // 02:00
}
withNano()
方法会在后面提及,主要是修改当前对象表示的纳秒数的值。在上面的代码中,有几点需要注意的地方:
ofEpochDay(long epochDay)
方法中的参数,指的是距1970年1月1日那天的时间间隔。- 在Java 8中,时间和日期的格式是按照ISO-8061的时间和日期标准来显示的。年份为4位数,月日时分秒都是2位数,不足两位用0补齐。
常用方法
LocalDate
还记得之前说过的,DayOfWeek
枚举类不持有当前时间信息,所以你无法单独使用它来得到今天是星期几
这种信息。然而如果获取到了当前日期的LocalDate
对象后,问题就迎刃而解了。
LocalDate
提供了大量的方法来进行日期信息的获取和计算。有了这一个LocalDate
对象,你不仅可以知道这个对象是哪年几月几日星期几,还能够对于年月日进行加减法计算,甚至你可以以周为单位进行日期的加减法计算,比如,你可以轻松解决两个周前的今天是几月几日
这类问题。
下面,是常用的方法,请自行查阅官方API文档
方法名返回值类型对该方法的解释getYear()int获取当前日期的年份getMonth()Month获取当前日期的月份对象getMonthValue()int获取当前日期是第几月getDayOfWeek()DayOfWeek表示该对象表示的日期是星期几getDayOfMonth()int表示该对象表示的日期是这个月第几天getDayOfYear()int表示该对象表示的日期是今年第几天withYear(int year)LocalDate修改当前对象的年份withMonth(int month)LocalDate修改当前对象的月份withDayOfMonth(int dayOfMonth)LocalDate修改当前对象在当月的日期isLeapYear()boolean是否是闰年lengthOfMonth()int这个月有多少天lengthOfYear()int该对象表示的年份有多少天(365或者366)plusYears(long yearsToAdd)LocalDate当前对象增加指定的年份数plusMonths(long monthsToAdd)LocalDate当前对象增加指定的月份数plusWeeks(long weeksToAdd)LocalDate当前对象增加指定的周数plusDays(long daysToAdd)LocalDate当前对象增加指定的天数minusYears(long yearsToSubtract)LocalDate当前对象减去指定的年数minusMonths(long monthsToSubtract)LocalDate当前对象减去注定的月数minusWeeks(long weeksToSubtract)LocalDate当前对象减去指定的周数minusDays(long daysToSubtract)LocalDate当前对象减去指定的天数compareTo(ChronoLocalDate other)int比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚,isBefore(ChronoLocalDate other)boolean比较当前对象日期是否在other对象日期之前isAfter(ChronoLocalDate other)boolean比较当前对象日期是否在other对象日期之后isEqual(ChronoLocalDate other)boolean比较两个日期对象是否相等列出这么多方法,不是要你死记硬背记住它们,而是要在脑海有个印象,知道有哪些常用方法,可以做什么。概括起来,LocalDate
类中常用的方法有四种:获取日期信息,修改日期信息,加减法运算和日期对象间的比较。记住了这些,以后在工作中就可以查阅使用,而不用自己在造一遍轮子。
有几点需要注意的地方:
- 上面列表里面有一个
ChronoLocalDate
,它是一个接口,LocalDate
类实现了这个接口,所以直接传一个LocalDate
类对象即可。 - isEqual(ChronoLocalDate other)这个方法,如果两个对象是同一个对象,或者这两个对象的值相等(同年同月同日),则返回true,否则返回false。
- 当一个方法返回的是
LocalDate
对象时,便可以使用链式调用
。举个例子,获取昨天的日期,我们可以直接这样写:LocalDate.now().minusDays(1)
。
下面用代码演示几个方法:
public static void main(String[] args) {
LocalDate now = LocalDate.now();
System.out.println(now.getYear()); // 2016
System.out.println(now.getDayOfWeek()); // MONDAY
System.out.println(now.getDayOfMonth()); // 11
System.out.println(now.withMonth(3)); // 2016-03-11
System.out.println(now.minusWeeks(2)); // 2016-06-27
System.out.println(now.plusDays(10)); // 2016-07-21
LocalDate firstDayOfYear = LocalDate.of(2016,1,1);
System.out.println(now.compareTo(firstDayOfYear)); // 6
System.out.println(now.isAfter(firstDayOfYear)); // true
System.out.println(now.isEqual(firstDayOfYear)); // false
}
LocalTime
LocalDate
类中的方法和LocalDate
中的类似,同样可以分为:获取时间信息,修改时间信息,加减法运算和时间对象间的比较。方法的具体描述我就不写了。根据LocalDate
类中列举的常用方法,你也能猜得出在LocalTime
类中有哪些对应的常用方法。下面还是用代码演示几个方法:
public static void main(String[] args) {
LocalTime now = LocalTime.now();
System.out.println(now.getHour()); // 14
System.out.println(now.getMinute()); // 15
System.out.println(now.getSecond()); // 22
System.out.println(now.getNano()); // 881000000
System.out.println(now.withNano(0)); // 14:15:22
System.out.println(now.minusHours(3)); // 11:15:22.881
System.out.println(now.minusMinutes(15)); // 14:00:22.881
System.out.println(now.minusSeconds(20)); // 14:15:02.881
LocalTime halfOfDay = LocalTime.of(12 ,0);
System.out.println(now.compareTo(halfOfDay)); // 1
System.out.println(now.isAfter(halfOfDay)); // true
}
不过有几点需要说明:
LocalTime
中没有isEqual()
方法。- 在
getNano()
中,nano指的是纳秒(毫微秒),1秒等于1亿纳秒。
4. LocalDateTime日期时间类
java.time.LocalDateTime
或许有人觉得,将日期和时间分开处理有些不方便。我想将时间和日期一起处理怎么办?当然可以,Java 8中还提供了LocalDateTime
来满足你的这个需求。
构造方法
和前面的类似,可以使用静态方法now()
和静态方法of()
来创建一个LocalDateTime
对象。比如:
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println(now); // 2016-07-11T14:27:20.169
LocalDateTime dateTime1 = LocalDateTime.of(1990, 1, 1, 12, 3);
LocalDateTime dateTime2 = LocalDateTime.of(2000, 2, 4, 8, 4, 20);
System.out.println(dateTime1); // 1990-01-01T12:03
System.out.println(dateTime2); // 2000-02-04T08:04:20
}
通常,你需要在of()
方法中传入6个参数,表示年月日时分秒。关于月份,既可以传入Month对象,也可以传入int值(当然1表示一月份)。也可以将秒这个参数省略了,传入5个参数。也可以增加一个纳秒参数,变为7个参数。
常用方法,这个不想再说了,和LocalDate
及LocalTime
类似。
LocalDateTime和LocalDate、LocalTime之间的转化
LocalDate、LocalTime、LocalDateTime之间的互相转换,也是可以走from方法:
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = LocalDate.from(localDateTime); //注意:不可以逆转
LocalTime localTime = LocalTime.from(localDateTime); //注意:不可以逆转
System.out.println(localDate);
System.out.println(localTime);
Date类与新日期时间、时间戳之间转换需要注意的抗:
Date类型可以表示日期,也可以表示日期+时间。因此Date类型转LocalDate、LocalTime、Instant等类型的转换就非常重要了。注意一个坑:他们转换的中间桥梁都是 Instant对象,但是转换的时候如果没有考虑时区,就会报错的。
LocalDate、LocalTime、LocalDateTime转Date,借助中间变量Instant来实现。
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
Instant instant = null;
ZoneId zone = ZoneId.systemDefault();
//LocalDateTime转Instant转Date
instant = localDateTime.atZone(zone).toInstant();
System.out.println(Date.from(instant));
//LocalDate转Instant转Date
instant = localDate.atStartOfDay().atZone(zone).toInstant();
System.out.println(Date.from(instant));
//LocalTime转Instant转Date(一般都不用)
//必须先借助localDate转换成localDateTime 在转成instant 再转date
LocalDateTime localDateTimeDate = LocalDateTime.of(localDate, localTime);
instant = localDateTime.atZone(zone).toInstant();
System.out.println(Date.from(instant));
Date转LocalDate、LocalTime等,借助LocalDateTime对象可保证万无一失。
Date date = new Date();
//时间戳转instant
Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
System.out.println(instant); // 注意:直接输出值是有时区问题的 时差8小时
//Date直接转Instant
System.out.println(date.toInstant());
//Instant --> Date
Date.from(Instant.now());
//Calendar --> Instant(这个用得很少)
Calendar.getInstance().toInstant();
// 注意时区的坑和date的表示含义
// 以ZoneId.systemDefault转换成LocalDateTime后,就可以随意转换了
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
//方式一:使用LocalDate、LocalTime的from
LocalDate fromLocalDate = LocalDate.from(localDateTime);
LocalTime fromLocalTime = LocalTime.from(localDateTime);
System.out.println(fromLocalDate);
System.out.println(fromLocalTime);
//方式二:直接to的方式
LocalDate toLocalDate = localDateTime.toLocalDate();
LocalTime toLocalTime = localDateTime.toLocalTime();
System.out.println(toLocalDate);
System.out.println(toLocalTime);
5.ZonedDateTime(带时区的日期和时间)
Java8使用ZoneId来标识不同的时区。ZonedDateTime的许多方法与LocalDateTime、LocalDate、LocalTime类似。
IANA(Internet Assigned Numbers Authority,因特网拨号管理局)维护着一份全球所有已知的时区数据库,Java使用了IANA的数据库。
//获得所有可用的时区
Set allZones = ZoneId.getAvailableZoneIds();
//获取默认ZoneId对象系统当前所在时区
ZoneId defZoneId = ZoneId.systemDefault();
//获取指定时区的ZoneId对象
ZoneId shanghaiZoneId = ZoneId.of("Asia/Shanghai");
//ZoneId.SHORT_IDS返回一个Map 是时区的简称与全称的映射。下面可以得到字符串 Asia/Shanghai
String shanghai = ZoneId.SHORT_IDS.get("CTT");
System.out.println(shanghai); //Asia/Shanghai
6. 解析和格式化 - DateTimeFormatter类
在Date和Calendar统治的时代,想要格式化一个日期,只能用Date来格式化,并且SimpleDateFormat还有线程安全隐患,无疑很麻烦。所以在高并发环境下,需要使用SimpleDateFormat,我们可以借助ThreadLocal, 来保证线程安全:
public static void main(String[] args) {
Date date = new Date();
System.out.println(format(date));
}
private static ThreadLocal threadLocal = new ThreadLocal() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
// 和线程绑定 保证安全
public static String format(Date date) {
return threadLocal.get().format(date);
}
在Java 8中,java.time包中的是类是不可变且线程安全的。时间日期的格式是按照ISO-8061的时间和日期标准来显示的。年份为4位数,月日时分秒都是2位数,不足两位用0补齐,日期之间需要用短横线连接,时间之间要用:
连接。必须按照此规则来进行解析,比如:
public static void main(String[] args) {
LocalDate date = LocalDate.parse("2016-09-08");
LocalTime time = LocalTime.parse("12:24:43");
System.out.println(date); // 2016-09-08
System.out.println(time); // 12:24:43
}
当然,Java是宽容的,如果你不按照ISO-8061
的格式传入,也可以自定义格式。
DateTimeFormatter类:格式化器用于打印和解析日期时间对象。主要提供两种方法 : 一种用于格式化,一种用于解析。
-
-
String
format(TemporalAccessor temporal)
使用此格式化程序格式化日期时间对象。
TemporalAccessor
parse(CharSequence text, ParsePosition position)
使用此格式化器解析文本,提供对文本位置的控制。
-
//String与LocalDate转换
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
// 解析
LocalDate localDate = LocalDate.parse("20160708", formatter);
// 格式化
String str = formatter.format(localDate);
System.out.println(str); // 20160708
System.out.println(localDate.toString()); // 2016-07-08
//String与LocalDateTime转换,同理
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
// 解析
LocalDateTime localDateTime = LocalDateTime.parse("2013/12/31 23:59:59", formatter2);
// 格式化
str = formatter2.format(localDateTime);
System.out.println(str); // 2013/12/31 23:59:59
System.out.println(localDateTime.toString()); // 2013-12-31T23:59:59
DateTimeFormatter预定义了一些格式,可以直接调用format方法。
根据当前操作系统语言环境,有SHORT MEDIUM LONG FULL 四种不同的风格来格式化。
注意:FormatStyle.FULL – 此格式样式适用于LocalDate.但是使用LocalTime实例抛出异常,jdk9后修复了。
System.out.println(DateTimeFormatter.BASIC_ISO_DATE.format(LocalDateTime.now()));
System.out.println(DateTimeFormatter.ISO_DATE.format(LocalDateTime.now()));
System.out.println(DateTimeFormatter.ISO_LOCAL_TIME.format(LocalDateTime.now()));
System.out.println(DateTimeFormatter.ISO_WEEK_DATE.format(LocalDateTime.now()));
System.out.println(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.now()));
7. Clock时钟
clock类:提供给我们用于访问某个特定时区的当前瞬时时间或当期瞬时日期时间。
方法等:
-
-
boolean
equals(Object obj)
检查这个时钟是否等于另一个时钟。
abstract ZoneId
getZone()
获取用于创建日期和时间的时区。
abstract Instant
instant()
获取当前的时钟瞬间。
long
millis()
获取时钟的当前毫秒时间。
static Clock
system(ZoneId zone)
获取使用最佳可用系统时钟返回当前时刻的时钟。
static Clock
systemDefaultZone()
获取使用最佳可用系统时钟返回当前即时的时钟,使用默认时区转换为日期和时间。
static Clock
systemUTC()
获取使用最佳可用系统时钟返回当前即时的时钟,使用UTC时区转换为日期和时间。
-
ZoneId 是一个时区ID类,比如:Asia/Shanghai
-
-
static ZoneId
of(String zoneId)
从ID获取一个
ZoneId
的实例,确保该ID有效并且可供使用。static ZoneId
systemDefault()
获取系统默认时区。
-
Clock c1 = Clock.systemUTC(); //系统默认UTC时钟(当前瞬时时间 System.currentTimeMillis())
Clock c2 = Clock.systemDefaultZone(); //系统默认时区时钟(当前瞬时时间)
Clock c3 = Clock.system(ZoneId.of("Asia/Shanghai"));//上海时区
Instant instant = c3.instant();
System.out.println(c3.millis());//1532179594406
System.out.println(c3.getZone());//Asia/Shanghai
8.Instant瞬时时间
java.time.Instant类:表示瞬时时间,等价于以前的System.currentTimeMillis()
Instant由两部分组成,代表到格林威治时间(GMT)/UTC的时间,没有时区的作用。所以上面的转换时需要考虑时区。
- 从原点开始到指定时间点的秒数s(用long存储),
- 距离该秒数s的纳秒数(用int存储)。
-
-
static Instant
now()
从系统时钟获取当前瞬间。
static Instant
now(Clock clock)
从指定的时钟获取当前时刻。
-
//瞬时时间 相当于以前的System.currentTimeMillis()
Instant instant1 = Instant.now();
System.out.println(instant1.getEpochSecond());//精确到秒 得到相对于1970-01-01 00:00:00 UTC的时间 1532179778
System.out.println(instant1.toEpochMilli()); //精确到毫秒 1532179778266
Clock clock1 = Clock.systemUTC(); //获取系统UTC默认时钟
Instant instant2 = Instant.now(clock1);//得到时钟的瞬时时间
System.out.println(instant2.toEpochMilli());
Clock clock2 = Clock.fixed(instant1, ZoneId.systemDefault()); //固定瞬时时间时钟
Instant instant3 = Instant.now(clock2);//得到时钟的瞬时时间
System.out.println(instant3.toEpochMilli());//equals instant1
9. java.time.Duration
java.time.Duration表示一段时间。可以是用来处理时间戳的差值计算。
//指定时间的Instant
Instant temp = Instant.parse("2007-12-03T10:15:30.00Z");
Instant now = Instant.now();
Instant instant = now.plusSeconds(TimeUnit.HOURS.toSeconds(25));
//希望得到两个时间戳,他们相隔了几个小时、几天、几个月?
System.out.println(now.until(instant, ChronoUnit.HOURS)); //25
System.out.println(now.until(instant,ChronoUnit.DAYS)); //1(这里显示1不是2哦)
System.out.println(instant.until(now,ChronoUnit.HOURS)); //-25(注意,这里是负数哦)
Instant start = Instant.parse("2017-12-03T10:15:30.00Z");
// doSomething();
Instant end = Instant.now();
//计算时间差
Duration timeElapsed = Duration.between(start, end);
long millis = timeElapsed.toMillis();
System.out.println("millis = " + millis);
10.java.time.Period
java.time.Period类:可以计算两个日期之间包含多少天、周、月、年等。
LocalDate start = LocalDate.of(2017,10,15);
LocalDate end = LocalDate.now();
System.out.println(start);
System.out.println(end);
//日常熟悉的表示法,间隔多少年多少月多少天
Period p = Period.between(start, end);
System.out.println("相差:" + p.getYears()+"年"+ p.getMonths() + "月" + p.getDays()+ "日");
//要得到前后的天数绝对值
long distance = ChronoUnit.DAYS.between(start, end);
System.out.println("相差:" + distance + "天");
// 得到前后的天数绝对值,可以输出在两个日期之间获得所有日期
List allDays = new ArrayList();
for (int i = 0; i {
LocalDate date = (LocalDate) x;
DayOfWeek dayOfWeek = date.getDayOfWeek();
if (dayOfWeek == DayOfWeek.FRIDAY) {
return date.plusDays(3);
} else if (dayOfWeek == DayOfWeek.SATURDAY) {
return date.plusDays(2);
} else {
return date.plusDays(1);
}
});
System.out.println(with);
参考文章: https://blog.csdn.net/wl9739/article/details/51882913
ends~