java8时间类API安全问题(赠送新的时间工具类哟)

LocalDateTime等新出的日期类全是final修饰的类,不能被继承,且对应的日期变量都是final修饰的,也就是不可变类。赋值一次后就不可变,不存在多线程数据问题。

 

 

  simpleDateFormat.parse()
 simpleDateFormat.format()


注意calendar.setTime(date);,Calendar类是里面基本都是final修饰的,calendar是共享变量,并且这个共享变量没有做线程安全控制。
当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat,一般会封装在工具类,复用】调用format方法时,
多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。

在多并发情况下使用SimpleDateFormat需格外注意:

SimpleDateFormat除了format方法是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了

 

 

平时封装工具时,封装个静态的SimpleDataFormat
里面这个变量时共享变量,多线程时会出现这样的场景:
A先设置,B也来设置时间值,由于并发了,后面C也来设置值,导致A,B取的值可能时C设置的值

 

结尾送上个我个人封装java8新的时间工具类供大家使用

 

package cn.linkkids.refund.util;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class DateUtil0 {

    private DateUtil0() throws Exception {
        throw new Exception("时间工具禁止new");
    }

    public static final String YYYYMMDDHHMMSSS = "yyyyMMddHHmmss";
    public static final String YYYY_MM_DD_HH_DD_SS_TIME = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDDHHMMSSTIME = "yyyy/MM/dd HH:mm:ss";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYYMMDD = "yyyy/MM/dd";
    public static final String YYYYMMDDDATE = "yyyyMMdd";

    //根据时间格式化成指定格式日期yyyyMMddHHmmss的字符串
    public static String LocalDateTime_TO_YYYYMMDDHHMMSSS(LocalDateTime localDateTime) {
        //时间传唤为指定格式字符串
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSS));
    }

    //根据时间格式化成指定格式日期yyyy-MM-dd HH:mm:ss的字符串
    public static String LocalDateTime_TO_YYYY_MM_DD_HH_DD_SS_TIME(LocalDateTime localDateTime) {
        //时间传唤为指定格式字符串
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_DD_SS_TIME));
    }

    //根据时间格式化成指定格式日期yyyy/MM/dd HH:mm:ss的字符串
    public static String LocalDateTime_TO_YYYYMMDDHHMMSSTIME(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSTIME));
    }

    //根据时间格式化成指定格式日期yyyy-MM-dd的字符串
    public static String LocalDateTime_TO_YYYY_MM_DD(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYY_MM_DD));
    }

    //根据时间格式化成指定格式日期yyyy/MM/dd的字符串
    public static String getYYYYMMDD01(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDD));
    }

    //根据时间格式化成指定格式日期yyyyMMdd的字符串
    public static String LocalDateTime_TO_YYYYMMDDDATE(LocalDateTime localDateTime) {
        return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDDDATE));
    }

    /**
     * 以上是日期转换为指定格式字符串
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     *
     */


    //yyyy-MM-dd HH:mm:ss格式字符串 转化为时间
    public static LocalDateTime YYYY_MM_DD_HH_DD_SS_TIME_TO_LocalDateTime(String dateStr) {
        return  LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_DD_SS_TIME));
    }

    //YYYYMMDDHHMMSSS格式字符串 转化为时间
    public static LocalDateTime YYYYMMDDHHMMSSS_TO_LocalDateTime(String dateStr) {
        return LocalDateTime.parse(dateStr,  DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSS));
    }

    //yyyy/MM/dd HH:mm:ss 格式字符串 转化为时间
    public static LocalDateTime YYYYMMDDHHMMSSTIME_TO_LocalDateTime(String dateStr) {
        return LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSTIME));
    }

    //yyyy-MM-dd 格式字符串 转化为时间
    public static LocalDate COVERT_TO_YYYY_MM_DD_OF_LocalDateTime(String dateStr) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYY_MM_DD));
    }



    //yyyy/MM/dd 格式字符串 转化为时间
    public static LocalDate COVERT_TO_YYYYMMDD_TO_LocalDateTime(String dateStr) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYYMMDD));
    }
    //yyyyMMdd 格式字符串 转化为时间
    public static LocalDate COVERT_TO_YYYYMMDDDATE_OF_LocalDateTime(String dateStr) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYYMMDDDATE));
    }

    /**
     * 以上是指定格式字符串换为相应日期
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     *
     */



    //毫秒计时间戳
    public static Long covertLocalDateTimeToSecondsMillions(LocalDateTime localDateTime) {
        return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
    }

    //秒计时间戳
    public static Long covertLocalDateTimeToSeconds(LocalDateTime localDateTime) {
        return localDateTime.toEpochSecond(ZoneOffset.of("+8"));
    }

    /**
     * 以上是日期转化为时间戳
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     *
     */

    //秒级时间戳转化为LocalDateTime
    // 入参是这种  时间戳 long second = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
    public static LocalDateTime covertMillisecondsToLocalDateTimeWithZone0(Long seconds) {
        //当前市区时间
        LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(seconds, 0, ZoneOffset.ofHours(8));
        return localDateTime;
    }

    //秒级时间戳转化为LocalDateTime
    // 入参是这种  时间戳    long milliseconds = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    public static LocalDateTime covertMillisecondsToLocalDateTimeWithZone(Long milliseconds) {
        LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(milliseconds/1000, 0, ZoneOffset.ofHours(8));
        return localDateTime;
    }


    //精确毫秒级别 保留三位小数的那种
    //入参          long milliseconds = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
    public static LocalDateTime covertMillisecondsToLocalDateTime(Long milliseconds) {
        LocalDateTime localDateTime = Instant.ofEpochMilli(milliseconds).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
        return localDateTime;
    }



    /**
     * 以上是时间戳转化为日期
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
     *
     */

    //LocalDateTime 转化为 Date
    public static Date covertDateTimeTODateTime(LocalDateTime localDateTime){
        // 获得 Instant
        Instant instant = Instant.ofEpochSecond(localDateTime.toEpochSecond(ZoneOffset.ofHours(8)));
        // 获得 Date
        Date date = Date.from(instant);
        return  date;
    }

    //LocalDateTime 转化为 Date
    public static Date covertDateTimeTODateTime_1(LocalDateTime localDateTime){
        // 获得 Instant
        Instant instant = localDateTime.atZone(ZoneOffset.ofHours(8)).toInstant();
        // 获得 Date
        Date date = Date.from(instant);
        return  date;
    }

    //LocalDate 转化为 Date
    public static Date covertLocalDateTODate(LocalDate localDate){
        // 获得 Instant
        Instant instant = localDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant();
        // 获得 Date
        Date date = Date.from(instant);
        return  date;
    }

    // Date转化为  LocalDate
    public static LocalDate covertDateToLocalDate(Date date){
        // 获得  LocalDate
        LocalDate localDate = date.toInstant().atOffset(ZoneOffset.ofHours(8)).toLocalDate();
        return  localDate;
    }
}

 

posted @ 2021-08-27 14:03  余生请多指教ANT  阅读(116)  评论(0编辑  收藏  举报