1. 需求描述
根據業務方的需求,我們需要取數據庫里某個類型為timestamp的字段存到ES,但是這個字段需要轉成當日0時刻(即00:00:00)時刻的時間戳。
2. 解決方案
最初的設想是計算當天已經經過的毫秒數,然后通過getTime()拿到的時間戳減去當天已經經過的毫秒數加上當前時區時間戳的偏移量
import java.util.Date; import java.util.TimeZone; /** * @author * @version 1.0 * @date */ public class DateUtils { private static final long MILLIS_PER_DAY = 86400000L; private static final long TIME_ZONE_OFFSET = TimeZone.getDefault().getRawOffset(); /** * 獲取指定時間當日 00:00:00 時刻的時間戳 */ public static Long getDayTimestamp(Date date) { if (date == null) { return null; } /* 距離當日 00:00:00 時刻毫秒數 */ long dayOffsetTimestamp = date.getTime() % MILLIS_PER_DAY; return date.getTime() - dayOffsetTimestamp + TIME_ZONE_OFFSET; } private DateUtils () {} }
但是這樣存在 bug,當0時區和當前時區時間不在同一天的時候會出現問題,getTime() % MILLIS_PER_DAY 得到的是0時區當天已經經過的毫秒數而非當前時區,更悲慘的是,當時自測的時候只簡單測了一下,用 new Date() 測試的沒問題,第二天業務方反饋說有問題才發現。修復后的版本如下
import java.util.Date; import java.util.TimeZone; /** * @author * @version 1.0 * @date */ public class DateUtils { private static final long MILLIS_PER_DAY = 86400000L; private static final long TIME_ZONE_OFFSET = TimeZone.getDefault().getRawOffset(); /** * 獲取指定時間當日 00:00:00 時刻的時間戳 */ public static Long getDayTimestamp(Date date) { if (date == null) { return null; } /* 距離當日 00:00:00 時刻毫秒數 */ long dayOffsetTimestamp = (date.getTime() + TIME_ZONE_OFFSET) % MILLIS_PER_DAY; return date.getTime() - dayOffsetTimestamp; } private DateUtils () {} }