ThreadLocal
public class Test {
private static final ThreadLocal<SimpleDateFormat> dbsdfLocal = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE);
}
};
private static final ThreadLocal<SimpleDateFormat> dbsdfSSSLocal = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.SIMPLIFIED_CHINESE);
}
};
public static void main(String[] args) {
SimpleDateFormat dbsdfSSS = dbsdfLocal.get();
if(dbsdfSSS == null){
dbsdfSSS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE);
}
System.out.println(dbsdfSSS.format(new Date()));
}
}
JDK1.8中的时间类
博客地址:
一、使用的原因
在JDK8发布的时候,推出了LocalDate、LocalTime、LocalDateTime这个三个时间处理类,以此来弥补之前的日期时间类的不足,简化日期时间的操作。
在Java8之前,处理日期时间的类是Date、Calendar,这两个在使用起来总是让人感觉不是很舒服,在设计上面有一些缺陷,并且还不是线程安全的。
最重要的一点,公司的重构项目要用到了mybatis-plus框架,这个框架自动生成映射文件的工具会将MySQL中的datetime类型转化成Java中的LocalDateTime类型,由于几次都出现了转化错误、转化繁琐的问题
因此,就打算详细的了解一下Java中的时间类的相关知识
二、科普前置需求
1.了解时区
我们平时在程序里面所见到的UTC时间,就是零时区的时间,它的全称是Coordinated Universal Time ,即世界协调时间。另一个常见的缩写是GMT,即格林威治标准时间
格林威治位于 零时区,因此,我们平时说的UTC时间和GMT时间在数值上面都是一样的。
日常中我们中国基本都是以北京时间为标准,也就是一下图中东八区,这里的一个区基本就是一个小时的时差,
2.由此可以总结
①时间戳: 是指格林威治(地球零时区)时间1970年01月01日00时00分00秒起至现在的总秒数,这个时间戳,在地球的各个地方都是一致的;
②时区:由于地球的自转,根据接收太阳光照的顺序将地球划分成24个区,从而方便当地人的生产生活,每个时区相差一小时,可以根据时间戳和时区计算当地的时间。
③格林威治处于零时区,北京处于东八区,因此,北京时间比格林威治时间早8个小时。这也就是转换时间中的(+8)由来
三、基本使用
/**
* locaDateTime工具类的使用
*/
@Test
void locaDateTime()
{
// 获取当前时区的日期
LocalDate localDate = LocalDate.now();
// localDate: 2021-09-17
System.out.println("localDate: " + localDate);
// 时间
LocalTime localTime = LocalTime.now();
// localTime: 20:50:04.384
System.out.println("localTime: " + localTime);
// 根据上面两个对象,获取日期时间
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
// localDateTime: 2021-09-17T20:50:04.384
System.out.println("localDateTime: " + localDateTime);
// 使用静态方法生成此对象
LocalDateTime localDateTime2 = LocalDateTime.now();
// localDateTime2: 2021-09-17T20:50:04.384
System.out.println("localDateTime2: " + localDateTime2);
// 格式化时间
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
// 格式化之后的时间: 2021-09-17 20:50:04
System.out.println("格式化之后的时间: " + localDateTime2.format(formatter));
// 转化为时间戳(秒)
long epochSecond = localDateTime2.toEpochSecond(ZoneOffset.of("+8"));
// 转化为毫秒
long epochMilli = localDateTime2.atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
// 时间戳为:(秒) 1631883004; (毫秒): 1631883004384
System.out.println("时间戳为:(秒) " + epochSecond + "; (毫秒): " + epochMilli);
// 时间戳(毫秒)转化成LocalDateTime
Instant instant = Instant.ofEpochMilli(epochMilli);
LocalDateTime localDateTime3 = LocalDateTime.ofInstant(instant, ZoneOffset.systemDefault());
// 时间戳(毫秒)转化成LocalDateTime: 2021-09-17 20:50:04
System.out.println("时间戳(毫秒)转化成LocalDateTime: " + localDateTime3.format(formatter));
// 时间戳(秒)转化成LocalDateTime
Instant instant2 = Instant.ofEpochSecond(epochSecond);
LocalDateTime localDateTime4 = LocalDateTime.ofInstant(instant2, ZoneOffset.systemDefault());
// 时间戳(秒)转化成LocalDateTime: 2021-09-17 20:50:04
System.out.println("时间戳(秒)转化成LocalDateTime: " + localDateTime4.format(formatter));
}
四、场景使用(有好的场景可以私聊发我,我会加上来)
1、获取时间戳
/**
* 获取北京时间戳:of("+8") 和 ofHours(8)意义相同
*
* @author 王子威
*/
@Test
void locaDateTime()
{
//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));
// second = 1631887657
System.out.println("second = " + second);
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
// milliSecond = 1631887657941
System.out.println("milliSecond = " + milliSecond);
}
2、根据年月获取对应时间
/**
* 根据年-月获取对应时间
*
*/
@Test
public void testLocalDateTimeUtil()
{
// 获取月初时间
LocalDateTime monthStatus = LocalDateTimeUtil.parseDate("2022-02", "yyyy-MM").atTime(LocalTime.MIN)
.with(TemporalAdjusters.firstDayOfMonth());
// monthStatus = 2022-2-1 59:59:59
System.out.println("monthStatus = " + monthStatus);
// 获取月末时间
LocalDateTime monthEnd = LocalDateTimeUtil.parseDate("2022-02", "yyyy-MM").atTime(LocalTime.MAX)
.with(TemporalAdjusters.lastDayOfMonth());
// monthEnd = 2022-2-28 59:59:59
System.out.println("monthEnd = " + monthEnd);
}