1、日期格式化
package java8.datetime; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; /** * @author kyle * @version 1.0 2018年8月24日 NEW * @function */ public class LocalDateFormat { public static void main(String[] args) { // 和老的java.util.DateFormat相比较,所有的DateTimeFormatter实例都是线程安全的。所以,你能够以单例模式创建格式器实例 LocalDate date = LocalDate.of(2018, 8, 24); String strDate = date.format(DateTimeFormatter.BASIC_ISO_DATE); // BASIC_ISO_DATE去掉分隔符 System.out.println(strDate); String strDate2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); System.out.println(strDate2); // 字符串转日期 LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE); LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE); // 日期格式化 LocalDate ldt = LocalDate.now(); String strD = ldt.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); System.out.println(strD); LocalDateTime ldtTime = LocalDateTime.now(); String strDTime = ldtTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); System.out.println(strDTime); /* 下面代码中,LocalDate的format方法使用指定的模式生成了一个代表该日期的字符串。 紧接着,静态的parse方法使用同样的格式器解析了刚才生成的字符串,并重建了该日期对象。 */ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); LocalDate date11 = LocalDate.of(2014, 3, 18); String formattedDate = date11.format(formatter); LocalDate date22 = LocalDate.parse(formattedDate, formatter); // 创建一个本地化的DateTimeFormatter DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.CHINA); LocalDate date111 = LocalDate.of(2018, 8, 24); String formattedDate1 = date111.format(italianFormatter); // 18. marzo 2014 LocalDate date222 = LocalDate.parse(formattedDate1, italianFormatter); System.out.println(date222); } }
2、日期提取,求日期差值,日期加减。
import java.time.*; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; /** * @author kyle * @version 1.0 2018年8月23日 NEW * @function */ public class MyLocalDate { public static void main(String[] args) { /* TemporalField是一个接口,它定 义了如何访问temporal对象某个字段的值。ChronoField枚举实现了这一接口,所以你可以很 方便地使用get方法得到枚举元素的值 */ LocalDate data = LocalDate.now(); int year = data.get(ChronoField.YEAR); int month = data.get(ChronoField.MONTH_OF_YEAR); int day = data.get(ChronoField.DAY_OF_MONTH); System.out.println(year); System.out.println(month); System.out.println(day); System.out.println("当前日期:"+year+"-"+month+"-"+day); LocalDate date = LocalDate.parse("2014-03-18"); LocalTime time = LocalTime.parse("13:45:20"); System.out.println("日期:"+date); System.out.println("时间:"+time); // 合并日期和时间,一步创建日期和时间 LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); System.out.println(dt1.toString().replace("T", " ")); // 组合创建日期和时间 LocalDateTime d1= LocalDateTime.of(date, time); System.out.println(d1); // 提取日期和时间 LocalDate ld = d1.toLocalDate(); LocalTime lt = d1.toLocalTime(); System.out.println(ld +" "+lt); Period tenDays = Period.between(LocalDate.of(2014, 03, 8), LocalDate.of(2014, 03, 18)); // 求两个时间的差值很方便 Period tenDays2 = Period.between(LocalDate.parse("2014-03-08"), LocalDate.parse("2014-03-18")); System.out.println("两个时间的差值test1:"+tenDays.getDays()); System.out.println("两个时间的差值test2:"+tenDays2.getDays()); System.out.println("-----------------------------------------------------------------------------"); /* 操纵、解析和格式化日期, 如果你已经有一个LocalDate对象,想要创建它的一个修改版,最直接也最简单的方法是使 用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属 性。 */ LocalDate date1 = LocalDate.of(2018, 8, 23); LocalDate date2 = date1.withYear(2011); // 年,创建对象的一个副本,不会修改原来对象的内容 LocalDate date3 = date2.withDayOfMonth(25); // 天 // 两种方式设置月份 LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9); // 月 LocalDate date5 = date3.withMonth(10); // 月 LocalDate date7 = date1.withYear(date1.getYear()-1); System.out.println("date1: "+ date1); System.out.println("date2: "+ date2); System.out.println("date3: "+ date3); System.out.println("date4: "+ date4); System.out.println("date5: "+ date5); System.out.println("date7: "+ date7); System.out.println("-----------------------------------上面是加,下面是减时间------------------------------------------"); // 日期加减 LocalDate date11 = LocalDate.of(2018, 8, 23); LocalDate date22 = date11.plusWeeks(1); System.out.println("原日期:"+date11); System.out.println("更改后:"+date22); LocalDate date33 = date22.minusYears(3); // 减3年 LocalDate date55 = date33.plus(5, ChronoUnit.MONTHS); // 加5个月 LocalDate date77 = date55.plusMonths(1); // 加一个月 System.out.println("date33: "+date33); System.out.println("date55: "+date55); System.out.println("date77: "+date77); // 经过下面这些操作,date变量的值是什么? LocalDate date9 = LocalDate.of(2014, 3, 18); date9 = date9.with(ChronoField.MONTH_OF_YEAR, 9); date9 = date9.plusYears(2).minusDays(10); /* date9.withYear(2011) 此处没赋值(即设置值之后没有将值赋值给变量LocalDate date = date9.withYear(2011))所以不会改变date9的日期 with只是创建复本不会对原来的对象做出修改 */ date9.withYear(2011); // System.out.println(date9); // 答案:2016-09-08。 } }
3、时区与日期设置
package java8.datetime; import java.sql.Timestamp; import java.time.OffsetDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; public class MyOffsetDateTime { public static void main(String[] args) { ZoneId chinaZone = ZoneId.of("Asia/Shanghai"); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); OffsetDateTime now = OffsetDateTime.now(chinaZone); // 当前日期减一天 OffsetDateTime start = now.plusDays(-1L).withHour(0).withMinute(0).withSecond(0).withNano(0); // 在当前日期减一天的基础上设置时分秒为23:59:59 OffsetDateTime end = start.withHour(23).withMinute(59).withSecond(59).withNano(0); System.out.println("start: "+ start.format(dtf)); System.out.println("end: "+ end.format(dtf)); System.out.println("start_Instant: "+ Timestamp.from(start.toInstant())); System.out.println("end_Instant: " + Timestamp.from(end.toInstant())); } }
4、指定月份最后一天,根据规则求日期
package java8.datetime; import java.time.LocalDate; import static java.time.temporal.TemporalAdjusters.*; import java.time.DayOfWeek; import java.time.OffsetDateTime; import java.time.temporal.TemporalAdjusters; /** * @author kyle * @version 1.0 2018年8月23日 NEW * @function */ public class MyTemporalAdjuster { public static void main(String[] args) { /** dayOfWeekInMonth 创建一个新的日期,它的值为同一个月中每一周的第几天 firstDayOfMonth 创建一个新的日期,它的值为当月的第一天 firstDayOfNextMonth 创建一个新的日期,它的值为下月的第一天 firstDayOfNextYear 创建一个新的日期,它的值为明年的第一天 firstDayOfYear 创建一个新的日期,它的值为当年的第一天 firstInMonth 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值 lastDayOfMonth 创建一个新的日期,它的值为当月的最后一天 lastDayOfNextMonth 创建一个新的日期,它的值为下月的最后一天 lastDayOfNextYear 创建一个新的日期,它的值为明年的最后一天 lastDayOfYear 创建一个新的日期,它的值为今年的最后一天 lastInMonth 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值 next/previous 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星 期几要求的日期 nextOrSame/previousOrSame 创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星 期几要求的日期,如果该日期已经符合要求,直接返回该对象 */ // 根据指定日期求出和指定日期最近的下一个周一和当月的最后一天 LocalDate date1 = LocalDate.of(2021, 07, 22); LocalDate date2 = date1.with(nextOrSame(DayOfWeek.MONDAY)); // 下周一(第一个符合指定星期几要求的日期) LocalDate date3 = date1.with(lastDayOfMonth()); // 当月的最后一天 System.out.println(date2); System.out.println(date3); // 根据当前日期求出当月的最后一天 LocalDate endDay = LocalDate.now().with(lastDayOfMonth()); System.out.println(endDay); // 求指写月份的最后一天,比如2月,这样我们就不用去判断是不是润年了 LocalDate twoMonthEndDay = LocalDate.now().withMonth(2).with(lastDayOfMonth()); System.out.println(twoMonthEndDay); OffsetDateTime time = OffsetDateTime.now(); // 指定某个月的第几周并返回日期,如5月第2个周日 dayOfWeekInMonth(2, DayOfWeek.SUNDAY)代表第2个周日 System.out.println( time.withMonth(5) // 固定设置为5月 .with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SUNDAY)) // 动态计算的5月第二周是哪天 .toLocalDate().toString()); } }
5、日期比较
package java8.datetime; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.MonthDay; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; /** * @author kyle * @version 1.0 2018年8月24日 NEW * @function */ public class MyZoneId { public static void main(String[] args) { // 为时间添加时区信息 ZoneId shanghai = ZoneId.of("Asia/Shanghai"); LocalDateTime localDateAndTime = LocalDateTime.now(); ZonedDateTime dateAndTimeInShanghai = ZonedDateTime.of(localDateAndTime, shanghai); System.out.println("Current date and time in a particular timezone : " + dateAndTimeInShanghai); System.out.println(ZoneId.systemDefault()); System.out.println(dateAndTimeInShanghai.getOffset()); // 判断是不是生日 LocalDate dateOfBirth = LocalDate.of(2018, 8, 24); MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth()); System.out.println("MonthDay.now(): "+MonthDay.now()); MonthDay currentMonthDay = MonthDay.from(MonthDay.now()); if (currentMonthDay.equals(birthday)) { System.out.println("Many Many happy returns of the day !!"); } else { System.out.println("Sorry, today is not your birthday"); } // 当前日期 LocalDate today = LocalDate.now(); // 如何用Java判断日期是早于还是晚于另一个日期 LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS); if(tomorrow.isAfter(today)){ System.out.println("Tomorrow comes after today"); } LocalDate yesterday = today.minus(1, ChronoUnit.DAYS); if(yesterday.isBefore(today)){ System.out.println("Yesterday is day before today"); } } }
6、求下一个跳跃日期
package java8.datetime; import java.time.DayOfWeek; import java.time.LocalDate; import java.time.temporal.ChronoField; import java.time.temporal.ChronoUnit; import java.time.temporal.Temporal; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; /** * @author kyle * @version 1.0 2018年8月24日 NEW * @function */ public class NextWorkingDay implements TemporalAdjuster { // 如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则返回下一个周一。 // 第一种方式实现接口 @Override public Temporal adjustInto(Temporal temporal) { DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); int dayToAdd = 1; if(dow == DayOfWeek.FRIDAY) dayToAdd =3; else if(dow == DayOfWeek.SATURDAY) dayToAdd = 2; // 这里没有判断周日,因为周日到周一也是1天,默认就是移动一天,所以周日和一至周五一样。 return temporal.plus(dayToAdd, ChronoUnit.DAYS); } public static void main(String[] args) { LocalDate date = LocalDate.of(2021, 7, 25); /* 如果你已经有一个LocalDate对象,想要创建它的一个修改版,最直接也最简单的方法是使 用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属 性。 */ date = date.with(new NextWorkingDay()); // 创建副本,修改属性 System.out.println(date); // 第二种方式,函数式直接实现接口 date = date.with(temporal -> { DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); int dayToAdd = 1; if (dow == DayOfWeek.FRIDAY) dayToAdd = 3; else if (dow == DayOfWeek.SATURDAY) dayToAdd = 2; return temporal.plus(dayToAdd, ChronoUnit.DAYS); }); System.out.println(date); // 第三种方式,如果你想要使用Lambda表达式定义TemporalAdjuster对象,推荐使用TemporalAdjusters类的静态工厂方法ofDateAdjuster TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(temporal -> { DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK)); int dayToAdd = 1; if (dow == DayOfWeek.FRIDAY) dayToAdd = 3; if (dow == DayOfWeek.SATURDAY) dayToAdd = 2; return temporal.plus(dayToAdd, ChronoUnit.DAYS); }); date = date.with(nextWorkingDay); System.out.println(date); } }