你还在用 Date?快使用 LocalDateTime 了!
在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?
通过阅读本篇文章你将了解到:
为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】;
java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改。
为什么需要LocalDate、LocalTime、LocalDateTime
1.Date如果不格式化,打印出的日期可读性差
Tue Sep 10 09:34:04 CST 2019
2.使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的SimpleDateFormat的format方法最终调用代码:
private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) { // Convert input date to time field list calendar.setTime(date); boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledPattern.length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i++] & 0xff; if (count == 255) { count = compiledPattern[i++] << 16; count |= compiledPattern[i++]; } switch (tag) { case TAG_QUOTE_ASCII_CHAR: toAppendTo.append((char)count); break; case TAG_QUOTE_CHARS: toAppendTo.append(compiledPattern, i, count); i += count; break; default: subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); break; } } return toAppendTo;
}
calendar是共享变量,并且这个共享变量没有做线程安全控制。关注微信公众号:互联网架构师,在后台回复:2T,可以获取教程,都是干货。
当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值
另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。
在多并发情况下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。
parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了
a、重置日期对象cal的属性值b、使用calb中中属性设置calc、返回设置好的cal对象
但是这三步不是原子操作
多线程并发如何保证线程安全 - 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大 - 对使用format和parse方法的地方进行加锁 => 线程阻塞性能差 - 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法
1.Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但都被弃用了啊
Come On 一起使用java8全新的日期和时间API
LocalDate
只会获取年月日
创建LocalDate
//获取当前年月日
LocalDate localDate = LocalDate.now();
//构造指定的年月日
LocalDate localDate1 = LocalDate.of(2019, 9, 10);
获取年、月、日、星期几
int year = localDate.getYear();
int year1 = localDate.get(ChronoField.YEAR);
Month month = localDate.getMonth();
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.getDayOfMonth();
int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);
LocalTime
只会获取几点几分几秒
创建LocalTime
LocalTime localTime = LocalTime.of(13, 51, 10);
LocalTime localTime1 = LocalTime.now();
获取时分秒
//获取小时
int hour = localTime.getHour();
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
//获取分
int minute = localTime.getMinute();
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
//获取秒
int second = localTime.getSecond();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
LocalDateTime
获取年月日时分秒,等于LocalDate+LocalTime
创建LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);
获取LocalDate
LocalDate localDate2 = localDateTime.toLocalDate();
获取LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();
Instant
获取秒数
创建Instant对象
Instant instant = Instant.now();
获取秒数
long currentSecond = instant.getEpochSecond();
获取毫秒数
long currentMilli = instant.toEpochMilli();
个人觉得如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()来得更为方便
修改LocalDate、LocalTime、LocalDateTime、Instant
LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本
增加、减少年数、月数、天数等 以LocalDateTime为例
LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
//增加一年
localDateTime = localDateTime.plusYears(1);
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
//减少一个月
localDateTime = localDateTime.minusMonths(1);
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
通过with修改某些值
//修改年为2019
localDateTime = localDateTime.withYear(2020);
//修改为2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
还可以修改月、日
时间计算
比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());
比如通过firstDayOfYear()返回了当前日期的第一天日期,还有很多方法这里不在举例说明
格式化时间
LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
//自定义格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);
DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,
可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式
解析时间
LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);
和SimpleDateFormat相比,DateTimeFormatter是线程安全的
小结
LocalDateTime:Date有的我都有,Date没有的我也有,日期选择请Pick Me
SpringBoot中应用LocalDateTime
将LocalDateTime字段以时间戳的方式返回给前端添加日期转化类
public class LocalDateTimeConverter extends JsonSerializer{ @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli()); }
}
并在LocalDateTime字段上添加@JsonSerialize(using = LocalDateTimeConverter.class)注解,如下:
@JsonSerialize(using = LocalDateTimeConverter.class)
protected LocalDateTime gmtModified;
将LocalDateTime字段以指定格式化日期的方式返回给前端 在LocalDateTime字段上添加@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")注解即可,如下:
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;
对前端传入的日期进行格式化 在LocalDateTime字段上添加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解即可,如下:
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;
作者:何甜甜在吗
https://juejin.im/post/5d7787625188252388753eae
关注微信公众号:互联网架构师,在后台回复:2T,可以获取我整理的教程,都是干货。
猜你喜欢
1、GitHub 标星 3.2w!史上最全技术人员面试手册!FackBoo发起和总结
2、如何才能成为优秀的架构师?
3、从零开始搭建创业公司后台技术栈
4、程序员一般可以从什么平台接私活?
5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...
6、滴滴业务中台构建实践,首次曝光
7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事
8、15张图看懂瞎忙和高效的区别
9、2T架构师学习资料干货分享
你还在用 Date?快使用 LocalDateTime 了!相关推荐
- 【Java】什么?你项目还在用Date表示时间?!日期类LocalDateTime的使用
什么?你项目还在用Date表示时间?! 这都什么年代了,怎么还在用 Date来处理和表示时间! 别的先不说,我们先来看几个关于 Date用法的例子,这玩意真的好用吗? 一.我想新建一个表示" ...
- 什么?你项目还在用Date表示时间?!
为啥会有这篇文章 最近接手了一个别人的老项目,拿到代码,导入IDEA的那一瞬间,我哭出了声 . . . 我瞥了一眼代码,就知道这次肯定遇到了屎山!因为我看到了这种代码: 我擦,这都什么年代了,怎么 ...
- 什么?你项目还在用Date表示时间?
为啥会有这篇文章 最近接手了一个别人的老项目,拿到代码,导入IDEA的那一瞬间,我哭出了声 . . . 我瞥了一眼代码,就知道这次肯定遇到了屎山!因为我看到了这种代码: 我擦,这都什么年代了,怎么 ...
- 日期上午下午怎么用date存_Java12都要出来了,你还在使用Date操作日期吗?
Java12都要出来了,你还在使用Date操作日期吗? 如果你想要用Date表示Java8的发布日期(2014年3月18日),需要创建这样的Date实例: Date date = new Date(1 ...
- java lang ill_请MATLAB高手帮忙我的MATLAB老出现以下东西,这些东东还刷的挺快,不按ESC都不停止.java.lang.Ill...
请MATLAB高手帮忙我的MATLAB老出现以下东西,这些东东还刷的挺快,不按ESC都不停止.java.lang.Ill 请MATLAB高手帮忙 我的MATLAB老出现以下东西, 这些东东还刷的挺快, ...
- 你还在用 Date?建议使用 LocalDateTime 了!
在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗? 通过阅读本篇文章你将了解到: 为什么需要LocalDate.Loc ...
- Java精粹--Date/Calendar/JodaTime/LocalDateTime解释
点此查看全部文字教程.视频教程.源代码 本文目录 1. 不够好的开始 1.1 Date 日期时间类 1.2 Calendar 日历类 1.3 SimpleDateFormat 日期时间格式化 2. 足 ...
- 设计新奇的充电器,能搭积木还支持多口快充,IDMIX积木桌面充电器上手
平时给手机.笔记本等设备充电的时候,大家一般会用原装的充电器,有时候同时充电的设备比较多,我们还需要加上一个插线板,然后配上三四个充电器,这样桌面上看起来未免有些凌乱,上周我发现了一款桌面充电器,支持 ...
- POSTGRESQL COPY 命令导入数据,你还另一个更快的方案!
POSTGRESQL 数据库数据导入的核心一般都使用COPY 命令,熟悉POSTGRESQL 的同学应该对这个命令不陌生,相对于MYSQL 去一条条的执行insert命令来说,COPY 命令是POST ...
- 03Java常用API-19. Jdk8新增的日期Date API(LocalDateTime,LocalDate,LocalTime,Instant,Period,Duration)
概述 LocalDateTime:包含了日期及时间. LocalDate:不包含具体时间的日期. LocalTime:不含日期的时间. Instant:代表的是时间戳. 获取日期时间的信息 Local ...
最新文章
- Visual SVN 非常好的转贴
- UGUI 自动布局的重叠BUG
- 【C++ Priemr | 15】虚函数常见问题
- ubuntu16.04升级 vim 8.0
- 开源组件XStream 修复11个漏洞并公开 PoC
- Total Defense Anti-Virus – 免费6个月
- jQuery UI dialog实现dialog弹框显示
- 支付宝当面付扫码支付支付后不回调_新开支付宝不满90天当面付收款第二天到账怎么办?如何实现秒到而不是冻结的来看看吧!...
- 【权限维持】window服务端常见后门技术
- JSP个人博客网站设计与实现
- 阜师院2016年c语言真题答案,C语言A卷答案.doc
- 通过Bellman算子理解动态规划
- config.py参数解释
- MATLAB注意事项
- Spring Boot 统一功能处理
- 股票中的KD指标金叉和死叉
- 阿里云ecs安全组管理(双可变宽带公网出口)
- 【akka】Akka源码分析-Event Bus
- C++ 获取jpg和png的图片宽和高,不使用第三方库
- fix协议的服务器,FIX 协议开发(3):QuickFIX/J 实战经验小结