2017-08-01 47 views
2

我有兩個紀元時間戳,我試圖找到兩個時間戳之間的天數。斯卡拉兩個紀元日之間的天數

這是我現在有:

dateFrom = inputEntry.getValue(inputFields(0).get).asInstanceOf[String].toLong 
dateTo =inputEntry.getValue(inputFields(1).get).asInstanceOf[String].toLong 

例子:

dateFrom dateTo  result 
1501583232 1501641000 1 
1501583232 1501986600 5 

我開始與這裏有兩個劃時代日期

+2

可能的重複[獲取天數,星期和月份,因爲Epoch在Java](https://stackoverflow.com/questions/6158053/get-the-number-of-days-weeks-and-數月以來在java中的時代) –

+0

這不是重複的。這個問題從紀元秒數開始。 –

+0

這是真的,但它很容易通過從時間減去這兩天的日期來計算兩個日期之間的天數 –

回答

2

TL;博士

ChronoUnit.DAYS.between(… , …) 

詳細

Stack Overflow已經涵蓋了很多次。所以在這裏簡單地...

對於日期時間值,使用日期時間對象。只使用java.time類,避免了麻煩的遺留日期 - 時間類(日期,日曆等)。

您的意思是日期的差異或24小時的時間差異?

我會在這裏約會。

首先,將自1970-01-01T00:00:00的時代參考日期以來的整秒數翻譯爲時間軸中UTC的點。

注意數字文字末尾的L以表示long而不是int。

Instant instant = Instant.ofEpochSecond(1_501_583_232L) ; 

指定您想考慮日期的時區。

ZoneId z = ZoneId.of("America/Montreal") ; 
ZonedDateTime zdt = instant.atZone(z); 

轉換爲僅供日期使用。

LocalDate ld = zdt.toLocalDate() ; 

獲取差異。

long days = ChronoUnit.DAYS.between(ld , ld2) ; 
1

要得到你想要的結果,你必須定義你將如何計算差異。

以你的第一示例(1501583232和1501641000之間的差值應爲1天):

曆元1501583232和1501641000是因爲1970-01-01T00:00Z的秒數,因此它們是等效於以下UTC日期:

1501583232: 2017-08-01T10:27:12Z 
1501641000: 2017-08-02T02:30:00Z 

請注意,他們之間的差異是16小時2分48秒(如此,不到一天)。如果你在幾天內獲得差異,技術上它將爲零。

但是如果你考慮日期(2017-08-012017-08-02)和忽略時間(小時/分/秒),則差值可以是0或1,這取決於你的時區。

如果您只考慮UTC日期(2017-08-012017-08-02),則差異爲1天。

但如果你採取同樣的UTC在America/Los_Angeles時區上面的日期,你會得到:

1501583232: 2017-08-01T03:27:12-07:00 
1501641000: 2017-08-01T19:30-07:00 

現在差​​爲零天,如果你只考慮日期(均爲2017-08-01)不管,或日期和時間(以小時計算的差值將是16日,小於一天)。所以,你必須定義你將如何計算差異(只考慮日期,或者同時考慮日期和時間,以及將使用什麼時區)。


在你的情況,似乎你只考慮日期,而忽略了時間,但目前還不清楚它使用的是什麼時區。無論如何,您可以使用JDK的8 new java.time API(對於JDK < = 7,您可以使用ThreeTen Backport - 下面的代碼適用於兩者。唯一的區別是軟件包名稱(在Java 8中爲java.time和ThreeTen Backport(或Android的ThreeTenABP )是org.threeten.bp),但類別和方法名稱是相同的)。

該代碼基本上與@BasilBourque's answer相同,因爲它對新API非常直接(我只是想添加上面的見解)。

首先,從時代價值創造Instant的:

Instant instant1 = Instant.ofEpochSecond(1501583232L); 
Instant instant2 = Instant.ofEpochSecond(1501641000L); 

如果你想考慮的日期和時間的差異,你可以使用:

ChronoUnit.DAYS.between(instant1, instant2); 

結果將是零。

如果你想只考慮UTC日期(而忽略時間),只是做:

// convert to UTC and get just the date (day/month/year) 
LocalDate d1 = instant1.atZone(ZoneOffset.UTC).toLocalDate(); 
LocalDate d2 = instant2.atZone(ZoneOffset.UTC).toLocalDate(); 
long days = ChronoUnit.DAYS.between(d1, d2); 

的結果爲1

要轉換到不同的時區(而不是UTC),使用ZoneId類:

// use a specific timezone 
ZoneId zone = ZoneId.of("Asia/Kolkata"); 
// convert the Instant to a timezone and get only the date 
LocalDate d1 = instant1.atZone(zone).toLocalDate(); 
LocalDate d2 = instant2.atZone(zone).toLocalDate(); 
long days = ChronoUnit.DAYS.between(d1, d2); 

在這種情況下,差爲1,但正如我上面所說的,不同的時區可以產生不同的效果(可以是零或1 - 例如,將上面的代碼更改爲ZoneId.of("America/Los_Angeles"),結果爲零)。


注意,API使用IANA timezones names(總是在格式Region/City,像Asia/KolkataEurope/Berlin)。 避免使用3字母縮寫(如CSTIST),因爲它們是ambiguous and not standard

通過調用ZoneId.getAvailableZoneIds(),您可以獲得可用時區列表(並選擇最適合您的系統的時區)。

您也可以使用系統的默認時區ZoneId.systemDefault(),但即使在運行時也可以在不通知的情況下對其進行更改,因此最好使用特定的時區。