天天看点

java 日期转化

关于日期转化的 文章很多.我只要讲讲我遇到的一些与日期转化有关的问题.

大约1年前,我遇到过一个很令人郁闷又费解的问题.

项目使用的是struts2框架,表单中有日期,提交表单时总是报错,说日期转化有问题,没能马上找到原因.

过了很长时间,才搞清楚关键之所在,有一个日期格式是:"yyyy-mm-ddthh:mm:ss".

日期和时间之间使用t 分割,而不是采用我们熟知的空格来分割."yyyy-mm-ddthh:mm:ss"是美国一种的日期格式,中文中是没有这种日期格式的.

我当时使用的浏览器是ie,碰巧当时ie浏览器的语言被设置成了英语,所以提交表单时struts2按照yyyy-mm-ddthh:mm:ss来解析,但是我表单中日期的格式却是""yyyy-mm-dd hh:mm:ss"",所以就报错了.

怎么办呢?不是仅仅把浏览器的语言设置成为中文就ok 了,因为这没有彻底解决问题.

我的方法是编写一个自定义的日期转化converter,当然得继承struts2的ognl.defaulttypeconverter

java 日期转化

package com.common.convert;  

import java.sql.date;  

import java.sql.timestamp;  

import java.text.parseexception;  

import java.text.simpledateformat;  

import java.util.map;  

import ognl.defaulttypeconverter;  

import org.apache.commons.lang.stringutils;  

import org.apache.commons.lang3.time.dateutils;  

import org.apache.log4j.logger;  

/*** 

 * 日期转换器.<br>用于struts2 

 *  

 * @author huangwei 

 * 

 */  

public class dateconverter extends defaulttypeconverter {  

    private static final logger logger = logger.getlogger(dateconverter.class);  

    private static final string datetime_pattern = "yyyy-mm-dd hh:mm:ss";  

    private static final string datetime_pattern_no_second = "yyyy-mm-dd hh:mm";  

    private static final string datetime_pattern_zh ="yyyy年mm月dd日 hh点mm分ss秒";  

    private static final string datetime_pattern_zh2 ="yyyy年mm月dd日 hh时mm分ss秒";  

    private static final string date_pattern = "yyyy-mm-dd";  

    private static final string month_pattern = "yyyy-mm";  

    /** 

     * convert value between types 

     */  

    @suppresswarnings("unchecked")  

    public object convertvalue(map ognlcontext, object value, class totype) {  

        object result = null;  

        // java.sql.date 是java.util.date 的子类  

        if (totype == java.util.date.class) {  

            try {  

                result = doconverttodate(value,  totype);  

            } catch (parseexception e) {  

                e.printstacktrace();  

            }  

        } else if (totype == java.sql.timestamp.class) {  

                java.util.date date=doconverttodate(value, totype);  

                result = new timestamp(date.gettime());  

        } else if (totype == string.class) {  

            result = doconverttostring(value);  

        }  

        return result;  

    }  

     * convert string to date 

     *  

     * @param value 

     * @return 

     * @throws parseexception 

    private java.util.date doconverttodate(object value,class totype) throws parseexception {  

        java.util.date result = null;  

        if (value instanceof string) {  

            result = dateutils.parsedate((string) value, new string[] {datetime_pattern,  

                    date_pattern,  month_pattern   

                    ,datetime_pattern_no_second,datetime_pattern_zh,datetime_pattern_zh2});  

//          if(totype==java.sql.timestamp.class){  

//              result=new java.sql.timestamp(result.gettime());  

//          }  

            // all patterns failed, try a milliseconds constructor  

            if (result == null && stringutils.isnotempty((string) value)) {  

                try {  

                    result = new date(new long((string) value).longvalue());  

                } catch (exception e) {  

                    logger.error("converting from milliseconds to date fails!");  

                    e.printstacktrace();  

                }  

        } else if (value instanceof object[]) {  

            // let's try to convert the first element only  

            object[] array = (object[]) value;  

            if ((array != null) && (array.length >= 1)) {  

                value = array[0];  

                result = doconverttodate(value,totype);  

        } else if (date.class.isassignablefrom(value.getclass())) {  

            result = (date) value;  

        return (java.util.date)result;  

     * convert date to string 

    private string doconverttostring(object value) {  

        simpledateformat simpledateformat = new simpledateformat(  

                datetime_pattern);  

        string result = (string)value;  

        if (value instanceof date) {  

            result = simpledateformat.format(value);  

}  

 还要进行一些配置,具体参见: 

<a href="http://huangkunlun520.blog.51cto.com/2562772/1576131" target="_blank">struts2中转换date类型的问题</a>

这里我要强调一点:我之所以写converter是为了根本上解决问题,这样不管浏览器是什么语言都不用担心了.

我推荐使用org.apache.commons.lang3.time.dateutils 来进行日期转化,为什么呢?

我们看到org.apache.commons.lang3.time.dateutils 的第二个参数是一个数组,意思就是我循环的从数组中拿出一个pattern进行parse,直到解析成功为止.其实这就是一种容错的思维,非常好的思维.

场景:更新的时候,需要把日期放到表单的隐藏域中,但是如果日期为空的话,提交就报错,大概意思:

can not convert string "" to date.根本原因是隐藏域的值为空.

所以解决方法:也是写一个转化器,如果日期字符串为空,则返回空就完了,不必报错.