日期:2014-05-19  浏览次数:20796 次

SimpleDateFormat日期解析成1970年问题
各位大虾好,目前我们公司生产库出现极少数的日期解析成1970年的问题,有年份解析错误的,有年月解析错误的,也有年月日都解析错误的。
  查看xml报文,时间是2012-5-26,但解析的结果却是1970-5-26

  我们解析的方法是这样的:
  DateFormat dateForm = new SimpleDateFormat("yyyy-mm-dd");

  Date d = dateForm.parse(date);
  而这个date是其它系统传过来的字符串。

  感觉好奇怪的,99.9%是正确的,几千万的数据就那么几十条有问题,不知道怎么回事。

  哪位能指点下原因不?

------解决方案--------------------

SimpleDateFormat不是线程安全的,如果多线程访问同一个SimpleDateFormat对象就会出错。

我曾经写过一个多线程导数据的程序,结果下单时间比支付时间还晚,后来才发现是这个问题。

Java code

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * 线程安全的SimpleDateFormat帮助类<br/>
 * 创建SimpleDateFormat对象成本较高,但是SimpleDateFormat又不是线程安全的,因此使用ThreadLocal模式<br/>
 * 
 * @author xujsh(xjs250@163.com)
 * 
 * */
public class DateFormatUtil {
    
    public static final String PATTERN10 = "yyyy-MM-dd";
    public static final String PATTERN19 = "yyyy-MM-dd HH:mm:ss";
    
    private static final ThreadLocal<Map<String,SimpleDateFormat>> DATE_FORMAT_HOLDER = new ThreadLocal<Map<String,SimpleDateFormat>>(){
        @Override
        protected Map<String, SimpleDateFormat> initialValue() {
            Map<String, SimpleDateFormat> map = new HashMap<String, SimpleDateFormat>();
            map.put(PATTERN10, new SimpleDateFormat(PATTERN10));
            map.put(PATTERN19, new SimpleDateFormat(PATTERN19));
            return map;
        }
    };
    private DateFormatUtil(){
        //私有的构造函数
    }
    /**
     * 获取符合pattern格式的SimpleDateFormat对象<br/>
     * 如果pattern格式的SimpleDateFormat对象不存在,会创建并缓存之<br/>
     * 
     * @param pattern
     * @return 
     * */
    public static SimpleDateFormat getDateFormat(String pattern){
        Map<String, SimpleDateFormat> map = DATE_FORMAT_HOLDER.get();
        SimpleDateFormat sdf = map.get(pattern);
        if(sdf == null){
            sdf = new SimpleDateFormat(pattern);
            map.put(pattern, sdf);
        }
        return sdf;
    }
    /**
     * 获取yyyy-MM-dd格式的SimpleDateFormat对象
     * 
     * @return
     * */
    public static SimpleDateFormat getDateFormat10(){
        return getDateFormat(PATTERN10);
    }
    /**
     * 获取yyyy-MM-dd HH:mm:ss格式的SimpleDateFormat对象
     * 
     * @return
     * */
    public static SimpleDateFormat getDateFormat19(){
        return getDateFormat(PATTERN19);
    }
    /**
     * 把日期格式化成yyyy-MM-dd字符串
     * 
     * @param date
     * @return
     * */
    public static String format10(Date date){
        if(date == null){
            return "";
        }
        return getDateFormat10().format(date);
    } 
    /**
     * 把日期格式化成yyyy-MM-dd HH:mm:ss字符串
     * 
     * @param date
     * @return
     * */
    public static String format19(Date date){
        if(date == null){
            return "";
        }
        return getDateFormat19().format(date);
    } 
    /**
     * 把yyyy-MM-dd格式的字符串转化成日期
     * 
     * @param datestr
     * @return
     * */
    public static Date parse10(String datestr){
        if(datestr == null || datestr.length()!=10){
            return null;
        }
        try{
            return getDateFormat10().parse(datestr);
        }catch(Exception e){
            return null;
        }
    } 
    /**
     * 把yyyy-MM-dd HH:mm:ss格式的字符串转化成日期
     * 
     * @param datestr
     * @return
     * */
    public static Date parse19(String datestr){
        if(datestr == null || datestr.length() != 19){
            return null;
        }
        try{
            return getDateFormat19().parse(datestr);
        }catch(Exception e){
            return null;
        }
    } 
}