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 ...
随机推荐
- 谷粒商城--分布式基础篇P28~P101(完结)
谷粒商城--分布式基础篇P28~P101(完结) 前面1-27节主要是环境配置特别难,后面的28~101节主要是前端编写的代码较多以及后台的CRUD操作比较多.因为内容很多,所以我是根据自己想学的点进 ...
- Bigdecimal用法
一.简介 Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数.在实际应用中,需要对更大或者更 ...
- leetcode最短无序连续子数组
平民解法: 既然是找最小数组,那就得到一个排序好的数组,然后直接和初试数组比对,用一个left,right分别记录从最初开始不同,到最后不同的小标,最后左右做差再加一,就能得到长度. 其他解法: 双指 ...
- 【FATE】设置虚拟机固定IP以及免密登录
一.前期准备 1.VMWare上新建三个Centos7的虚拟机 2.VMWare虚拟机的三种联网方式 1.桥接模式 -- 桥接: 默认使用VMnet0 这一种联网方式最简单,在局域网内,你的主机是怎么 ...
- 判断Windows系统是32位或64位并执行不同脚本命令
判断Windows系统是32位或64位并执行不同脚本命令 https://www.autoahk.com/?p=16549&preview=true https://www.cnblogs.c ...
- 查看filesystem type及ftype的值
查看Filesystem type df -Th 查看ftype xfs_info [filesystem_name] | grep ftype
- Nature Cancer | 宋尔卫/苏士成团队揭示lncRNA调控巨噬细胞“双刃剑”作用新机制
巨噬细胞 (macrophage, Mϕ) 是先天免疫系统中重要的免疫细胞,也是血液.淋巴和所有哺乳动物组织类型中最常见的吞噬细胞,具有极强的功能多样性.其中,肿瘤微环境组织中存在的巨噬细胞也被称作肿 ...
- 随着日益增多的新技术,Android开发接下来的路该怎么走?
很多小伙伴们经常问我android移动开发者的走向,一部分人都想多快好省,间歇性踌躇满志.持续性混吃等死 ,只想用CV的开发模式们快速完成工作,然后回家王者农药.其实这种现象很普遍,我想告诉你的是 , ...
- small-spring 代码贡献者3个月,敢说精通Spring了,分享我的总结!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.为什么手写Spring 这个与我们码农朝夕相处的 Spring,就像睡在你身边的媳妇,你知 ...
- C++STL—string类
string容器 1.1 string容器的基本概念 string容器是一个类 这个容器中有一个指针,指针维护了一个数组 string容器提供copy.find.insert.replace等等功能 ...