2015-09-25 117 views
4

以毫秒爲單位給定UTC的午夜時間的建議方式是什麼?我嘗試了下面這似乎工作,想知道是否有更好/更乾淨的做同樣的事情。以millis爲單位獲得午夜紀元時間

public long toUtcMidnight(final Long date) { 
    return LocalDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.of("UTC")) 
      .toLocalDate() 
      .atStartOfDay() 
      .toInstant(ZoneOffset.UTC) 
      .toEpochMilli(); 
    } 

我們可以爲此使用Joda時間,但是我只想爲此使用java 8日期庫。

+0

這對我來說很不錯。您也可以使用GregorianCalendar方式,但我懷疑它會更好。 – pmartin8

+0

我不喜歡這樣的事實,我必須提供兩次「UTC」,一次作爲ZoneId,一次作爲偏移量:( – u07103

回答

0

你有什麼作品,但如果你在尋找更具可讀性的東西,怎麼樣使用日曆?

public long toUtcMidnight(long date) { 
     Calendar cal = Calendar.getInstance(); 
     cal.setTimeInMillis(date); 
     cal.setTimeZone(TimeZone.getTimeZone("UTC")); 
     cal.set(Calendar.HOUR_OF_DAY, 0); 
     cal.set(Calendar.MINUTE, 0); 
     cal.set(Calendar.SECOND, 0); 
     cal.set(Calendar.MILLISECOND, 0); 
     return cal.getTimeInMillis(); 
} 
+1

我不覺得這是更可讀的'truncatedTo'! – Tunaki

4

你應該能夠截斷一個Instant的一天。從javadoc

截斷的瞬間返回原始的副本領域 比設置爲零指定的單位小。

使用ChronoUnit.Days,你會清零時,分,秒,毫秒時間。

例如

Instant.ofEpochMilli(date).truncatedTo(ChronoUnit.DAYS).toEpochMilli(); 
+0

絕對整潔!看起來像truncate在內部使用UTC – u07103

0

因爲這一切都UTC只是做millis/86400_000 * 86400_000;

long(int)部分將截斷爲幾天,* msecs/day將返回msecs。

如果需要,您可以截斷爲幾周,幾小時或任何你想要的。

+0

想知道這是否會導致代碼的可讀性降低?Sotirios的解決方案看起來很可讀,請讓我知道,如果您認爲不然, – u07103

+0

這取決於您是否看到「明天見亞」或「看到亞在86400秒「?我認爲大多數程序員已經記住了以msecs爲單位的常見時間單位,但有時候我會看到一個靜態變量'MSECS_PER_DAY',在當天的msec中還會看到'msecs%86400_000' – brian

0

其他答案似乎工作太辛苦。

我使用調用atStartOfDay的方法,因爲我會將它用於任何時區。某些地區每天的第一天是而非總是00:00:00.0。而且這種方法也適用於UTC。

ZonedDateTime midnightUtc = LocalDate.now(ZoneOffset.UTC).atStartOfDay(ZoneOffset.UTC); 
long millisecondsSinceEpoch = midnightUtc.toInstant().toEpochMilli(); 

轉儲到控制檯。

System.out.println("midnightUtc: " + midnightUtc); 
System.out.println("millisecondsSinceEpoch: " + millisecondsSinceEpoch); 

運行時。

midnightUtc:2015-09-26T00:00Z

millisecondsSinceEpoch:1443225600000

+0

如果需要給定日期而不是'現在',這不會大致轉化爲最初提出的代碼嗎?此外,我想避免在代碼中重複使用'UTC'(在此使用兩次) – u07103

+0

Y我的代碼非常接近你的。英雄所見略同。我會說我的更好,因爲它分成兩行給了我們一個'ZonedDateTime',我們可以在調試,日誌記錄和斷言測試中使用。至於UTC常數的多次使用,這不是重複的。 java.time框架要求我們通過「Local」類來調用start-of-day方法。所以我們需要在離開和重新加入時間軸時應用一個時區。 Joda-Time圖書館在其分區日期時間類(DateTime)上提供了一個'withTimeAtStartOfDay'方法,但是java.time沒有(我不知道爲什麼)。 –

0

這裏是一個非常可讀的解決辦法,我使用:

long fullMsecs = System.currentTimeMillis(); 
long days = TimeUnit.MILLISECONDS.toDays(msecs); 
long truncatedMsecs = TimeUnit.DAYS.toMillis(days); 

或縮寫:

long msecs = TimeUnit.DAYS.toMillis(
       TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis()));