一. SimpleDateFormat
想必大家对 SimpleDateFormat 并不陌生。SimpleDateFormat 是 Java 中一个非常常用的类,他是以区域敏感的方式格式化和解析日期的具体类。 它允许格式化 (date -> text)、语法分析 (text -> date)和标准化。

1. 日期时间格式(例如:yyyy-MM-dd HH:mm:ss)


2. 实例说明(Date–>Text)
SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
SimpleDateFormat myFmt1 = new SimpleDateFormat("yy/MM/dd HH:mm");
SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//等价于now.toLocaleString()
SimpleDateFormat myFmt3 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
SimpleDateFormat myFmt4 = new SimpleDateFormat("一年中的第 D 天 一年中第w个星期 一月中第W个星期 在一天中k时 z时区");
Date now = new Date();
System.out.println(myFmt.format(now));
System.out.println(myFmt1.format(now));
System.out.println(myFmt2.format(now));
System.out.println(myFmt3.format(now));
System.out.println(myFmt4.format(now));
System.out.println(now.toGMTString());
System.out.println(now.toLocaleString());
System.out.println(now.toString());

3. 实例说明(Text–>Date)
 String time1 = "2018年06月19日 23时10分05秒";
 String time2 = "18/06/19 23:10";
 String time3 = "2018-06-19 23:10:05";
 String time4 = "2018年06月19日 23时10分05秒 星期二";        SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
 SimpleDateFormat myFmt1 = new SimpleDateFormat("yy/MM/dd HH:mm");
 SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//等价于now.toLocaleString()
 SimpleDateFormat myFmt3 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E");
 Date date1 = null;
 try {
     date1 = myFmt.parse(time1);
 } catch (ParseException e) {
     e.printStackTrace();
 }
 System.out.println(date1);

Date date2 = null;
 try {
     date2 = myFmt1.parse(time2);
 } catch (ParseException e) {
     e.printStackTrace();
 }
 System.out.println(date2);

Date date3 = null;
 try {
     date3 = myFmt2.parse(time3);
 } catch (ParseException e) {
     e.printStackTrace();
 }
 System.out.println(date3);

Date date4 = null;
 try {
     date4 = myFmt3.parse(time4);
 } catch (ParseException e) {
     e.printStackTrace();
 }
 System.out.println(date4);
结果:

4.线程不安全
多个线程同时对一个SimpleDateFormat对象进行操作的时候,就会出现错乱。
例如全局的private static final SimpleDateFormat df = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
查看SimpleDateFormat 源码:calendar为protected类型的全局变量,当线程A设置了calendar.setTime(date);
线程B又设置了一次,那么calendar值就变了,线程A在subFormat方法中用到的calendar就不是自己设置的而是线程B设置的。

这个问题背后隐藏着一个更为重要的问题–无状态:无状态方法的好处之一,就是它在各种环境下,都可以安全的调用。衡量一个方法是否是有状态的,就看它是否改动了其它的东西,比如全局变量,比如实例的字段。format 方法在运行过程中改动了 SimpleDateFormat 的 calendar 字段,所以,它是有状态的。

5. 解决办法
1.每个线程使用的时候创建新的SimpleDateFormat,将有线程安全问题的对象由共享变为局部私有都能避免多线程问题
2.使用同步:同步 SimpleDateFormat 对象

public class DateSyncUtil {
        private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        public static String formatDate(Date date) throws ParseException {
            synchronized (sdf) {
                return sdf.format(date);
            }
        }
        public static Date parse(String strDate) throws ParseException {
            synchronized (sdf) {
                return sdf.parse(strDate);
            }
        }
}
说明:当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要 block 等待,多线程并发量大的时候会对性能有一定的影响
 
3.使用 ThreadLocal

public class DateSyncUtil {
        private ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(){
            @Override
            protected DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }
        };
        public Date parse(String dateStr){
            return threadLocal.get().parse(dateStr);
        }
        public String format(Date date) {
            return threadLocal.get().format(date);
        }
 }
 说明:使用 ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。

二. DateTimeFormatter
Java 8 提供了新的日期时间 API,其中包括用于日期时间格式化的 DateTimeFormatter,它与 SimpleDateFormat 最大的区别在于:DateTimeFormatter 是线程安全的,而 SimpleDateFormat 并不是线程安全。

//Text-->Date
String dateStr= "2018-06-20 11:25:56";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.parse(dateStr, dateTimeFormatter);
ZoneId zone = ZoneId.systemDefault();
Instant instant = localDateTime.atZone(zone).toInstant();
Date date = Date.from(instant);

//Date-->Text
Date date = new Date();
Instant instant = date.toInstant();
ZoneId zone = ZoneId.systemDefault();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String nowStr = localDateTime.format(format);
System.out.println(nowStr);

//LocalDateTime获取毫秒
System.out.println(localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());

JAVA中日期转换SimpleDateFormat和DateTimeFormatter相关推荐

  1. JAVA中日期格式SimpleDateFormat

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public cla ...

  2. [转载] Java中日期格式转换

    参考链接: Java中的类型转换和示例 Code: /**     * 字符串转换为java.util.Date<br>     * 支持格式为 yyyy.MM.dd G 'at' hh: ...

  3. java中日期格式的转换_java中定义日期格式的转换符

    Hi,大家好久不见,今天我们在这里给大家介绍一下关于Java的小知识,在Java中定义日期格式的转换符,至于运用呢就不和大家做介绍了:接下来就给大家详细介绍一下如何实现. 那我们该如何创建使用呢?首先 ...

  4. JAVA中日期 yyyy-MM-dd HH:mm:ss和yyyy-MM-dd hh:mm:ss的区别

    其实就是一个很小的知识点,但是本人在开发中,踩到了坑. 把两个格式弄混了.程序中需要按日期查询,用到了hh的,结果总是少12个小时的数据.弄了半天,刚开始还以为是时区弄错了呢,后来才发现原来是hh和H ...

  5. js 中日期 转换成时间戳 例如2013-08-30 转换为时间戳

    js 中日期 转换成时间戳 例如2013-08-30 转换为时间戳 热心网友  2018-11-18 js字符串转化时间戳可以使用自带函数 Date(要转化的时间字符串)先转化为Date类型,之后再将 ...

  6. java中日期格式大小写标准写法

    java中日期格式大小写标准写法: yyyy-MM-dd HH:mm:ss (年-月-日 时:分:秒)

  7. 计算机编码基础知识及Java中编码转换

    一.前言 最近项目中用到招商银行的企业直连功能,通过接口的方式直接调用招商银行的前置机(http://www.cmbchina.com/corporate/firmbank/FirmbankInfo. ...

  8. Java 中日期的几种常见操作 —— 取值、转换、加减、比较

    Java 的开发过程中免不了与 Date 类型纠缠,准备总结一下项目经常使用的日期相关操作,JDK 版本 1.7,如果能够帮助大家节约那么几分钟起身活动一下,去泡杯咖啡,便是极好的,嘿嘿.当然,我只提 ...

  9. java中日期如何转换_java如何转换日期格式?

    展开全部 import java.util.*; import java.text.*; import java.util.Calendar; public class VeDate { /** * ...

最新文章

  1. R语言ggplot2可视化自动换行适配长文本图例(legend)实战:Multiple Lines for Text per Legend Label
  2. 计算机应用基础20级月考,中职计算机应用基础月考试题
  3. [HOW TO]-官网拉取Trusty-TEE的代码
  4. 计算机三级网络技术大题多少分,2017年计算机三级网络技术考前试题及答案(3)...
  5. oracle 连多表查询语句,Oracle join多表查询
  6. 如何自定义SAP Spartacus店铺的购物车图表css风格
  7. VS Code的golang开发配置 之 代码提示
  8. A Data Access Layer to persist business objects using attributes and reflection - Part III [无常译]...
  9. 【转载】最好女孩子概率模型
  10. ActiveMQ学习总结(7)——ActiveMQ使用场景
  11. Cisco AP1240多SSID配置简解
  12. 关于大型网站技术演进的思考(十)--网站静态化处理—动静整合方案(2)
  13. python随机产生手机号码
  14. 万豪国际集团旗舰酒店品牌正式入驻中国东北地区
  15. 网易杭研易盾实习心得(4)
  16. robot光线机器人安卓版_RobotMake下载-RobotMake机器人控制软件下载v3.1.5 安卓版-西西软件下载...
  17. 如何远程访问公司的内部办公系统?
  18. python 的 pointcloud 计算探路
  19. 杭电2019计算机分数线,杭州电子科技大学2019年各省录取分数线及各专业录取分数线...
  20. Raspberry-Pi-PICO系列--第八篇 高级篇使用SWD接口下载和调试(第二章)

热门文章

  1. 通用mapper自增id mysql_Mybatis通用Mapper使用详解
  2. 基于Struts开发电影订票网站
  3. 怎么用电视看电视台直播?看CCTV频道
  4. 皇冠采集模板php,ptcms4.2.8自动采集配置教程
  5. 一键获取隐藏Wi-Fi SSID:利用Python和Scapy发现隐藏无线热点
  6. 印象笔记mac版 同步问题_Notability 最佳手写笔记 APP 之一!让 iPad / iPhone 变成工作学习利器...
  7. ArcGIS小知识(七)——ArcMap中裁剪影像或DEM等栅格数据,clip和mask遇到的问题
  8. MAC修改本地域名与 ip 的绑定
  9. [ArcGIS] 空间分析(十)3D分析 - 天际线 3D点要素、多面体创建 -错误合集
  10. 基于图嵌入的降维算法——边界Fisher分析(MFA)