2011-09-20 118 views
83

我有從Web服務下載的長整型值列表(例如:1220227200,1220832000,1221436800 ...)。我必須將其轉換爲日期。不幸的是,這種方式,例如:在Java中將長整數轉換爲日期格式返回1970

Date d = new Date(1220227200); 

返回1970年1月1日。任何人都知道另一種方法來正確地轉換它?

+0

你能告訴你預期的值嗎?秒/毫秒的問題可能是有效的問題,但1220227200不是1/1/1970。它看起來像你傳遞0給構造函數。更多的代碼可能會有幫助。 – SJuan76

+1

@mmmiki - 你應該接受一個答案 – Stewart

+0

它返回1970年1月15日,在這裏,不是1月1日。 – njzk2

回答

111

Date constructor(點擊鏈接!)接受時間爲long毫秒,而不是秒。你需要乘以1000,並確保你提供它作爲long

Date d = new Date(1220227200L * 1000); 

在這裏,這表明

太陽年08月31日20:00:00 GMT-04:00 2008年

+10

或者,或者使用'Date d = new Date(TimeUnit.SECONDS.toMillis(1220227200L));'以獲得更清晰且更少的* magic-numberesque *解決方案。 –

35

它看起來像你的渴望是秒,而不是毫秒。日期的構造需要時間單位爲毫秒,所以

Date d = new Date(timeInSeconds * 1000); 
+4

爲什麼這會得到一個downvote?在這裏,享受反對票。 – f1sh

+4

@ f1sh:我沒有downvote,但原來的答案是不同的。他在5分鐘的寬限期內對其進行了編輯。 – BalusC

+0

感謝您的澄清。這是自己的缺點SO有...: -/ – f1sh

8

這些都是可能的時間戳在,而不是在毫秒這是需要在Java新的日期(長)構造函數。只需乘以1000,你應該沒問題。

+0

Bah .. 30秒太慢:P –

+19

更正確30000毫秒太慢 – SJuan76

0

新日期(數字)返回的日期爲1970年1月1日之後的number毫秒。很可能您的日期格式不會顯示小時,分鐘和秒鐘,以便您可以看到1970年1月1日之後的一點點。

您需要根據正確的解析路由解析日期。我不知道1220227200是什麼,但如果它是1970年1月1日之後的幾秒鐘,那麼將其乘以產生毫秒。如果不是,則在1970年之後以某種方式將其轉換爲毫秒(如果您想繼續使用java.util.Date)。

0

適合我。你可能想用multiplz它1000,因爲你得到的是從1970年的秒,你必須從毫秒1 1970年

1

1220227200對應於1980年1月15日(實際上是新日期(1220227200).toString( )返回「Thu Jan 15 03:57:07 CET 1970」)。如果你將一個長期價值傳遞給一個日期,即在01/01/1970之前它實際上將返回一個01/01/1970的日期。確保你的值不在這種情況下(低於82800000)。

3

試試這個:

Calendar cal = Calendar.getInstance(); 
cal.setTimeInMillis(1220227200 * 1000); 
System.out.println(cal.getTime()); 
3

長期價值,最有可能的,對應於Epoch時間戳和值是:

1220227200 =星期一,2008年9月01 00:00:00 GMT

1220832000 =星期一,2008年九月08日00:00:00 GMT

1221436800 =週一,2008 00:00:00 GMT

9月15日

考慮到java.util的實際情況,可以將這些長整型值轉換爲java.util.Date。日期採用的毫秒 - 如先前暗示,但也有一些缺陷 - 是這樣的:

// note: enforcing long literals (L), without it the values would just be wrong. 
Date date = new Date(1220227200L * 1000L); 

現在,正確地顯示日期,可以使用java.text.DateFormat中所示以下簡稱:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); 
df.setTimeZone(TimeZone.getTimeZone("UTC")); 
System.out.println("Wrong date time value: " + date); 
System.out.println("Correct date time value: " + df.format(date)); 

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008 
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC 
7

只有設定的時間在日曆鋼廠:使用以及使用的日期格式下面是顯示轉換後的長期價值,以java.util.Date的結果,而不 反對

Calendar c = Calendar.getInstance(); 
c.setTimeInMillis(1385355600000l); 
System.out.println(c.get(Calendar.YEAR)); 
System.out.println(c.get(Calendar.MONTH)); 
System.out.println(c.get(Calendar.DAY_OF_MONTH)); 
// get Date 
System.out.println(c.getTime()); 
36

TL;博士

Instant.ofEpochSecond(1_220_227_200L) 

知道你的數據

人們在跟蹤時間,因爲一個epoch一些使用各種精度。因此,當您獲得一些數字以被解釋爲從一個時代開始計算時,您必須確定:

  • 什麼時代?
    Many epochs dates已被用於各種系統。通常使用的是POSIX/Unix time,其中時代是UTC的1970年的第一時刻。但你不應該假設這個時代。
  • 什麼精度?
    我們正在談論秒,milliseconds,microseconds,或nanoseconds自紀元?
  • 什麼時區?
    通常,自曆元開始計數在UTC/GMT時區,即根本沒有時區偏移。但是有時候,當涉及沒有經驗或日期時間的無知的程序員時,可能會有一個隱含的時區。

就你的情況而言,正如其他人所指出的那樣,自從Unix時代以來,你似乎已經有了幾秒鐘的時間。但是你將這些秒傳遞給一個期望毫秒的構造函數。所以解決方案是乘以1,000。

教訓:

  • 確定的,不承擔,接收到的數據的含義。
  • 閱讀the doc

Graph showing various granularities of resolution in date-time systems including whole seconds, milliseconds, microseconds, and nanoseconds.

您的數據

你的數據似乎是在整秒。如果我們假設1970年開始的時代,如果我們假設UTC時區,然後1,220,227,200是2008年9月的第一天的第一時刻

喬達時間

與java.util.Date和Java捆綁在一起的日曆類是非常麻煩的。避免它們。使用Java 8中捆綁的Joda-Time庫或新的java.time package(受Joda-Time啓發)。

請注意,與j.u.Date不同,Joda-Time的DateTime確實知道它自己分配的time zone。因此,在下面看到的示例Joda-Time 2.4代碼中,請注意,我們首先使用UTC的默認假設來解析毫秒。然後,其次,我們分配巴黎的時區進行調整。在宇宙的時間軸中同一時刻,但是不同wall-clock time。爲了演示,我們再次調整到UTC。幾乎總是更好地明確指定您想要的/預期的時區,而不是依賴隱式的默認值(通常是日期時間工作中的麻煩原因)。

我們需要毫秒來構造一個DateTime。所以,你需要輸入秒數,並乘以一千。請注意,結果必須是64位long,因爲我們會溢出一個32位的int

long input = 1_220_227_200L; // Note the "L" appended to long integer literals. 
long milliseconds = (input * 1_000L); // Use a "long", not the usual "int". Note the appended "L". 

將該毫秒計數傳給構造函數。這個特定的構造函數假設計數來自1970年的Unix時代。因此,在構建之後根據需要調整時區。

使用proper time zone名稱,大洲和城市/地區的組合。切勿使用3或4個字母代碼,如EST,因爲它們既不標準也不唯一。

DateTime dateTimeParis = new DateTime(milliseconds).withZone(DateTimeZone.forID("Europe/Paris")); 

要進行演示,請再次調整時區。

DateTime dateTimeUtc = dateTimeParis.withZone(DateTimeZone.UTC); 
DateTime dateTimeMontréal = dateTimeParis.withZone(DateTimeZone.forID("America/Montreal")); 

轉儲到控制檯。請注意,蒙特利爾的日期不同,因爲新的一天已經開始在歐洲,但尚未在美國。

System.out.println("dateTimeParis: " + dateTimeParis); 
System.out.println("dateTimeUTC: " + dateTimeUtc); 
System.out.println("dateTimeMontréal: " + dateTimeMontréal); 

運行時。

dateTimeParis: 2008-09-01T02:00:00.000+02:00 
dateTimeUTC: 2008-09-01T00:00:00.000Z 
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00 

java.time

喬達時間的製造商已經要求我們儘快遷移到其更換時,java.time框架很方便。雖然Joda-Time將繼續得到積極的支持,但未來的所有開發都將在ThreeTen-Extra項目中的java.time類及其擴展上完成。

java時間框架由JSR 310定義,並內置於Java 8及更高版本中。 java.time類已被移植到ThreeTen-Backport項目上的Java 6 & 7以及ThreeTenABP項目中的Android中。

是時間軸上UTC的時刻,分辨率爲納秒。它的時代是UTC的1970年的第一個時刻。

Instant instant = Instant.ofEpochSecond(1_220_227_200L); 

應用的offset-from-UTCZoneOffset得到一個OffsetDateTime

更好的是,如果已知,則應用時區ZoneId以獲得ZonedDateTime

ZoneId zoneId = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant , zoneId); 
+1

乾杯好友。很好的解釋。從1970年開始,我得到了新的DateTime(),當時我意識到我在幾秒鐘內給它並且需要以毫秒 –

相關問題