<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在專案開發過程中,前端傳遞過來的時間(Date型別)在A模組是正確的,然後A模組呼叫B模組將時間(Date型別)作為引數傳過去,然後B模組接收到的時間有誤差,天數會多一天,小時少10小時,這應該是SpringCloud Feign元件造成的問題
我這裡的解決辦法是在A模組呼叫之前先將時間(Date型別)轉為String型別,B模組接收到A模組的引數後將時間由String型別再轉為Date型別就可以了
/** * 日期格式化為字串 * * @param source * @return java.lang.String * @author zxzhang * @date 2020/2/9 */ public Date string2date(String source) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.parse(source); } /** * 字串解析為日期 * * @param source * @return java.lang.String * @author zxzhang * @date 2020/2/9 */ public String date2String(Date source) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(source); }
到此 Feign 傳輸Date型別引數存在誤差的問題完美解決。
請看下邊這段程式碼
public static void main(String[] args) throws Exception { Date date1 = new Date(); System.out.println("date1: " + date1.toString()); Date date2 = new Date(date1.toString()); System.out.println("date2: " + date2.toString()); }
執行結果如下
date1: Mon Jul 22 08:47:19 CST 2019
date2: Mon Jul 22 22:47:19 CST 2019
當前時間是2019年7月22日8點48分,CST是中國的時區China Standard Time的簡稱,但是可以看到date2的輸入比實際時間多了14個小時。
CTS代表的時區其實有四個(Central Standard Time (USA) UT-6:00、Central Standard Time (Australia) UT+9:30、China Standard Time UT+8:00、Cuba Standard Time UT-4:00),同時表示美國,澳大利亞,中國,古巴四個國家的標準時間。
原因
new Date(date1.toString())
這個方法會呼叫Date.parse(String)方法,它傳的引數是Mon Jul 22 08:47:19 CST 2019,這個方法上有一段註釋
* <li>Any word that matches <tt>EST, CST, MST</tt>, or <tt>PST</tt>, * ignoring case, is recognized as referring to the time zone in * North America that is five, six, seven, or eight hours west of * Greenwich, respectively. Any word that matches <tt>EDT, CDT, * MDT</tt>, or <tt>PDT</tt>, ignoring case, is recognized as * referring to the same time zone, respectively, during daylight * saving time.</ul><p>
可以看到CST會被當作美國中部的時區Central Standard Time,即JVM認為你傳入的時間是美國中部的時間,而當date2呼叫toString方法的時候,它會檢測到系統的時區是中國,就會自動加14個小時(東八區與西六區的時差),就變成了Mon Jul 22 22:47:19 CST 2019
這個問題其實如果自己寫程式碼的話很難出現,因為所有的Java書籍都不會這麼教,大多數都是通過SimpleDateFormat,進行Date和String的轉換,畢竟new Date(date1.toString())這個方法已經標註為廢棄了
Feign使用者端在進行通訊時,會呼叫Date的toString方法轉為String型別,伺服器端在接受的時候,使用的就是new Date(String)這個方法,這裡就會發生前邊介紹的問題,產生14個小時的時差
在使用者端新增程式碼,規定Feign在將Date引數轉化成String引數的格式:
import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.openfeign.FeignFormatterRegistrar; import org.springframework.core.convert.converter.Converter; import org.springframework.format.FormatterRegistry; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Slf4j @Component public class FeignDateFormatRegister implements FeignFormatterRegistrar { @Override public void registerFormatters(FormatterRegistry registry) { registry.addConverter(Date.class, String.class, new Date2StringConverter()); } private class Date2StringConverter implements Converter<Date, String> { @Override public String convert(Date source) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return sdf.format(source); } } }
在伺服器端新增程式碼,規定SpringContext在String和Date時的用的轉化器,讓轉化器知道我們在使用者端設定的引數格式:
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import javax.annotation.PostConstruct; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @Slf4j @Configuration public class FeignConfiguration { @Autowired private RequestMappingHandlerAdapter handlerAdapter; /** * 增加字串轉日期的功能 */ @PostConstruct public void initEditableValidation() { ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) handlerAdapter.getWebBindingInitializer(); if (initializer.getConversionService() != null) { GenericConversionService genericConversionService = (GenericConversionService) initializer.getConversionService(); genericConversionService.addConverter(String.class, Date.class, new String2DateConverter()); } } class String2DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return simpleDateFormat.parse(source); } catch (ParseException e) { log.error("", e); } return null; } } }
注意以上兩個設定類需要自己設定包掃描之類的把它們加到Spring環境中
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45