java8日期时间格式总结

传统的java日期时间格式和Java8的日期时间格式最大的不同就是现成安全

public class TestDate {
    public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        Callable<Date> callable = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return sdf.parse("20161121");

            }
        };

        //创建大小为10的线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        //把格式化的结构放入集合中
        List<Future<Date>> results = new ArrayList<>();
        //执行
        for (int i=0; i<10; i++){
            results.add(pool.submit(callable));
        }
        //打印
        for (Future<Date> future: results){
            System.out.println(future.get());
        }

        pool.shutdown();
    }
}

你会得到一个这样的异常

解决办法就是加锁,这也是传统的解决方案

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * 时间日期总结
 */
public class TestDate {
    public static void main(String[] args) throws Exception{

        Callable<Date> callable = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return DateFormatThreadLocal.convert("20161121");

            }
        };

        //创建大小为10的线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        //把格式化的结构放入集合中
        List<Future<Date>> results = new ArrayList<>();
        //执行
        for (int i=0; i<10; i++){
            results.add(pool.submit(callable));
        }
        //打印
        for (Future<Date> future: results){
            System.out.println(future.get());
        }

        pool.shutdown();
    }

    static class DateFormatThreadLocal{

        private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
          protected DateFormat initialValue(){
              return new SimpleDateFormat("yyyyMMdd");
          }
        };

        public static  final Date convert(String source) throws ParseException {
            return df.get().parse(source);
        }
    }

}

用上Java8的日期后就不用担心线程安全的问题了

import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * 时间日期总结
 */
public class TestDate {
    public static void main(String[] args) throws Exception{

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");

        Callable<LocalDate> callable = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
                return LocalDate.parse("20161121",dtf);
            }
        };

        //创建大小为10的线程池
        ExecutorService pool = Executors.newFixedThreadPool(10);
        //把格式化的结构放入集合中
        List<Future<LocalDate>> results = new ArrayList<>();
        //执行
        for (int i=0; i<10; i++){
            results.add(pool.submit(callable));
        }
        //打印
        for (Future<LocalDate> future: results){
            System.out.println(future.get());
        }

        pool.shutdown();
    }
}

看一下新的java8API大概的分布,都是在java.time包下的

LocalDate、LocalTime、LocalDateTime

看一下这三个类的用法,会用一个其他的都差不多的

​
/**
 * 时间日期总结
 */
public class TestDate {
    public static void main(String[] args) throws Exception{
        // 获取当前系统的的时间日期
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);

        // 手动指定日期时间
        LocalDateTime ld2 = LocalDateTime.of(2016, 11, 21, 10, 10, 10);
        System.out.println(ld2);

        // 对日期事假的计算,加20年,可以加月,加日,加十分秒,包括LocalDate、LocalTime都可以加,能显示什么就能加什么
        LocalDateTime ldt3 = ld2.plusYears(20);
        System.out.println(ldt3);
        // 减
        LocalDateTime ldt4 = ld2.minusMonths(2);
        System.out.println(ldt4);
        //单独打印出年月日时分秒
        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());
        //LocalDate、LocalTime、LocalDateTime 这三个类的方法大致一样的,只不过操作的方法有点不同而已,比如时间日期类可以操作时间和日期,而日期类只能操作日期而不能操作时间
    }
}

​

Instant时间戳

public class TestDate {
    //2. Instant : 时间戳。 (使用 Unix 元年  1970年1月1日 00:00:00 所经历的毫秒值)
    public static void main(String[] args) throws Exception{
        Instant ins = Instant.now();  //默认使用 UTC 时区(世界协调时间)
        System.out.println(ins);

        OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));//偏移量计算,utc和北京时间差8小时
        System.out.println(odt);

        System.out.println(ins.toEpochMilli());//打印时间戳

        Instant ins2 = Instant.ofEpochSecond(1);//1970-01-01T00:00:00加上多少毫秒
        System.out.println(ins2);
    }
}

Duration : 用于计算两个“时间”间隔
Period : 用于计算两个“日期”间隔

public class TestDate {
    //Duration : 用于计算两个“时间”间隔
    //Period : 用于计算两个“日期”间隔
    public static void main(String[] args) throws Exception{
        Instant ins1 = Instant.now();

        System.out.println("--------------------");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        Instant ins2 = Instant.now();

        System.out.println("所耗费时间为(毫秒):" + Duration.between(ins1, ins2).toMillis());

        System.out.println("----------------------------------");

        LocalDate ld1 = LocalDate.now();
        LocalDate ld2 = LocalDate.of(2011, 1, 1);

        Period pe = Period.between(ld2, ld1);
        System.out.println(pe.getYears());
        System.out.println(pe.getMonths());
        System.out.println(pe.getDays());
    }
}

TemporalAdjuster : 时间校正器(比如下一个周日,下一年等操作)

public class TestDate {
    // TemporalAdjuster : 时间校正器(比如下一个周日,下一年等操作)
    public static void main(String[] args) throws Exception{
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);

        //比如月中的天指定为10
        LocalDateTime ldt2 = ldt.withDayOfMonth(10);
        System.out.println(ldt2);

        //如何下一个周日,TemporalAdjusters还有好多方法,自己查看API
        LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        System.out.println(ldt3);

        //自定义:下一个工作日
        LocalDateTime ldt5 = ldt.with((l) -> {
            LocalDateTime ldt4 = (LocalDateTime) l;
            //拿到目前是周几
            DayOfWeek dow = ldt4.getDayOfWeek();

            if(dow.equals(DayOfWeek.FRIDAY)){//如果是周五+3天
                return ldt4.plusDays(3);
            }else if(dow.equals(DayOfWeek.SATURDAY)){//如果是周6+2天
                return ldt4.plusDays(2);
            }else{//其他的都+1天
                return ldt4.plusDays(1);
            }
        });

        System.out.println(ldt5);
    }
}

DateTimeFormatter : 解析和格式化日期或时间

// DateTimeFormatter : 解析和格式化日期或时间
    public static void main(String[] args) throws Exception {
        // 可以用他规定好的格式
        //		DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;

        // 也可以自己定义格式化标准
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");

        //格式化
        LocalDateTime ldt = LocalDateTime.now();
        String strDate = ldt.format(dtf);
        System.out.println(strDate);

        //再解析回去
        LocalDateTime newLdt = ldt.parse(strDate, dtf);
        System.out.println(newLdt);
    }

ZonedDate、ZonedTime、ZonedDateTime : 带时区的时间或日期

//6.ZonedDate、ZonedTime、ZonedDateTime : 带时区的时间或日期
    @Test
    public void test7(){
        //获取一个指定时区构建一个时间
        LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println(ldt);

        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific"));
        System.out.println(zdt);
    }

    @Test
    public void test6(){
        //打印看一下java8支持多少时区
        Set<String> set = ZoneId.getAvailableZoneIds();
        set.forEach(System.out::println);
    }

猜你喜欢

转载自blog.csdn.net/qq_36125138/article/details/94635249