天天看點

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.根本原因是隐藏域的值為空.

是以解決方法:也是寫一個轉化器,如果日期字元串為空,則傳回空就完了,不必報錯.