前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >为什么建议使用你LocalDateTime,而不是Date?

为什么建议使用你LocalDateTime,而不是Date?

作者头像
良月柒
发布于 2019-10-28 09:55:25
发布于 2019-10-28 09:55:25
1.6K03
代码可运行
举报
运行总次数:3
代码可运行

程序员的成长之路

互联网/程序员/成长/职场

关注

阅读本文大概需要 4 分钟。

作者:何甜甜在吗

juejin.im/post/5d7787625188252388753eae

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?

通过阅读本篇文章你将了解到:

  • 为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】
  • java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改

为什么需要LocalDate、LocalTime、LocalDateTime

Date如果不格式化,打印出的日期可读性差

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Tue Sep 10 09:34:04 CST 2019

使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的 SimpleDateFormat的format方法最终调用代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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是共享变量,并且这个共享变量没有做线程安全控制。

当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。

在多并发情况下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。

parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了

  • 重置日期对象cal的属性值
  • 使用calb中中属性设置cal
  • 返回设置好的cal对象

但是这三步不是原子操作

多线程并发如何保证线程安全

  • 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大
  • 对使用format和parse方法的地方进行加锁 => 线程阻塞性能差
  • 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法

Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但都被弃用了啊。

Come On 一起使用java8全新的日期和时间API

LocalDate

只会获取年月日

创建LocalDate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//获取当前年月日
LocalDate localDate = LocalDate.now();
//构造指定的年月日
LocalDate localDate1 = LocalDate.of(2019, 9, 10);

获取年、月、日、星期几

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 LocalTime localTime = LocalTime.of(13, 51, 10);
 LocalTime localTime1 = LocalTime.now();

获取时分秒

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//获取小时
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.getMinute();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);
LocalDateTime

获取年月日时分秒,等于LocalDate+LocalTime

创建LocalDateTime

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 LocalDate localDate2 = localDateTime.toLocalDate();

获取LocalTime

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LocalTime localTime2 = localDateTime.toLocalTime();
Instant

获取秒数

创建Instant对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Instant instant = Instant.now();

获取秒数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
long currentSecond = instant.getEpochSecond();

获取毫秒数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
long currentMilli = instant.toEpochMilli();

个人觉得如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()来得更为方便。

修改LocalDate、LocalTime、LocalDateTime、Instant

LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本。

增加、减少年数、月数、天数等,以LocalDateTime为例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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修改某些值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//修改年为2019
localDateTime = localDateTime.withYear(2020);
//修改为2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);

还可以修改月、日

时间计算

比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());

比如通过firstDayOfYear()返回了当前日期的第一天日期,还有很多方法这里不在举例说明。

格式化时间
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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方法创建自定义格式化方式。

解析时间
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的成长之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Vscode修改.exe文件生成位置
程序运行产生的可执行文件和源码混在一起,作为一名强迫症,我怎能容忍它 “如此放肆”,特意查看了一波官方文档后终于找到了解决办法,这是对.exe文件位置重定向后的工作区文件目录:
攻城狮杰森
2022/06/03
3.1K0
Vscode修改.exe文件生成位置
Vscode如何配置C语言以及C++环境
这里选择MinGW-W64,他作为MinGW的升级版,效率更加高。 我这里就只用最新版本的离线下载,因为在线很慢,而且需要魔法,鉴于此,我选择离线下载。提供了新版和旧版本 的离线下载链接。 8.1.0 (旧版):链接:https://pan.baidu.com/s/1fWkRgl4wWUm-lK9-QMNVkw 提取码:iki0 新版下载(在线下载):https://github.com/Vuniverse0/mingwInstaller/releases 新版下载(离线下载):https://github.com/mmozeiko/build-gcc-mingw/releases
用户7272142
2023/10/11
7450
Vscode如何配置C语言以及C++环境
Win Vscode C++
每次配都要网上找一遍太麻烦了。。。 MinGW下载地址 https://www.mingw-w64.org/downloads/
SakuraTears
2023/02/16
5850
VSCode配置C/C++环境
在我们上面创建的下项目文件helloWorld.cpp可以编写相应的C/C++程序,这里以输出为例。
跋扈洋
2022/03/29
1.1K0
VSCode配置C/C++环境
Visual Studio Code C++配置文件
以下三个文件放在 项目下 .vscode 文件夹中,内容从网络收集,经自己实践添加修改以备忘
Michael阿明
2022/01/07
1.3K0
手把手教你 之 VScode配置C/C++编译环境
下载的文件:进入网站后不要点击 “Download Lasted Version”,往下滑,找到最新版的 “x86_64-posix-seh”。
小火柴棒
2021/05/19
8.6K0
手把手教你 之 VScode配置C/C++编译环境
VsCode配置c/c++环境
文章目录 1. vsCode配置C/C++环境 1. vsCode下载和安装 1. 下载Microsoft vsCode 2. 安装vsCode 3. 下载中文插件 2. MinGW编译器下载和配置 1. 下载MinGW 2. 下载后放到自己方便的目录,并复制文件里bin目录的路径(后面用得到) 3. 在系统环境变量配置path变量 4. 检查是否配置成功 3. vsCode配置c/c++ 1. 下载c/c++插件 2. 配置 3. 测试是否成功 4. 常见问题 5.最后 1. vsCode配置C/C++
Twcat_tree
2022/11/22
7850
VsCode配置c/c++环境
整理:Visual Studio Code (vscode) 配置C、C++环境/编写运行C、C++(主要Windows、简要Linux)
2020年2月22日更新,又按照自己的帖子尝试了以下,感觉大的思路是没问题的啊,小改动用紫色的标记标注出来了,另外如评论区所说删去了部分旧版本的内容和图片,不知道为啥评论区的留言我都没收到邮件。。。
全栈程序员站长
2022/07/23
5.3K0
整理:Visual Studio Code (vscode) 配置C、C++环境/编写运行C、C++(主要Windows、简要Linux)
vscode配置c语言环境
昨晚上一不小心给电脑整坏了,无奈之下就重装了系统。装完系统之后最麻烦的当然就是所有学习资料的安装恢复了。这样的工作对我这种记忆力不大好的“老年人”极度不友好!可是这又有什么办法呢,找到了我在云盘的学习资料后,当然是安装对应的工具了。我首先选择恢复的是vscode这款神器,我感觉这款轻量编辑器还是对我挺友好的,各个系统平台都可以使用,支持多种语言不说,还有丰富多样的各类插件免费使用。
是小北a
2022/03/30
1.4K0
vscode配置c语言环境
vscode 配置C语言编译环境(完美版)_C语言环境安装
要在VSCode中配置C语言环境,我们首先可能要一个VSCode(废话),所以先下载安装一个VSCode; 然后肯定需要相关插件,因为VSCode不能直接拿来写C; 然后任何语言的程序在运行前都需要编译,那还需要一个编译器,很可惜VSCode插件里面不自带,所以要自己下载然后配置; 最后在VSCode中进行相关配置,就可以
全栈程序员站长
2022/09/30
3.1K0
vscode 配置C语言编译环境(完美版)_C语言环境安装
[原创]Windows上使用VS code写C++代码
如果在Windows上用过gdb编译过C++,一般都会对 MinGW有印象,Windows版的Eclipse for C++/Dev C++等都是基于MinGW来做的。于是我们在Windows上要想在VS code中用gdb的环境,同样需要先配置好MinGW的环境。
极客中心
2021/02/25
2.7K0
1.Win10+VsCode的C/CPP编译环境搭建
我是从开始学C++的时候就一直用的是visual studio,毕竟宇宙第一IDE,写和调试都是超级方便快捷,唯一的缺点可能就是启动慢一点。 之前电脑没有换固态之前,用过一段时间的codeblocks,换了之后就一直用VS了。 这次换vscode的原因主要是因为最近看到CPP的一些细节的东西的时候发现VS会完全忽略掉这些错误和警告。 印象最深的是关于函数返回局部指针变量的处理: eg:
和蔼的zhxing
2018/10/26
5.1K1
vscode一键配置C/C++多个C及CPP文件编译与tasks.json和launch.json原理
搜了很多的教程,发现要么教程太老,给的配置信息里面有些参数都不能使用了,要么就是直接扔下自己的配置信息就没了,不知道咋来的,也不能拿过来直接用,让我这种小白无从下手,于是就摸索整理一下,帮助一下像我这样小白刚入手的小伙伴们。
全栈程序员站长
2022/11/01
8.1K1
vscode一键配置C/C++多个C及CPP文件编译与tasks.json和launch.json原理
VsCode 配置 C/C++ 开发环境,真的很简单
最近在学习C语言版的数据结构,要敲敲C/C++的代码,DevC++成功把我劝退了。
宁在春
2022/10/31
7.6K0
VsCode 配置 C/C++ 开发环境,真的很简单
VSCode配置C环境(MinGW)啰里啰唆篇
该args数组指定将传递给g ++的命令行参数。必须按照编译器期望的顺序指定这些参数。
云深无际
2021/04/28
9330
VSCode配置C环境(MinGW)啰里啰唆篇
Ubuntu 系统配置 VS Code C++ 开发环境
build-essential 包含了 GNU 编辑器集合、GNU 调试器、其他编译软件所必需的开发库和工具,简单来说,安装了 build-essential 就相当于安装了 gcc、g++、make 等工具。
为为为什么
2023/12/14
1.4K0
Ubuntu 系统配置 VS Code C++ 开发环境
vscode基于Linux和Windows下c/c++的多文件编译与连接
cygwin64/home/xxx/.bash_profile ,末尾加上如下代码(后面vscodeMake.bat要用到环境变量"_T"):
战神伽罗
2019/07/24
3.1K0
VSCode 配置 C++ 运行环境
本文记录使用 vscode 配置c++编程环境的流程。 环境准备 项目 内容 操作系统 Windows 10 软件安装 VS code 官网:https://code.visualstudio.com/ 安装gcc编译器 下载 链接:MinGW-w64 - for 32 and 64 bit Windows 选最新版本中的x86_64-posix-seh 安装 解压压缩包 将目录中的bin添加到环境变量 验证 在cmd中输入命令 > gcc -v Using built
为为为什么
2022/08/05
1.2K0
VS code搭建 C 和 C++ 环境的完整图文教程!
VS code是一个微软旗下的一个广受欢迎的开源文本编辑器,相较于其他编辑器,VS code有着非常多的优点而让开发者们对其爱不释手。
李肖遥
2022/12/22
3.5K0
VS code搭建 C 和 C++ 环境的完整图文教程!
[原创]Windows中VS code无法查看C++ STL容器的值
1 Windows中VS code debug时无法查看C++ STL容器内容
极客中心
2021/02/25
1.9K0
推荐阅读
相关推荐
Vscode修改.exe文件生成位置
更多 >
LV.0
数据分析工程师
目录
  • 为什么需要LocalDate、LocalTime、LocalDateTime
  • Come On 一起使用java8全新的日期和时间API
    • LocalDate
    • LocalTime
    • LocalDateTime
    • Instant
    • 修改LocalDate、LocalTime、LocalDateTime、Instant
    • 时间计算
    • 格式化时间
    • 解析时间
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档