java 编程中 Date 与 SimpleDateFormat 时间转换不一致问题 与 SimpleDateFormat 线程安全问题 |
您所在的位置:网站首页 › excel版本不兼容导致日期格式不对怎么办 › java 编程中 Date 与 SimpleDateFormat 时间转换不一致问题 与 SimpleDateFormat 线程安全问题 |
前提说明: 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 |