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 util.bloomfilter; 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; /**
* java8时间工具类
*/
public class DateUtil {
private DateUtil() 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 getYYYYMMDDHHMMSSS(LocalDateTime localDateTime) {
//时间传唤为指定格式字符串
return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSS));
} //根据时间格式化成指定格式日期yyyy-MM-dd HH:mm:ss的字符串
public static String getYYYY_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 getYYYYMMDDHHMMSSTIME(LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ofPattern(YYYYMMDDHHMMSSTIME));
} //根据时间格式化成指定格式日期yyyy-MM-dd的字符串
public static String getYYYYMMDD(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 getYYYYMMDDDATE(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 YYYY_MM_DD_TO_LocalDateTime(String dateStr) {
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYY_MM_DD));
} //yyyy/MM/dd 格式字符串 转化为时间
public static LocalDate YYYYMMDD_TO_LocalDateTime(String dateStr) {
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYYMMDD));
}
//yyyyMMdd 格式字符串 转化为时间
public static LocalDate YYYYMMDDDATE_TO_LocalDateTime(String dateStr) {
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(YYYYMMDDDATE));
} /**
* 以上是指定格式字符串换为相应日期
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*
*/ //毫秒计时间戳
public static Long getMillionsTime(LocalDateTime localDateTime) {
return localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
} //秒计时间戳
public static Long getSeconds(LocalDateTime localDateTime) {
return localDateTime.toEpochSecond(ZoneOffset.of("+8"));
} /**
* 以上是日期转化为时间戳
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*
*/ //秒级时间戳转化为LocalDateTime
// 入参是这种 时间戳 long second = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
public static LocalDateTime getSeconds(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 milliseconds(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 millisecondsppoint(Long milliseconds) {
LocalDateTime localDateTime = Instant.ofEpochMilli(milliseconds).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
return localDateTime;
} /**
* 以上是时间戳转化为日期
* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*
*/ //LocalDateTime 转化为 Date
public static Date getLocalDateTime_TO_DateTime(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 getLocalDateTime_TO_DateTime0(LocalDateTime localDateTime){
// 获得 Instant
Instant instant = localDateTime.atZone(ZoneOffset.ofHours(8)).toInstant();
// 获得 Date
Date date = Date.from(instant);
return date;
} //LocalDate 转化为 Date
public static Date getLocalDate_TO_Date(LocalDate localDate){
// 获得 Instant
Instant instant = localDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant();
// 获得 Date
Date date = Date.from(instant);
return date;
} // Date转化为 LocalDate
public static LocalDate getLocalDate(Date date){
// 获得 LocalDate
LocalDate localDate = date.toInstant().atOffset(ZoneOffset.ofHours(8)).toLocalDate();
return localDate;
} public static void main(String[] args) {
// String str="2021-08-27 10:41:22";
// System.out.println(DateUtil.YYYY_MM_DD_HH_DD_SS_TIME_TO_LocalDateTime(str));
// String str0="20210827104122";
// System.out.println(DateUtil.YYYYMMDDHHMMSSS_TO_LocalDateTime(str0));
// String str1="2021/08/27 10:41:22";
// System.out.println(DateUtil.YYYYMMDDHHMMSSTIME_TO_LocalDateTime(str1));
// String str2="2021-08-27";
// System.out.println(DateUtil.YYYY_MM_DD_TO_LocalDateTime(str2));
// String str3="2021/08/27";
// System.out.println(DateUtil.YYYYMMDD_TO_LocalDateTime(str3));
// String str4="20210827";
// System.out.println(DateUtil.YYYYMMDDDATE_TO_LocalDateTime(str4)); //秒转化为日期
// long second = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
// System.out.println(second);
// System.out.println(DateUtil.getSeconds(second));
//
//毫秒转化日期
// long milliseconds = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
// System.out.println(milliseconds);
// System.out.println(DateUtil.milliseconds(milliseconds));
//毫秒转化为毫秒精确级别日期
// long millisecondss = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
// System.out.println(millisecondss);
// System.out.println(DateUtil.millisecondsppoint(millisecondss)); System.out.println(DateUtil.getLocalDateTime_TO_DateTime(LocalDateTime.now()));
System.out.println(DateUtil.getLocalDate_TO_Date(LocalDate.now()));
System.out.println(DateUtil.getLocalDate(new Date())); } }
java8时间类API安全问题(赠送新的时间工具类哟)的更多相关文章
- Expo大作战(二十七)--expo sdk api之Util(expo自带工具类),tackSnapshotAsync,Svg,SQLite
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习
c#中@标志的作用 参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...
- BadgeView新提示开源工具类
BadgeView是使用某个图标作为新功能的提醒,类似于收到短息后短信图标的右上方有信息数目或者其他的显示性提示.BadgeView很好的实现了这个功能,而且进行了拓展,可自定义位置和提示图标. 工具 ...
- 【转载】C#工具类:实现文件操作File的工具类
在应用程序的开发中,文件操作的使用基本上是必不可少的,FileStream类.StreamWriter类.Directory类.DirectoryInfo类等都是文件操作中时常涉及到的类,我们可以通过 ...
- mybatis的基本配置:实体类、配置文件、映射文件、工具类 、mapper接口
搭建项目 一:lib(关于框架的jar包和数据库驱动的jar包) 1,第一步:先把mybatis的核心类库放进lib里
- UUID与System.currentTimeMillis()产生一个新文件名的工具类
1.FileUtils.java package Utils.GenerateNewFileName; import java.util.UUID; public class FileUtils { ...
- Vcode的生成工具类,生成制定长度验证码,图文验证码工具类
public class VCodeUtils { // 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符 public static f ...
- 【工具类】获取Http请求IP的工具类
public class IpAddressUtil { public static String getIpAddr(HttpServletRequest request){ String ipAd ...
- 【工具类】获取请求头中User-Agent工具类
public class AgentUserKit { private static String pattern = "^Mozilla/\\d\\.\\d\\s+\\(+.+?\\)&q ...
随机推荐
- 离散数学-传递闭包(POJ3275)
就是n的元素给定m个关系求他们之间的关系. eg. ∵a>b and b>c ∴a>c emmmm 若要知道n个元素的绝对关系,则需知道C(n,2)个关系. 例题:POJ3275 ...
- odoo14通过命令行启动以及报错进不去系统问题解决办法
一.通过CMD命令界面启动odoo:进入odoo-bin目录下:执行 python odoo-bin -c odoo.conf 二.pycharm配置自动安装升级模块:-c E:\odoo14\od ...
- 福利!Python制作动态字符画(附源码)
字符画,一种由字母.标点.汉字或其他字符组成的图画.简单的字符画是利用字符的形状代替图画的线条来构成简单的人物.事物等形象,它一般由人工制作而成:复杂的字符画通常利用占用不同数量像素的字符代替图画上不 ...
- SpringBoot添加Cors跨域配置,解决No 'Access-Control-Allow-Origin' header is present on the requested resource
目录 什么是CORS SpringBoot 全局配置CORS 拦截器处理预检请求 什么是CORS 跨域(CORS)请求:同源策略/SOP(Same origin policy)是一种约定,由Netsc ...
- 大数据学习(04)——MapReduce原理
前两篇文章介绍了HDFS的原理和高可用,下面再来介绍Hadoop的另外一个模块MapReduce.它的思想是很多技术的鼻祖,值得一学. MapReduce是什么 MapReduce是一个分布式计算系统 ...
- 从 HTTP 切换到 HTTPS,这下我的技术博客安全了吧?
博客园 的小伙伴们,大家好,我是刚脱离险境的二哥呀! 很久(大概两年)之前,我就搞了一个独立的个人博客网站,长下面这样. 大家有访问过的,可以在评论区扣 1 可惜一直没搞备案和 HTTPS,导致每次访 ...
- noi linux 2.0 体验
一.起因 下午,我打开 noi 官网准备报名 csp j/s,一看官网展板:"noi linux 2.0 发布" 我就兴奋了起来.(9 月 1 日起开始使用, 也就意味着 csp ...
- Java流程控制02——顺序结构
- 串、KMP模式匹配算法
串是由0个或者多个字符组成的有限序列,又名叫字符串. 串的比较: 串的比较是通过组成串的字符之间的编码来进行的,而字符的编码指的是字符在对应字符集中的序号. 计算机中常用的ASCII编码,由8位二进制 ...
- 如何在idea中配置Tomcat服务器
.IDEA 中动态 web 工程的操作 a)IDEA 中如何创建动态 web 工程 1.创建一个新模块: 2.选择你要创建什么类型的模块 3.输入你的模块名,点击[Fin ...