2016-04-20 79 views
2

我想要做的是存儲日期,以毫秒爲單位表示,即從當前時間開始的下一個午夜。所以,在晚上10點11分發布這個消息,我想要一個日期,明天上午12:00。對於這個任務,我寫這行代碼(知道有一天86400000毫秒):添加毫秒但不在正確時間的Android日期

long time = System.currentTimeMillis() + (86400000 - (System.currentTimeMillis() % 86400000)); 

該生產線設計爲從最後午夜計算額外的毫秒。減去從一個整天找到下一個午夜的時間,然後將其添加到當前時間,以便新值是下一個午夜的值。不管什麼原因,調用#toString()方法時,我用來調試的日期對象吐出「Wed Apr 20 20:00:00 EDT 2016」。目前的時間據稱是「2016年4月19日22:08:34美國東部時間2016」,與其他日期的計算同時進行。

這意味着毫秒長實際上代表第二天晚上8:00,而我希望它代表中午12:00。任何人都可以幫助我發現我的邏輯中的缺陷嗎?

我很可能錯過了一些明顯的東西,所以請耐心等待。

注:我也嘗試計算這樣的時間:

long time = System.currentTimeMillis() - (System.currentTimeMillis() % 86400000) + 86400000; 

,但是這導致在同一Date對象。

+2

您需要調整您的時區,'System.currentTimeMillis的()'是UTC – Breavyn

回答

1

您忘記調整您的時區。這是一個簡單的方法來實現這一點。

TimeZone tz = TimeZone.getDefault(); 
long time = System.currentTimeMillis() + (86400000 - (System.currentTimeMillis() % 86400000)); 
time -= tz.getOffset(time); 

System.out.println(new Date(time)); 
+0

這臺代表從當前日期2天午夜的時間。當我打印出日期對象時,它會在4/21(這裏的日期是4/19)返回午夜。在這種情況下,我可以減去一天,但總是會提前一天?只是爲了安全的目的。 – NuffsaidM8

1

java.time

您使用的是早已取代有缺陷的麻煩日期時間類,首先由喬達時庫,現在它的繼任者,Java中內嵌的8 java.time框架然後。很多java.time已被移植到Java 3,然後由ThreeTenABP項目改編爲Android。

Instant是UTC時間軸上的一個時刻,分辨率爲納秒。

Instant instant = Instant.now(); 

應用時區以獲得ZonedDateTime。時區對確定日期至關重要。它可能已經是你的東邊的「明天」或者西邊的「昨天」。

ZoneId zoneId = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ZonedDateTime.ofInstant(zoneId); 

要獲得一天中的第一個時刻,請不要假設時間爲00:00:00.0。夏令時等異常可能會導致不同的時間。讓java.time確定時間。要做到這一點,我們必須通過LocalDate課程。

LocalDate today = zdt.toLocalDate(); 

天並不總是24小時長,這是您的問題和代碼中的錯誤假設。再次,讓java.time通過調用plusDays來確定第二天。

LocalDate tomorrow = LocalDate.plusDays(1); 
ZonedDateTime zdtTomorrowStart = tomorrow.atStartOfDay(zoneId); 

我建議你避免跟蹤日期時間值作爲從時代計數。這很容易出錯,而且非常難以調試。當你從納秒分辨率到毫秒時,你將會丟失數據。但是,如果你堅持。

long millis = zdtTomorrowStart.toInstant().toEpochMilli(); 
0

直接時間計算可能會很棘手,但也有不少案例。我想,以避免它最簡單的解決方法是:

// now, with current timezone and locale 
    Calendar calendar = new GregorianCalendar(); 
    // tomorrow 
    calendar.add(Calendar.DAY_OF_MONTH, 1); 
    // midnight 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MILLISECOND, 0); 
    // get the resulting date 
    Date date = calendar.getTime();