Java8新特性之日期处理(日期格式化)

目录

新的时间处理API

15.1 日期/时间

15.2 时间戳

15.3 计算日期/时间间隔

15.4 时间矫正器

15.5 格式化日期/时间

15.6 时区日期/时间


新的时间处理API

  • 传统日期处理的方式线程不安全(多线程的环境下)

  • Java8的日期处理方式线程是安全的(多线程的环境下)

 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.*;
 ​
 /**
  * Java8之前的 日期处理方式(线程不安全) 多线程情况下会抛异常 
  */
 public class DateTest {
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
 ​
         Callable<Date> task = new Callable<Date>() {
             @Override
             public Date call() throws Exception {
                 return dateFormat.parse("2018-12-12");
             }
         };
         ExecutorService service = Executors.newFixedThreadPool(10);
         List<Future<Date>> results = new ArrayList<>();
 ​
         for (int i = 0; i < 10; i++) {
             results.add(service.submit(task));
         }
 ​
         for (Future<Date> result : results) {
             System.out.println(result.get());
         }
         service.shutdown();
     }
 }
 ​
 Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: "11.E111E"
     at java.util.concurrent.FutureTask.report(FutureTask.java:122)
     at java.util.concurrent.FutureTask.get(FutureTask.java:192)
     at DateTest.main(DateTest.java:34)
 Caused by: java.lang.NumberFormatException: For input string: "11.E111E"
     at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
     at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
     at java.lang.Double.parseDouble(Double.java:538)
     at java.text.DigitList.getDouble(DigitList.java:169)
     at java.text.DecimalFormat.parse(DecimalFormat.java:2089)
     at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1867)
     at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
     at java.text.DateFormat.parse(DateFormat.java:364)
     at DateTest$1.call(DateTest.java:21)
     at DateTest$1.call(DateTest.java:18)
     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
     at java.lang.Thread.run(Thread.java:748)

解决办法:

传统方式

 import java.text.DateFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 public class ThreadLocalDateFormat  {
     private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
         protected DateFormat initialValue() {
             return new SimpleDateFormat("yyyyMMdd");
         }
     };
 ​
     public static Date convert(String source) throws ParseException {
         return df.get().parse(source);
     }
 }
 ​
 package time;
 ​
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.concurrent.*;
 ​
 public class TimeTest {
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         Callable<Date> task = new Callable<Date>() {
             @Override
             public Date call() throws Exception {
                 return ThreadLocalDateFormat.convert("20181020");
             }
         };
         ExecutorService service = Executors.newFixedThreadPool(10);
         List<Future<Date>> results = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
             results.add(service.submit(task));
         }
 ​
         for (Future<Date> result : results) {
             System.out.println(result.get());
         }
         service.shutdown();
     }
 }

Java8处理方式

 public class TimeTest {
     public static void main(String[] args) throws ExecutionException, InterruptedException {
         DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMdd");
         Callable<LocalDate> task = new Callable<LocalDate>() {
             @Override
             public LocalDate call() throws Exception {
                 return LocalDate.parse("20161212", df);
             }
         };
 ​
         ExecutorService service = Executors.newFixedThreadPool(10);
         List<Future<LocalDate>> results = new ArrayList<>();
         for (int i = 0; i < 10; i++) {
             results.add(service.submit(task));
         }
 ​
         for (Future<LocalDate> result : results) {
             System.out.println(result.get());
         }
         service.shutdown();
     }
 }

15.1 日期/时间

LocalDate(日期)、LocalTime(时间)、LocalDateTime(日期和时间)

 public class TimeTest02 {
     public static void main(String[] args) {
         LocalDateTime ldt = LocalDateTime.now();
         System.out.println(ldt);//2019-08-05T11:24:09.013
 ​
         LocalDateTime ldt2 = LocalDateTime.of(2018, 8, 5, 11, 24, 15);
         System.out.println(ldt2);//2018-08-05T11:24:15
                 // 对日期进行加操作
                 LocalDateTime ldt3 = ldt.plusYears(2);
         System.out.println(ldt3);//2021-08-05T11:27:01.479
         //对日期进行减操作
         LocalDateTime ldt4 = ldt.minusMonths(2);
         System.out.println(ldt4);//2019-06-05T11:28:38.154
             
         System.out.println(ldt.getYear());
         System.out.println(ldt.getMonthValue());
         System.out.println(ldt.getDayOfMonth());
         System.out.println(ldt.getHour());
         System.out.println(ldt.getMinute());
         System.out.println(ldt.getSecond());
     }
 }

15.2 时间戳

Instant(时间戳):以Unix元年:1970年1月1日00:00:00到某个时间的毫秒值

 Instant ins1 = Instant.now();//默认获取UTC时区
 System.out.println(ins1);//2019-08-05T03:40:20.398Z
 ​
 OffsetDateTime odt = ins1.atOffset(ZoneOffset.ofHours(8));
 System.out.println(odt);//2019-08-05T11:40:20.398+08:00(北京时间)
 ​
 System.out.println(ins1.toEpochMilli());//1564976586686
 ​
 Instant ins2 = Instant.ofEpochSecond(60);
 System.out.println(ins2);//1970-01-01T00:01:00Z

 

15.3 计算日期/时间间隔

Duration:计算俩个"时间"之间的间隔

 //Duration 方式一
 Instant now1 = Instant.now();
 ​
 try {
   Thread.sleep(1000);
 } catch (InterruptedException e) {
   e.printStackTrace();
 }
 Instant now2 = Instant.now();
 ​
 System.out.println(Duration.between(now1,now2).toMillis());
 ​
 LocalTime local1 = LocalTime.now();
 //Duration 方式二
 try {
   Thread.sleep(1000);
 } catch (InterruptedException e) {
   e.printStackTrace();
 }
 LocalTime local2 = LocalTime.now();
 ​
 System.out.println(Duration.between(local1,local2).toMillis());

Period:计算俩个"日期"之间的间隔

 LocalDate localDate1 = LocalDate.of(2015, 1, 1);
 LocalDate localDate2 = LocalDate.now();
 Period period = Period.between(localDate1, localDate2);
 System.out.println(period.getYears());
 System.out.println(period.getMonths());
 System.out.println(period.getDays());

15.4 时间矫正器

  • TemporalAdjuster:时间矫正器。有时我们可能需要获取例如:将日期调整到"下一个周日"等操作

  • TemporalAdjusters:该类通过静态方法提供了大量的常用TemporalAdjuster的实现

    例如:

     //获取下一个周日:
     LocalDate date = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
     System.out.println(date);
     ​
     //获取下一个工作日
     LocalDateTime dateTime = LocalDateTime.now().with((dom) -> {
                 LocalDateTime time = (LocalDateTime) dom;
                 DayOfWeek dayOfWeek = time.getDayOfWeek();
                 if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                     return time.plusDays(3);
                 } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                     return time.plusDays(2);
                 } else {
                     return time.plusDays(1);
                 }
             });
             System.out.println(dateTime);

15.5 格式化日期/时间

 DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
 LocalDateTime ldt = LocalDateTime.now();
 String format = ldt.format(dtf);
 System.out.println(format); //2019-08-06
 ​
 DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 String str2 = ldt.format(pattern);
 System.out.println(str2); //2019-08-06 16:38:23
 ​
 LocalDateTime localDateTime = ldt.parse(str2,pattern);
 System.out.println(localDateTime); //2019-08-06T16:38:23

15.6 时区日期/时间

ZonedDate、ZonedTime、ZonedDateTime

 //获取所有的时区
 ZoneId.getAvailableZoneIds().forEach(System.out::println);
 ​
 //获取指定时区当前的时间值
 LocalDateTime ldt1 = LocalDateTime.now(ZoneId.of("Hongkong"));
 System.out.println(ldt1);
 ​
 //LocalDateTime转为ZonedDateTime
 LocalDateTime ldt2 = LocalDateTime.now();
 ZonedDateTime zdt1 = ldt2.atZone(ZoneId.of("Hongkong"));
 System.out.println(zdt1);

15.6 LocalDateTime和java.lang.Date之前的转换

Date to LocalDateTime

Date todayDate = new Date();

LocalDateTime ldt = todayDate.toInstant()
        .atZone( ZoneId.systemDefault() )
        .toLocalDateTime();

System.out.println(ldt); //2020-11-19T16:29:12.773

LocalDateTime to Date

LocalDateTime localDateTime = LocalDateTime.now();

Date date = Date.from( localDateTime.atZone( ZoneId.systemDefault()).toInstant());

System.out.println(date);
//Thu May 16 16:32:37 CST 2020

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值