java程序猿经常会碰到的一个问题就是日期格式化。当接收参数中有日期或时间,那么就需要与前端商量好其格式,这边我知道是2种:1、时间戳 2、字符串。

先说一下时间戳,这个形势的参数,Java只需new Date(Long date)就能获得Date,但是我在使用过程中还是碰到奇怪的问题,就是时区与数据库对不上。获得的Date是CST格式的,而 CST却同时可以代表如下 4 个不同的时区:

Central Standard Time (USA) UT-6:00

Central Standard Time (Australia) UT+9:30

China Standard Time UT+8:00

Cuba Standard Time UT-4:00

所以用起来还是有点麻烦,于是我放弃了时间戳。

然后我用起了字符串,字符串就简单了,只需要用SimpleDateFormat格式化一下,而且后端在调试模式可以很明确看到什么时间。但是SimpleDateFormat有个缺点就是线程不安全,而且在使用的时候需要抛出异常或者try catch,至于为什么线程不安全我就不细说了,在阿里的Java开发手册(嵩山版)中有明确指出:【强制】SimpleDateFormat 是线程不安全的类,一般不要定义为 static变量,如果定义为 static, 必须加锁,或者使用 DateUtils工具类。 正例:注意线程安全,使用 DateUtils。亦推荐如下处理: private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; 说明:如果是JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替SimpleDateFormat,官方给出的解释:simple beautiful strong immutable thread-safe。

那么解决他线程不安全有几种办法:

1、将SimpleDateFormat定义成局部变量,在每次用到的时候就创建一个对象,方法结束作为垃圾回收,但是这样会消耗内存,就是大家用一个杯子喝水,可能不卫生或者抢着喝,但是每人一个一次性杯子,就增加了开销。

2、加线程同步锁(synchronized)这个我忘的差不多了,自行百度,这不是本节重点。

3、使用ThreadLocal,这个同上。

4、这个简单,不安全咱不用,jdk1.8中新增了 LocalDate 与 LocalDateTime等类来解决日期处理方法,同时引入了一个新的类DateTimeFormatter来解决日期格式化问题。API中讲的很详细,重点是This class is immutable and thread-safe。这个类是不可变的和线程安全的。LocalDateTime,DateTimeFormatter两个类都是线程安全的,只要不创建为public类型就没啥问题。可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat,具体使用方法可以查看API。

下面是我自用的一个工具类:

 1 package com.hmbb.demo.util;
2 import org.springframework.util.StringUtils;
3 import java.time.LocalDateTime;
4 import java.time.ZoneId;
5 import java.time.format.DateTimeFormatter;
6 import java.util.Date;
7 ​
8 /**
9 * @description 时间工具类
10 * @author: zx
11 * @create: 2020-10-28 09:43:30
12 **/
13 public class DateUtils {
14 ​
15 ​
16 private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
17 ​
18 /**
19 * 字符串转Date
20 * @param date 时间字符串 "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd"
21 * @param type null or "00" or "23"
22 * @return Date
23 */
24 public static Date getDate(String date,String type){
25 try {
26 if(StringUtils.isEmpty(date))return null;
27 if(date.length()==10){
28 date = date.concat(" 00:00:00");
29 }
30 LocalDateTime localDateTime = LocalDateTime.parse(date,formatter);
31 if(StringUtils.isEmpty(type)){
32 return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
33 }else{
34 return changeFormat(localDateTime,type);
35 }
36 }catch (Exception e){
37 e.printStackTrace();
38 }
39 return null;
40 }
41 private static Date changeFormat(LocalDateTime localDateTime,String type){
42 if("00".equals(type)){
43 localDateTime = localDateTime.withHour(00);
44 localDateTime = localDateTime.withMinute(00);
45 localDateTime = localDateTime.withSecond(00);
46 return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
47 }else if("23".equals(type)){
48 localDateTime = localDateTime.withHour(23);
49 localDateTime = localDateTime.withMinute(59);
50 localDateTime = localDateTime.withSecond(59);
51 return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
52 }else {
53 throw new IllegalArgumentException(type+"--type参数异常!");
54 }
55 }
56 }
注:type: null 返回原格式  00 当天最初时刻,时分秒为0  23 当天最后时刻,23时59分59秒

DateTimeFormatter接替SimpleDateFormat的更多相关文章

  1. 日期时间格式化 SimpleDateFormat与DateTimeFormatter

    原文:https://www.jianshu.com/p/b212afa16f1f 1.SimpleDateFormat为什么不是线程安全的? 如果我们把SimpleDateFormat定义成stat ...

  2. 还在使用SimpleDateFormat?你的项目崩没?

    如果是在多线程环境下,就需要注意了. 要点: 1.加Synchronized同步: 2.使用ThreadLocal: 3.jdk8使用DateTimeFormatter替代SimpleDateForm ...

  3. SimpleDateFormat 使用时出现的线程同步问题。。。

    错误使用: public static final SimpleDateFormat DAY_UI_MONTH_DAY_FORMAT = new SimpleDateFormat("MM-d ...

  4. SimpleDateFormat线程不安全原因及解决方案

    一. 线程不安全验证: /** * SimpleDateFormat线程安全测试 * 〈功能详细描述〉 * * @author 17090889 * @see [相关类/方法](可选) * @sinc ...

  5. 为什么SimpleDateFormat不是线程安全的?

    一.前言 日期的转换与格式化在项目中应该是比较常用的了,最近同事小刚出去面试实在是没想到被 SimpleDateFormat 给摆了一道... 面试官:项目中的日期转换怎么用的?SimpleDateF ...

  6. 阿里Java开发手册1.3.0 文字版

    版本: 1.3.0 update: 2017.9.25 一.编程规约 (一) 命名风格 1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例:_name _na ...

  7. 304902阿里巴巴Java开发手册1.4.0

    转自官网 前言 <阿里巴巴Java开发手册>是阿里巴巴集团技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善,系统化地整理成册,回馈给广大开发者.现代软件行业的高速 ...

  8. 阿里巴巴 Java 开发手册 1.4.0

    一.编程规约(一) 命名风格1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束.反例: _name / __name / $name / name_ / name$ ...

  9. Java开发最佳实践(一) ——《Java开发手册》之"编程规约"

    Java开发手册版本更新说明 专有名词解释 一. 编程规约 (一) 命名风格 (二) 常量定义 (三) 代码格式 (四) OOP 规约 (五) 集合处理 (六) 并发处理 (七) 控制语句 (八) 注 ...

随机推荐

  1. Django-Scrapy生成后端json接口

    Django-Scrapy生成后端json接口: 网上的关于django-scrapy的介绍比较少,该博客只在本人查资料的过程中学习的,如果不对之处,希望指出改正: 以后的博客可能不会再出关于djan ...

  2. 【原创】经验分享:一个小小emoji尽然牵扯出来这么多东西?

    前言 之前也分享过很多工作中踩坑的经验: 一个线上问题的思考:Eureka注册中心集群如何实现客户端请求负载及故障转移? [原创]经验分享:一个Content-Length引发的血案(almost.. ...

  3. Linux就该这么学28期——Day02 2.1-2.3

    本文记录必须掌握的Linux命令,部分内容引用自https://www.linuxprobe.com/basic-learning-02.html 工作中可使用https://www.linuxcoo ...

  4. Django Croppie

    下载 Django CroppieDjango Croppie django -croppie是一个简单集成croppie.js图像cropper到django项目的应用程序. 安装 安装与pip安装 ...

  5. ASP。NET Core Blazor CRUD使用实体框架和Web API

    下载source code - 1.7 MB 介绍 *请查看我的Youtube视频链接来学习ASP.NET Core Blazor CRUD使用实体框架和Web API. 在本文中,我们将了解如何为A ...

  6. 优质分享 | Spring Boot 入门到放弃!!!

    持续原创输出,点击上方蓝字关注我 目录 前言 视频目录 如何获取? 总结 前言 最近不知不觉写Spring Boot专栏已经写了九篇文章了,从最底层的项目搭建到源码解析以及高级整合的部分,作者一直在精 ...

  7. NOI 2012 【迷失游乐园】

    这道题,额,反正我是刚了2天,然后就萎了......(是不是觉得我很菜) 题目描述: 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐 ...

  8. OAth 2.0 的白话讲解

    一.OAuth2.0是什么,主要做什么用的? 官方注解 简单说,OAuth 就是一种授权机制.数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据.系统从而产生一个短期的进入令牌(token ...

  9. java基础知识总结(续写)

    1.两个容易搞混的C盘文件夹 文件名 描述 Progrm Files 默认存储的64位软件 Progrm Files(x86) 默认存储32位软件 2.常用基础DOS命令(Windows+R打开命令) ...

  10. MeteoInfoLab脚本示例:SeaWiFS HDF Grid数据

    SeaWiFS HDF Grid数据读取,特别是涉及到了文件的众多属性数据的读取,数据取对数后绘图.脚本程序: #Add data file f = addfile('D:/Temp/hdf/S199 ...