java 编程中 Date 与 SimpleDateFormat 时间转换不一致问题 与 SimpleDateFormat 线程安全问题

您所在的位置:网站首页 excel版本不兼容导致日期格式不对怎么办 java 编程中 Date 与 SimpleDateFormat 时间转换不一致问题 与 SimpleDateFormat 线程安全问题

java 编程中 Date 与 SimpleDateFormat 时间转换不一致问题 与 SimpleDateFormat 线程安全问题

2024-07-09 21:26| 来源: 网络整理| 查看: 265

前提说明:

         java.util.Date中的getTime函数定义如下:

     java.util.Date代表一个时间点,其值为距公元1970年1月1日 00:00:00的毫秒数。所以它是没有时区和Locale概念的。

     public long getTime() 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数

  java中通过如下形式取得当前时间点: 

Date now =new Date(); //这个时间点与本地系统的时区无关,故不同时区同一时间获取的Date数据时间戳是一致的。

  而正因为其与时区的无关性,才使得我们的存储数据(如:数据库中的时间datetime类型数据)是一致的。

问题出现原因:不同时区服务器 连接统一数据库 获取时间 Date 数据是一致的,但是 由于服务器所在时区的不同,使用如下代码进行字符串转换的时候,出现不同时区服务器SimpleDateFormat转换出的字符串不一致问题。

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

String snow = sdf.format(now);

提示:上面代码SimpleDateFormat 没有设定时区属性,会自动获取当前服务器所在时区,进行字符串的转换,进而造成时间字符串显示的不同。

解决:

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

sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

String snow = sdf.format(now);// snow = 2011-12-04 21:22:24

sdf.setTimeZone(TimeZone.getTimeZone("GMT+7"));

String snow2 = sdf.format(now);// snow2 = 2011-12-04 20:22:24 (可见:东八区比东七区早一个小时)

  另外,你可以通过如下代码修改本地时区信息:

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

安全问题:

JDK文档的最下面有如下说明:

  SimpleDateFormat中的日期格式不是同步的。推荐(建议)为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。

  JDK原始文档如下:   Synchronization:   Date formats are not synchronized.    It is recommended to create separate format instances for each thread.    If multiple threads access a format concurrently, it must be synchronized externally.

  下面我们通过看JDK源码来看看为什么SimpleDateFormat和DateFormat类不是线程安全的真正原因:

  SimpleDateFormat继承了DateFormat,在DateFormat中定义了一个protected属性的 Calendar类的对象:calendar。只是因为Calendar累的概念复杂,牵扯到时区与本地化等等,Jdk的实现中使用了成员变量来传递参数,这就造成在多线程的时候会出现错误。

  在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++]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3