對於有的時候要輸出日期格式爲yyyy-MM-dd,而有的時候要輸出yyyy-MM-dd hh:mm:ss時怎麼辦?html
第一種方案:純註解式, 對日期類型的字段進行註解java
@JSONField(format = "yyyy-MM-dd") private Date updateDate; @JSONField(format = "yyyy-MM-dd hh:mm:ss") private Date createDate; public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public Date getCreateDate() { return createDate; }
第二種方案:使用fastjson的WriteDateUseDateFormat配置(使得返回的日期類型默認爲yyyy-MM-dd hh:mm:ss), 特殊類型使用字段@JSONField來進行控制web
<!-- 默認的註解映射的支持,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping --> <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"> <mvc:message-converters register-defaults="true"> <!-- 將Jackson2HttpMessageConverter的默認格式化輸出爲true --> <!-- 配置Fastjson支持 --> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="features"> <list> <!-- 輸出key時是否使用雙引號 --> <value>QuoteFieldNames</value> <!-- 是否輸出值爲null的字段 --> <!-- <value>WriteMapNullValue</value> --> <!-- 數值字段若是爲null,輸出爲0,而非null --> <value>WriteNullNumberAsZero</value> <!-- List字段若是爲null,輸出爲[],而非null --> <value>WriteNullListAsEmpty</value> <!-- 字符類型字段若是爲null,輸出爲"",而非null --> <value>WriteNullStringAsEmpty</value> <!-- Boolean字段若是爲null,輸出爲false,而非null --> <value>WriteNullBooleanAsFalse</value> <!-- null String不輸出 --> <value>WriteNullStringAsEmpty</value> <!-- null String也要輸出 --> <!-- <value>WriteMapNullValue</value> --> <!-- Date的日期轉換器 --> <value>WriteDateUseDateFormat</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- REST中根據URL後綴自動斷定Content-Type及相應的View --> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="mediaTypes" > <map> <entry key="json" value="application/json"/> </map> </property> <!-- 這裏是否忽略掉accept header,默認就是false --> <property name="ignoreAcceptHeader" value="true"/> <property name="favorPathExtension" value="true"/> </bean>
@JSONField(format = "yyyy-MM-dd") private Date updateDate; public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; }
第三種方案:使用FastJson的消息轉換器, 特殊類型使用字段@JSONField來進行控制spring
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializeConfig; import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import org.springframework.http.HttpOutputMessage; import org.springframework.http.converter.HttpMessageNotWritableException; import java.io.IOException; import java.io.OutputStream; /** * 若是沒有注入默認的日期格式,也沒有配置<value>WriteDateUseDateFormat</value>, 也沒有屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出時間戳 * 若是隻配置<value>WriteDateUseDateFormat</value>,則會轉換輸出yyyy-MM-dd hh:mm:ss * 配置<value>WriteDateUseDateFormat</value>, 屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出爲屬性註解的格式 * 若是注入了默認的日期格式,屬性註解@JSONField(format="yyyy-MM-dd hh:mm:ss") 則會轉換輸出爲屬性註解的格式 * 若是注入了默認的日期格式,則會轉換輸出爲默認的日期格式 * 若是三者都配置則會轉換成屬性註解的格式 * Created by PETER on 2016/2/5. */ public class CustomerFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter { public static SerializeConfig mapping = new SerializeConfig(); private String defaultDateFormat; @Override protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { OutputStream out = outputMessage.getBody(); String text = JSON.toJSONString(obj, mapping, super.getFeatures()); byte[] bytes = text.getBytes(getCharset()); out.write(bytes); } public void setDefaultDateFormat(String defaultDateFormat) { mapping.put(java.util.Date.class, new SimpleDateFormatSerializer(defaultDateFormat)); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <description>Spring MVC Configuration</description> <!-- 加載配置屬性文件 --> <context:property-placeholder ignore-unresolvable="true" location="classpath:/xmutca.properties" /> <!-- 掃描dubbo註解須要在controller以前,不然會形成沒法注入的問題 --> <dubbo:annotation package="com.xmutca"></dubbo:annotation> <!-- 使用Annotation自動註冊Bean,只掃描@Controller --> <context:component-scan base-package="com.xmutca" use-default-filters="false"> <!-- base-package 若是多個,用「,」分隔 --> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 默認的註解映射的支持,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping --> <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager"> <mvc:message-converters register-defaults="true"> <!-- 將Jackson2HttpMessageConverter的默認格式化輸出爲true --> <!-- 配置Fastjson支持 --> <bean class="com.ydyx.core.web.converter.CustomerFastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="features"> <list> <!-- 輸出key時是否使用雙引號 --> <value>QuoteFieldNames</value> <!-- 是否輸出值爲null的字段 --> <!-- <value>WriteMapNullValue</value> --> <!-- 數值字段若是爲null,輸出爲0,而非null --> <value>WriteNullNumberAsZero</value> <!-- List字段若是爲null,輸出爲[],而非null --> <value>WriteNullListAsEmpty</value> <!-- 字符類型字段若是爲null,輸出爲"",而非null --> <value>WriteNullStringAsEmpty</value> <!-- Boolean字段若是爲null,輸出爲false,而非null --> <value>WriteNullBooleanAsFalse</value> <!-- null String不輸出 --> <value>WriteNullStringAsEmpty</value> <!-- null String也要輸出 --> <!-- <value>WriteMapNullValue</value> --> </list> </property> <property name="defaultDateFormat" value="yyyy-MM-dd"></property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- REST中根據URL後綴自動斷定Content-Type及相應的View --> <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> <property name="mediaTypes" > <map> <entry key="json" value="application/json"/> </map> </property> <!-- 這裏是否忽略掉accept header,默認就是false --> <property name="ignoreAcceptHeader" value="true"/> <property name="favorPathExtension" value="true"/> </bean> <!-- 視圖文件解析配置 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="${web.view.prefix}"/> <property name="suffix" value="${web.view.suffix}"/> </bean> <!-- 對靜態資源文件的訪問, 將沒法mapping到Controller的path交給default servlet handler處理 --> <mvc:default-servlet-handler/> <!-- 定義無Controller的path<->view直接映射 --> <mvc:view-controller path="/" view-name="redirect:${web.view.index}"/> <!-- 基於註解式子的異常處理 --> <bean id="exceptionHandlerExceptionResolver" class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver"></bean> <!-- Shiro end --> <!-- 上傳文件攔截,設置最大上傳文件大小 10M=10*1024*1024(B)=10485760 bytes --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="${web.maxUploadSize}" /> </bean> </beans>
第四種方案:使用SpringMVC的自定義屬性編輯器express
@InitBinder protected void initBinder(WebDataBinder binder) { // String類型轉換,將全部傳遞進來的String進行先後空格處理, null字符串處理 binder.registerCustomEditor(String.class, new PropertyEditorSupport() { @Override public void setAsText(String text) { setValue(text == null ? null : text.trim()); } @Override public String getAsText() { Object value = getValue(); return value != null ? value.toString() : ""; } }); // Date 類型轉換 binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { @Override public void setAsText(String text) { setValue(DateUtils.parseDate(text)); } @Override public String getAsText() { Date date = (Date) getValue(); return DateUtils.formatDate(date, "yyyy-MM-dd"); } }); }
DateUtils源代碼:apache
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.lang.time.DateFormatUtils; /** * 日期工具類, 繼承org.apache.commons.lang.time.DateUtils類 * */ public class DateUtils extends org.apache.commons.lang3.time.DateUtils { private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" ,"yyyyMMdd"}; /** * 獲得當前日期字符串 格式(yyyy-MM-dd) */ public static String getDate() { return getDate("yyyy-MM-dd"); } /** * 獲得當前日期字符串 格式(yyyy-MM-dd) pattern能夠爲:"yyyy-MM-dd" "HH:mm:ss" "E" */ public static String getDate(String pattern) { return DateFormatUtils.format(new Date(), pattern); } /** * 獲得日期字符串 默認格式(yyyy-MM-dd) pattern能夠爲:"yyyy-MM-dd" "HH:mm:ss" "E" */ public static String formatDate(Date date, Object... pattern) { String formatDate = null; if (pattern != null && pattern.length > 0) { formatDate = DateFormatUtils.format(date, pattern[0].toString()); } else { formatDate = DateFormatUtils.format(date, "yyyy-MM-dd"); } return formatDate; } /** * 獲得日期時間字符串,轉換格式(yyyy-MM-dd HH:mm:ss) */ public static String formatDateTime(Date date) { return formatDate(date, "yyyy-MM-dd HH:mm:ss"); } /** * 獲得當前時間字符串 格式(HH:mm:ss) */ public static String getTime() { return formatDate(new Date(), "HH:mm:ss"); } /** * 獲得當前日期和時間字符串 格式(yyyy-MM-dd HH:mm:ss) */ public static String getDateTime() { return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"); } /** * 獲得當前年份字符串 格式(yyyy) */ public static String getYear() { return formatDate(new Date(), "yyyy"); } /** * 獲得當前月份字符串 格式(MM) */ public static String getMonth() { return formatDate(new Date(), "MM"); } /** * 獲得當天字符串 格式(dd) */ public static String getDay() { return formatDate(new Date(), "dd"); } /** * 獲得當前星期字符串 格式(E)星期幾 */ public static String getWeek() { return formatDate(new Date(), "E"); } /** * 日期型字符串轉化爲日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMdd" } */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } /** * 獲取過去的天數 * * @param date * @return */ public static long pastDays(Date date) { long t = new Date().getTime() - date.getTime(); return t / (24 * 60 * 60 * 1000); } /** * 獲取過去的小時 * @param date * @return */ public static long pastHour(Date date) { long t = new Date().getTime()-date.getTime(); return t/(60*60*1000); } /** * 獲取過去的分鐘 * @param date * @return */ public static long pastMinutes(Date date) { long t = new Date().getTime()-date.getTime(); return t/(60*1000); } /** * 轉換爲時間(天,時:分:秒.毫秒) * @param timeMillis * @return */ public static String formatDateTime(long timeMillis){ long day = timeMillis/(24*60*60*1000); long hour = (timeMillis/(60*60*1000)-day*24); long min = ((timeMillis/(60*1000))-day*24*60-hour*60); long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60); long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000); return (day>0?day+",":"")+hour+":"+min+":"+s+"."+sss; } /** * 獲取某一天的開始時間(0點) * @param date * @return */ public static Date getDateStart(Date date) { if (date == null) { return null; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 00:00:00"); } catch (ParseException e) { e.printStackTrace(); } return date; } /** * 獲取某一天的結束時間(23:59) * * @param date * @return */ public static Date getDateEnd(Date date) { if (date == null) { return null; } SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { date = sdf.parse(formatDate(date, "yyyy-MM-dd") + " 23:59:59"); } catch (ParseException e) { e.printStackTrace(); } return date; } /** * 比較兩個日期時間的大小,反回1表示preDateStr > nextDateStr,0就相等,-1爲小於 * @author: weihuang.peng * @param preDateStr * @param nextDateStr * @return result */ public static int compareDate(Object preDateStr, Object nextDateStr) { int result = 0; Date preDate = parseDate(preDateStr); Date nextDate = parseDate(nextDateStr); try { result = preDate.compareTo(nextDate); } catch (Exception e) { result = 0; e.printStackTrace(); } return result; } /** * 獲取某一天的前幾天或者後幾天,根據數字符號決定天數 * @author: weihuang.peng * @param date * @param days * @return */ public static String getPastDayStr(Object dateObj, int days) { Date date = parseDate(dateObj); long time = date.getTime() + days * (long)(24 * 60 * 60 * 1000); return formatDate(new Date(time)); } /** * preDateStr - nextDateStr 返回秒數 * @author: huiyang.yu * @param preDateStr * @param nextDateStr * @return */ public static long getSubactDate(Object preDateStr, Object nextDateStr) { Date preDate = parseDate(preDateStr); Date nextDate = parseDate(nextDateStr); long result = (preDate.getTime() - nextDate.getTime()) / 1000L; return result; } /** * 返回過去的天數: preDateStr - nextDateStr * @author: weihuang.peng * @param preDateStr * @param nextDateStr * @return */ public static long getDifferDate(Object preDateStr, Object nextDateStr) { return getSubactDate(preDateStr, nextDateStr) / (60 * 60 * 24L); } /** * 傳入日期時間與當前系統日期時間的比較, * 若日期相同,則根據時分秒來返回 , * 不然返回具體日期 * @author: huiyang.yu * @param updateDate 傳入日期 * @param updateTime 傳入時間 * @return 日期或者 xx小時前||xx分鐘前||xx秒前 */ public static String getNewUpdateDateString(String updateDate, String updateTime) { String result = updateDate; long time = 0; if (updateDate.equals(DateUtils.getDate())) { time = DateUtils.getSubactDate(DateUtils.getDateTime(), updateDate + " " + updateTime); if (time >= 3600) { result = time / 3600 + "小時前"; } else if (time >= 60) { result = time / 60 + "分鐘前"; } else if (time >= 1) { result = time + "秒前"; } else { result = "剛剛"; } } else if (result.length() >= 10) { result = result.substring(5); } return result; } }