el-date-picker设置默认日期_程序员必备:Java 日期处理的十个坑

前言

整理了Java日期处理的十个坑,希望对大家有帮助。

一、用Calendar设置时间的坑

反例:

Calendar c = Calendar.getInstance();

c.set(Calendar.HOUR, 10);

System.out.println(c.getTime());

运行结果:

Thu Mar 26 22:28:05 GMT+08:00 2020

解析:

我们设置了10小时,但运行结果是22点,而不是10点。因为Calendar.HOUR默认是按12小时制处理的,需要使用Calendar.HOUROFDAY,因为它才是按24小时处理的。

正例:

Calendar c = Calendar.getInstance();

c.set(Calendar.HOUR_OF_DAY, 10);

二、Java日期格式化YYYY的坑

反例:

Calendar calendar = Calendar.getInstance();

calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("YYYY-MM-dd");

System.out.println("2019-12-31 转 YYYY-MM-dd 格式后 " + dtf.format(testDate));

运行结果:

2019-12-31 转 YYYY-MM-dd 格式后 2020-12-31

解析:

为什么明明是2019年12月31号,就转了一下格式,就变成了2020年12月31号了?因为YYYY是基于周来计算年的,它指向当天所在周属于的年份,一周从周日开始算起,周六结束,只要本周跨年,那么这一周就算下一年的了。正确姿势是使用yyyy格式。

4ef03b14c394632176f8e111956156af.png

正例:

Calendar calendar = Calendar.getInstance();

calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd");

System.out.println("2019-12-31 转 yyyy-MM-dd 格式后 " + dtf.format(testDate));

三、Java日期格式化hh的坑。

反例:

String str = "2020-03-18 12:00";

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd hh:mm");

Date newDate = dtf.parse(str);

System.out.println(newDate);

运行结果:

Wed Mar 18 00:00:00 GMT+08:00 2020

解析:

设置的时间是12点,为什么运行结果是0点呢?因为hh是12制的日期格式,当时间为12点,会处理为0点。正确姿势是使用HH,它才是24小时制。

正例:

String str = "2020-03-18 12:00";

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

Date newDate = dtf.parse(str);

System.out.println(newDate);

四、Calendar获取的月份比实际数字少1即(0-11)

反例:

//获取当前月,当前是3月

Calendar calendar = Calendar.getInstance();

System.out.println("当前"+calendar.get(Calendar.MONTH)+"月份");

运行结果:

当前2月份

解析:

The first month of the year in the Gregorian and Julian calendars

is JANUARYcode> which is 0;

也就是1月对应的是下标 0,依次类推。因此获取正确月份需要加 1.

正例:

//获取当前月,当前是3月

Calendar calendar = Calendar.getInstance();

System.out.println("当前"+(calendar.get(Calendar.MONTH)+1)+"月份");

五、Java日期格式化DD的坑

反例:

Calendar calendar = Calendar.getInstance();

calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-DD");

System.out.println("2019-12-31 转 yyyy-MM-DD 格式后 " + dtf.format(testDate));

运行结果:

2019-12-31 转 yyyy-MM-DD 格式后 2019-12-365

解析:

DD和dd表示的不一样,DD表示的是一年中的第几天,而dd表示的是一月中的第几天,所以应该用的是dd。

正例:

Calendar calendar = Calendar.getInstance();

calendar.set(2019, Calendar.DECEMBER, 31);

Date testDate = calendar.getTime();

SimpleDateFormat dtf = new SimpleDateFormat("yyyy-MM-dd");

System.out.println("2019-12-31 转 yyyy-MM-dd 格式后 " + dtf.format(testDate));

六、SimleDateFormat的format初始化问题

反例:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

System.out.println(sdf.format(20200323));

运行结果:

1970-01-01

解析:

用format格式化日期是,要输入的是一个Date类型的日期,而不是一个整型或者字符串。

正例:

Calendar calendar = Calendar.getInstance();

calendar.set(2020, Calendar.MARCH, 23);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

System.out.println(sdf.format(calendar.getTime()));

七、日期本地化问题

反例:

String dateStr = "Wed Mar 18 10:00:00 2020";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy");

LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);

System.out.println(dateTime);

运行结果:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'Wed Mar 18 10:00:00 2020' could not be parsed at index 0

at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)

at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

at java.time.LocalDateTime.parse(LocalDateTime.java:492)

at com.example.demo.SynchronizedTest.main(SynchronizedTest.java:19)

解析:

DateTimeFormatter 这个类默认进行本地化设置,如果默认是中文,解析英文字符串就会报异常。可以传入一个本地化参数(Locale.US)解决这个问题

正例:

String dateStr = "Wed Mar 18 10:00:00 2020";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy",Locale.US);

LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);

System.out.println(dateTime);

八、SimpleDateFormat 解析的时间精度问题

反例:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

String time = "2020-03";

System.out.println(sdf.parse(time));

运行结果:

Exception in thread "main" java.text.ParseException: Unparseable date: "2020-03"

at java.text.DateFormat.parse(DateFormat.java:366)

at com.example.demo.SynchronizedTest.main(SynchronizedTest.java:19)

解析:

SimpleDateFormat 可以解析长于/等于它定义的时间精度,但是不能解析小于它定义的时间精度。

正例:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

String time = "2020-03";

System.out.println(sdf.parse(time));

九、SimpleDateFormat 的线性安全问题

反例:

public class SimpleDateFormatTest {

private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public static void main(String[] args) {

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(1000));

while (true) {

threadPoolExecutor.execute(() -> {

String dateString = sdf.format(new Date());

try {

Date parseDate = sdf.parse(dateString);

String dateString2 = sdf.format(parseDate);

System.out.println(dateString.equals(dateString2));

} catch (ParseException e) {

e.printStackTrace();

}

});

}

}

运行结果:

Exception in thread "pool-1-thread-49" java.lang.NumberFormatException: For input string: "5151."

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

at java.lang.Long.parseLong(Long.java:589)

at java.lang.Long.parseLong(Long.java:631)

at java.text.DigitList.getLong(DigitList.java:195)

at java.text.DecimalFormat.parse(DecimalFormat.java:2051)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)

at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)

at java.text.DateFormat.parse(DateFormat.java:364)

at com.example.demo.SimpleDateFormatTest.lambda$main$0(SimpleDateFormatTest.java:19)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

at java.lang.Thread.run(Thread.java:748)

Exception in thread "pool-1-thread-47" java.lang.NumberFormatException: For input string: "5151."

at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

at java.lang.Long.parseLong(Long.java:589)

at java.lang.Long.parseLong(Long.java:631)

at java.text.DigitList.getLong(DigitList.java:195)

at java.text.DecimalFormat.parse(DecimalFormat.java:2051)

at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)

at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)

at java.text.DateFormat.parse(DateFormat.java:364)

at com.example.demo.SimpleDateFormatTest.lambda$main$0(SimpleDateFormatTest.java:19)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

at java.lang.Thread.run(Thread.java:748)

解析:

全局变量的SimpleDateFormat,在并发情况下,存在安全性问题。

  • SimpleDateFormat继承了 DateFormat

  • DateFormat类中维护了一个全局的Calendar变量

  • sdf.parse(dateStr)和sdf.format(date),都是由Calendar引用来储存的。

  • 如果SimpleDateFormat是static全局共享的,Calendar引用也会被共享。

  • 又因为Calendar内部并没有线程安全机制,所以全局共享的SimpleDateFormat不是线性安全的。

解决SimpleDateFormat线性不安全问题,有三种方式:

  • 将SimpleDateFormat定义为局部变量

  • 使用ThreadLocal。

  • 方法加同步锁synchronized。

正例:

public class SimpleDateFormatTest {

private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>();

public static DateFormat getDateFormat() {

DateFormat df = threadLocal.get();

if(df == null){

df = new SimpleDateFormat(DATE_FORMAT);

threadLocal.set(df);

}

return df;

}

public static String formatDate(Date date) throws ParseException {

return getDateFormat().format(date);

}

public static Date parse(String strDate) throws ParseException {

return getDateFormat().parse(strDate);

}

public static void main(String[] args) {

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 100, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(1000));

while (true) {

threadPoolExecutor.execute(() -> {

try {

String dateString = formatDate(new Date());

Date parseDate = parse(dateString);

String dateString2 = formatDate(parseDate);

System.out.println(dateString.equals(dateString2));

} catch (ParseException e) {

e.printStackTrace();

}

});

}

}

}

10、Java日期的夏令时问题

反例:

TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println(sdf.parse("1986-05-04 00:30:00"));

运行结果:

Sun May 04 01:30:00 CDT 1986

解析:

先了解一下夏令时

  • 夏令时,表示为了节约能源,人为规定时间的意思。

  • 一般在天亮早的夏季人为将时间调快一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。

  • 各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。

  • 1986年4月,中国中央有关部门发出“在全国范围内实行夏时制的通知”,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时。(1992年起,夏令时暂停实行。)

  • 夏时令这几个时间可以注意一下哈,1986-05-04, 1987-04-12, 1988-04-10, 1989-04-16, 1990-04-15, 1991-04-14.

结合demo代码,中国在1986-05-04当天还在使用夏令时,时间被拨快了1个小时。所以0点30分打印成了1点30分。如果要打印正确的时间,可以考虑修改时区为东8区。

正例:

TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

System.out.println(sdf.parse("1986-05-04 00:30:00"));

b9da565305865de747ec048d9c577ff7.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244441.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scope python_Python标准库Scope

作者&#xff1a;zhbzz2007 出处&#xff1a;http://www.cnblogs.com/zhbzz2007 欢迎转载&#xff0c;也请保留这段声明。谢谢&#xff01;1 模块简介你一定在很多计算机科学课程上听说过作用域。它很重要&#xff0c;如果你不理解它的工作原理&#xff0c;那么就会出现一些令人…

java命令_JAVA与模式之命令模式

在阎宏博士的《JAVA与模式》一书中开头是这样描述命令(Command)模式的&#xff1a;命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Transaction)模式。命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化&#xf…

android 16进制 全透明_你有几种实现方案Android 设备唯一标识?

前言项目开发中&#xff0c;多少会遇到这种需求&#xff1a;获得设备唯一标识DeviceId&#xff0c;用于&#xff1a;1.标识一个唯一的设备&#xff0c;做数据精准下发或者数据统计分析&#xff1b;2.账号与设备绑定&#xff1b;3.....分析这类文章&#xff0c;网上有许多资料&a…

链表的数据域怎么使用结构体_一步一步教你从零开始写C语言链表

为什么要学习链表&#xff1f;链表主要有以下几大特性&#xff1a;1、解决数组无法存储多种数据类型的问题。2、解决数组中&#xff0c;元素个数无法改变的限制(C99的变长数组&#xff0c;C也有变长数组可以实现)。3、数组移动元素的过程中&#xff0c;要对元素进行大范围的移动…

python计算bmi_Python编程语言:如何用Python编程来判断体重指数BMI是否健康

上一篇小编分享了自己学习Python语言有关字符串和模块time使用的相关知识&#xff0c;这一篇小编分享给大家的是比较有趣的运用&#xff0c;那就是如何用Python编程来表示自己体重BMI。 用Python程序来算出我们自己的BMI指数&#xff0c;来判断我们自己的健康情况&#xff0c;首…

drbd实现mysql地热备_heartheartbeat+drbd+mysql主库热备

1 环境主机名网卡磁盘mastereth0 桥接模式 eth0(192.168.1.10) 自定义模式(VMnet2)(192.168.2.10)VIP 192.168.1.200/210系统盘20G外接磁盘slaveeth0 桥接模式(192.168.1.20) eth1 自定义模式(VMnet2)(192.168.2.20)VIP 192.168.1.200/210系统盘20G外接磁盘server3eth0 桥接模式…

dba的前景_运维、测试、程序员,这些技术岗位哪个更有前景?

在一个初具规模的互联网公司&#xff0c;从业务方面出发&#xff0c;有很多岗位类型&#xff0c;比如运营、客服、市场、产品、设计、技术等等。在这些大类下面&#xff0c;还要细分各种小类&#xff0c;以技术为例&#xff0c;可分为前端(客户端)、后端、测试、运维、DBA等等&…

mysql深度解析_百万级数据下的mysql深度解析

mysql 作为一款非常优秀的免费数据库被广泛的使用&#xff0c;平时我们开发的项目数据过百万的时候不多。最近花了大量的时间来深入的研究mysql百万级数据情况下的优化。 遇到了很多问题并解决了他们&#xff0c;特此分享给大家。欢迎提出您的宝贵意见&#xff01;一、百万级数…

python异步实现方式_Python通过yield实现异步

改写程序first函数等待long函数返回值的方式为yield,代码如下&#xff1a; import _thread import time gen None def long(): print (long execute) def fun(): time.sleep(5) result long end gen.send(result) _thread.start_new_thread(fun,()) def first(): print (firs…

免安装版的mysql步骤_mysql免安装版的安装方法及步骤

mysql免安装版的安装方法及步骤发布时间&#xff1a;2020-07-15 14:07:18来源&#xff1a;亿速云阅读&#xff1a;83作者&#xff1a;清晨小编给大家分享一下mysql免安装版的安装方法及步骤&#xff0c;希望大家阅读完这篇文章后大所收获&#xff0c;下面让我们一起去探讨吧&am…

jupyter notebook怎么写python代码_如何在Jupyter Notebook中使用Python虚拟环境?

如何在使用Jupyter Notebook时&#xff0c;解决Python虚拟环境间的切换问题&#xff1f;本文一步步帮你拆解。希望你能够避免踩坑的痛苦&#xff0c;把更多的时间花在愉快的编程上。 痛点 Python目前有两个主版本并存&#xff0c;这很让人苦恼。 一般人对于软件&#xff0c;总是…

cmd检查java_如何通过cmd查看java环境

展开全部JAVA环境变量设置一、下载JDK。62616964757a686964616fe4b893e5b19e31333363376561下载后是一个可执行程序&#xff0c;双击安装&#xff0c;安装路径为C:\Program Files\Java\jdk1.6.0_22\(当然&#xff0c;其他路径也可以)&#xff0c;如下图&#xff1a;二、设置环境…

ios 检测是否联网_秋招|阿里 iOS 五轮面经分享,已收到阿里的意向书

作者&#xff1a;aaaaaazzzz链接&#xff1a;https://www.nowcoder.com/discuss/302113来源&#xff1a;牛客网感觉牛客很少看到iOS的面经了&#xff0c;今天收到了阿里的意向书&#xff0c;来分享下面经&#xff0c;希望大家都Offer~&#xff01;总体感觉面试官都非常好&#…

java spring框架 注解_spring框架之注解的使用

原标题&#xff1a;spring框架之注解的使用今天是刘小爱自学Java的第122天。感谢你的观看&#xff0c;谢谢你。学习内容安排如下&#xff1a;Spring注解的使用。JavaWeb项目的搭建。Spring的Web集成。本来还计划学Spring的junit测试集成的&#xff0c;结果又没时间了。一、Spri…

idea 代码格式化插件_IDEA非常棒的插件,阿里巴巴约定成文的代码公约规范

无规矩&#xff0c;不方圆。每个人都有自己的编码风格&#xff0c;每个公司也有自己的代码规范。规范的代码&#xff0c;无论是自己日常维护&#xff0c;还是以后接盘者来接盘&#xff0c;都能快速定位上手&#xff0c;大大提高效率。作为一个IDEA万年爱好者&#xff0c;这些最…

java der pem_JAVA解析各种编码密钥对(DER、PEM、openssh公钥)

一、DER编码密钥对先说下DER编码&#xff0c;是因为JCE本身是支持DER编码密钥对的解析的&#xff0c;可以参见PKCS8EncodedKeySpec和X509EncodedKeySpec.DER编码是ASN.1编码规则中的一个子集&#xff0c;具体格式如何编排没有去了解&#xff0c;但最终呈现肯定的是一堆有规律的…

switch最大选项数目_随时随地学习C语言之3—if和switch哪个效率高?

之前学习C语言的时候&#xff0c;我经常有一个疑问&#xff0c;既然有if-else if-else结构的多分支选择语句&#xff0c;C语言为何还要制定switch这种多分支选择语句呢&#xff1f;直到两年前在分析ARM平台C语言反汇编代码的时候&#xff0c;才终于明白了switch-case这种结构存…

android java 退出程序_android开发两种退出程序方式(killProcess,System.exit)

KillProcess&#xff1a;在android中我们如果想要程序的进程结束可以这样写&#xff1a;android.os.Process.killProcess(android.os.Process.myPid());这样就可以从操作系统中结束掉当前程序的进程。注意&#xff1a;android中所有的activity都在主进程中&#xff0c;在Androi…

java 验证码_Java - 验证码 - 由Kaptcha组件实现

本文是基于SpringBoot整合Kaptcha验证码实现Kaptcha 是一个可高度配置的实用验证码生成工具&#xff0c;在项目开发中能够非常方便实现验证码先来看一个由 Kaptcha 制作的验证码效果图快速进入如何进行配置与实现的第1步&#xff1a;配置 Kaptcha 的依赖库com.github.penggle …

bat关闭java_通过bat脚本停止java进程的三个方法

通过bat脚本停止java进程的三个方法1.拷贝java.exe启动时复制java.exe程序修改进程映像名&#xff0c;然后通过映像名杀进程。栗子过程操作拷贝程序拷贝一份java.exe程序&#xff0c;重名为tstop.exe,放在PATH下。修改启动脚本echo offtitle tstoptstop -jar …/lib/laucher.ja…