吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1132|回复: 3
收起左侧

[Java 转载] Java 8 笔记 全新的日期时间API

[复制链接]
saz 发表于 2021-11-29 10:50

全新的日期、时间API

线程安全问题

Date线程不安全问题

多线程操作,解析同一个日期字符串

public class Demo01 {
    /**
     * Date 线程不安全
     */
    @Test
    public void test01() throws ExecutionException, InterruptedException {
        List<Future<Date>> dates = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        ExecutorService pool = Executors.newFixedThreadPool(10);
        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return sdf.parse("2020-09-08");
            }
        };
        for (int i = 0; i < 100; i++) {
            dates.add(pool.submit(task));

        }
        for (Future<Date> date : dates) {
            System.out.println(date.get());
        }

    }

}

抛出NumberFormatException异常

Tue Sep 08 00:00:00 GMT+08:00 2020
Tue Sep 08 00:00:00 GMT+08:00 2020

java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: "220022.E220022E44"

Date线程解决方案-ThreadLocal

ThreadLocal处理

/**
 * @description: Date 线程不安全的解决方案-ThreadLocal
 */
public class Demo02 {

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){

        @Override
        protected DateFormat initialValue(){
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

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

    /**
     * Date 线程不安全,处理现场
     */
    @Test
    public void test01() throws ExecutionException, InterruptedException {
        List<Future<Date>> dates = new ArrayList<>();
        ExecutorService pool = Executors.newFixedThreadPool(10);
        Callable<Date> task = new Callable<Date>() {
            @Override
            public Date call() throws Exception {
                return convert("2020-09-08");
            }
        };
        for (int i = 0; i < 100; i++) {
            dates.add(pool.submit(task));

        }

        pool.shutdown();

        for (Future<Date> date : dates) {
            System.out.println(date.get());
        }

    }
}

线程安全的类-LocalDate

/**
 * @description: 使用LocalDate DateTimeFormatter 线程安全的类解决线程安全问题
 */
public class Demo03 {
    /**
     * LocalDate 线程安全的类
     */
    @Test
    public void test01() throws ExecutionException, InterruptedException {
        List<Future<LocalDate>> dates = new ArrayList<>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        ExecutorService pool = Executors.newFixedThreadPool(10);
        Callable<LocalDate> task = new Callable<LocalDate>() {
            @Override
            public LocalDate call() throws Exception {
                return LocalDate.parse("2020-09-08",dtf);
            }
        };
        for (int i = 0; i < 100; i++) {
            dates.add(pool.submit(task));

        }
        for (Future<LocalDate> date : dates) {
            System.out.println(date.get());
        }

    }
}

部分API示例

/**
 * @description: 新的类API
 */
public class TestLocalDateTime {

    // 创建对象
    static final LocalDateTime now = LocalDateTime.now();
    static final LocalDateTime point = LocalDateTime.of(2020, 9, 8, 15, 48, 35);
    @Test
    public void test01(){

        System.out.println(point); // 2020-09-08T15:48:35
        System.out.println(point.plusDays(1)); // 2020-09-09T15:48:35
        System.out.println(point.minusDays(1)); // 2020-09-07T15:48:35
        System.out.println(point.getMonth()); // SEPTEMBER
        System.out.println(point.getMonthValue()); // 9

    }

    /**
     * Unix元年
     */
    @Test
    public void test02(){
        Instant now = Instant.now(); // 默认获取UTC时区,世界协调时间
        System.out.println(now); // 2020-09-08T08:35:19.255Z
        System.out.println(now.toEpochMilli()); // 1599554269206
        OffsetDateTime fdt = now.atOffset(ZoneOffset.ofHours(8));
        System.out.println(fdt); // 2020-09-08T16:35:19.255+08:00
        System.out.println(fdt.toInstant()); // 2020-09-08T08:37:49.206Z
        System.out.println(fdt.toInstant().toEpochMilli()); // 1599554269206
    }

}

求始末日期工具类

/**
 * @description: 给定一个时间段的始末日期
 *              使用1.8的静态方法和全新的API
 */
public interface RangeUtils {

   /*
    *   昨天
    */
    static Range lastDay() {
        LocalDate now = LocalDate.now();
        return new Range(now.plusDays(-1), now.plusDays(-1));
    }

   /*
    *   本周,是否包含未来
    */
    static Range currentWeek(boolean includeFuture) {
        LocalDate now = LocalDate.now();
        LocalDate start = now.with(WeekFields.of(Locale.CHINESE).dayOfWeek(), 1);
        LocalDate end = includeFuture ? now.with(WeekFields.of(Locale.CHINESE).dayOfWeek(), 7) : now;
        return new Range(start, end);

    }

    /**
    *   本月,是否包含未来
    */
    static Range currentMonth(boolean includeFuture) {
        LocalDate now = LocalDate.now();
        LocalDate start = now.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate end = includeFuture ? now.with(TemporalAdjusters.lastDayOfMonth()) : now;
        return new Range(start, end);
    }

   /*
    *   前 month 个月的始末
    */
    static Range lastMonth(int month) {
        LocalDate now = LocalDate.now();
        LocalDate start = now.plusMonths(-month).with(TemporalAdjusters.firstDayOfMonth());
        LocalDate end = now.plusMonths(-month).with(TemporalAdjusters.lastDayOfMonth());
        return new Range(start, end);
    }

   /*
    *   前 week 个周的始末
    */
    static Range lastWeek(int week) {
        LocalDate now = LocalDate.now();
        LocalDate start = now.plusWeeks(-week).with(WeekFields.of(Locale.CHINESE).dayOfWeek(), 1);
        LocalDate end = now.plusWeeks(-week).with(WeekFields.of(Locale.CHINESE).dayOfWeek(), 7);
        return new Range(start, end);
    }

   /*
    * 指定日期到今天的始末
    */
    static Range untilToday(String yyyyMMdd) {
        LocalDate start = LocalDate.parse(yyyyMMdd, DateTimeFormatter.ofPattern("yyyy-MM-DD"));
        if (start.isAfter(LocalDate.now())) {
            throw new IllegalStateException(start + " is after today.");
        }
        return new Range(start, LocalDate.now());
    }

   /*
    * 转换指定起始日期
    */
    static Range range(String st1, String st2) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate start = LocalDate.parse(st1, dateTimeFormatter);
        LocalDate end = LocalDate.parse(st2, dateTimeFormatter);
        if (start.isAfter(end)) {
            throw new IllegalStateException(start + " is after " + end + ".");
        }
        return new Range(start, end);
    }

    /*
     * 日期的区间内部类
     */
    class Range {
        private final LocalDate start;
        private final LocalDate end;

        public Range(LocalDate start, LocalDate end) {
            this.start = start;
            this.end = end;
        }

        @Override
        public String toString() {
            return "Range{" +
                    "start=" + start +
                    ", end=" + end +
                    '}';
        }
    }
}

时间转化与比较

  • rstFulBody 为返回对象
  // 确认验证码是否过期
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime createdTime = smsCheckCode.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
if (Duration.between(createdTime, now).toMinutes() > 5) {
    // 过期提示已过期
    rstFulBody.fail("该验证码已过期,请重新获取验证码!");
    smsCheckCodeService.deleteByPrimaryKey(smsCheckCode.getCkCodeId());
    return rstFulBody;
}
LocalDateTime localDateTime=LocalDateTime.now()
Date date = Date.from(localDateTime.atZone( ZoneId.systemDefault()).toInstant());

Date startDate=new Date();
LocalDateTime localDateTime = startDate.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime()

当前所处在一年中的周数

LocalDateTime now = LocalDateTime.now();
DayOfWeek dayOfWeek = DayOfWeek.MONDAY;
WeekFields weekFields = WeekFields.of(dayOfWeek,1);
int weekInYear = now.get(weekFields.weekOfWeekBasedYear());
getWeekIndex(){
    // 截掉时分秒保留整数天
    var date=new Date(new Date().toLocaleDateString());
    //设置日期为当前周周四
    date.setDate(date.getDate()+(4-(date.getDay()||7)));
    var year=date.getFullYear();
    var firstDate=new Date(year,0,1);
    firstDate.setDate(firstDate.getDate()+(4-(firstDate.getDay()||7)));
    //当年第一天早于周四第一周延后七天
    if(firstDate.getFullYear()<year){
        firstDate.setDate(firstDate.getDate()+7);
    }
    //计算当前周和第一周之间周数差
    return Math.ceil(((date-firstDate)/86400000+1)/7);
},

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

nnfengxi 发表于 2021-11-29 13:49
学习,不知道java12有什么变化
 楼主| saz 发表于 2021-11-29 14:15
wiliao123 发表于 2021-11-29 14:25
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 09:37

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表