一:解决传统时间格式化线程安全问题
传统时间格式化使用SimpleDateFormat类,但SimpleDateFormat不是一个线程安全的类,在多线程中会报错
public static void main(String[] args) throws Exception{ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); Callable<Date> task = () -> sdf.parse("20190813"); ExecutorService pool = Executors.newFixedThreadPool(10); List<Future<Date>> results = new ArrayList<>(); for(int i = 0; i < 10; i++) { results.add(pool.submit(task)); } for(Future<Date> future : results) { System.out.println(future.get()); } }
执行这段代码会发现报 java.lang.NumberFormatException: multiple points异常。
在java8中使用DateTimeFormatter就可以解决这个问题
public static void main(String[] args) throws Exception{ DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd"); Callable<LocalDate> task = () -> LocalDate.parse("20190813", df); ExecutorService pool = Executors.newFixedThreadPool(10); List<Future<LocalDate>> results = new ArrayList<>(); for(int i = 0; i < 10; i++) { results.add(pool.submit(task)); } for(Future<LocalDate> future : results) { System.out.println(future.get()); } }
二:新时间与新日期类型
1.LocalDate、LocalTime、LocalDateTime
public static void newDateTime() { //获取当前时间 LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); //获取指定年月日时分秒的时间 LocalDateTime ldt2 = LocalDateTime.of(2019, 9, 13, 18, 8, 4); System.out.println(ldt2); //增加/减少年份,增加/减少月、日、周、时、分、秒同理 LocalDateTime ldt3 = ldt.plusYears(2); System.out.println(ldt3); LocalDateTime ldt4 = ldt.minusYears(2); System.out.println(ldt4); //获取年、月 System.out.println(ldt.getYear()); System.out.println(ldt.getMonthValue()); }
2.Instant:时间戳
public static void newInstant() { //Instant.now()默认获取UTC时区,UTC时区与北京时间有8小时偏差 Instant ins1 = Instant.now(); System.out.println(ins1); //设置与UTC时区的偏移 OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(8)); System.out.println(odt); //获取毫秒级时间戳 System.out.println(ins1.toEpochMilli()); }
3.Duration:计算两个时间之间的间隔;Period:计算两个日期之间的间隔
public static void calculateInterval() throws Exception{ Instant ins1 = Instant.now(); Thread.sleep(1000); Instant ins2 = Instant.now(); //计算两个时间之间的间隔 Duration duration = Duration.between(ins1, ins2); System.out.println(duration.toMillis()); LocalDate ld1 = LocalDate.of(2015, 3, 22); LocalDate ld2 = LocalDate.now(); //计算两个日期之间的间隔 Period period = Period.between(ld1, ld2); System.out.println(period); //获取日期间隔的年、月、日 System.out.println(period.getYears()); System.out.println(period.getMonths()); System.out.println(period.getDays()); }
4. TemporalAdjuster:时间校正器
public static void demoTemporalAdjuster() { LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1); //获取当月的第十天的日期 LocalDateTime ldt2 = ldt1.withDayOfMonth(10); System.out.println(ldt2); //获取下一个周末的日期 LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); System.out.println(ldt3); //自定义获取下一个工作日的日期 LocalDateTime ldt5 = ldt1.with((l) -> { LocalDateTime ldt4 = (LocalDateTime) l; DayOfWeek dayOfWeek = ldt4.getDayOfWeek(); if(dayOfWeek.equals(DayOfWeek.FRIDAY)) { return ldt4.plusDays(3); } else if(dayOfWeek.equals(DayOfWeek.SATURDAY)) { return ldt4.plusDays(2); } else { return ldt4.plusDays(1); } }); System.out.println(ldt5); }
5.格式化时间:DateTimeFormatter
public static void demoDateTimeFormatter() { LocalDateTime now = LocalDateTime.now(); //定义日期转换模式 DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); //日期格式化 String formatDateStr = df.format(now); System.out.println(formatDateStr); //转换日期 LocalDateTime newDate = LocalDateTime.parse(formatDateStr, df); System.out.println(newDate); }