一、背景
- 項目中經常會涉及時間的處理及持久化,而時間是有時區和夏令時的;
- 而Web項目中,客戶端(瀏覽器操作系統)有1套時區和夏令時,服務端(操作系統)也有,數據庫還有,java也有。他們記錄的時間顯示出來,與用戶想看到的不一定匹配;
- 基於上述2點考慮,時間必須統一到一個地方處理:就在Java後端處理,其它地方全部使用UTC跟後臺交互;展示時,再轉成對應時區的時間處理。
二、問題
- 解決上述問題的過程中,有這樣一個業務場景:需要查詢當天0時0分0秒-當天23時59分59秒的數據;
注意:
- 需要獲取用戶當前時區下的0時0分0秒-當天23時59分59秒,而不是UTC時間下的0時0分0秒;
三、解決方案
方案一
- 可以先獲取1個今天的時間,比如System.currentTimeMillis()或者new Date(),二者等價;
- 通過時間格式化方式抹掉時分秒,不就變成了當天的0時0分0秒了嗎?
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getDefault());
String now = sdf.format(date);
try
{
Date newDate = sdf.parse(now);
long start1 = newDate.getTime();
System.out.println("current utc mills1:" + start1);
return start1;
}
catch (ParseException e)
{
System.out.println("error:" + e);
}
注意:
- Date對象然後按照本地時間格式化後,顯示的當然是當前天的本地起始時間。比如:2019-09-30;
- 再把2019-09-30轉成Date對象即可;
運行結果如下:
current utc mills1:1569772800000
方案二
使用新的java 8 sdk api(來自網絡,作者不詳):
//當天零點
LocalDateTime.of(LocalDate.now(),LocalTime.MIN).toEpochSecond(OffsetDateTime.now().getOffset());
四、總結
- 時間處理其實挺複雜的,儘量屏蔽掉多個處理的入口,使用統一的方式來做,比如時間處理全部放在Java後臺處理,數據庫使用UTC時間戳,這樣就屏蔽了數據庫時區的影響;
- 條條大道通羅馬,儘量使用簡潔的方式來做。比如項目不支持JDK8,則可以使用第1種;支持的話使用第2種會更簡單。第2種的使用方式不太好理解。