2012-05-04 34 views
3

我有03-AUG-12 08.15.00.000000000 PM -05:00 的時間戳我無法在yyyy-MM-dd HH:mm:ss的表單中獲得String表示形式。從Oracle數據庫轉換AM/PM日期時間字符串

這裏是我的代碼:

public static void convert() { 

    String oldstring = "03-AUG-12 08.15.00.000000000 PM -05:00"; 
    Date date = null; 
    try { 
     date = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.S aa").parse(oldstring); 
    } 
    catch (ParseException e) { 
     e.printStackTrace(); 
    } 

    String newstring = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); 
    System.out.println(newstring); 
} 

基本上它是從Oracle數據庫時區格式的時間戳。

+0

您的預期產量是多少? –

+0

預計輸出爲:2012-08-03 20:15:00 檢索輸出爲:2012-08-03 08:15:00 即PM部分沒有反映在輸出中。 –

+0

看到我的答案。 PM部分被忽略,因爲在解析日期時使用'HH'而不是'hh'。 –

回答

3

改變這一行是這樣的:

 date = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa").parse(oldstring); 

您需要使用小寫h其解析AM/PM小時1-12。

+0

感謝您提及小寫字母h。丹科! –

4

不能使用的SimpleDateFormat來分析這樣的字符串,至少在沒有一定的侷限性:

  • 的時區標誌一樣-05:00(根據ISO 8601)之前,不支持的Java 7.使用Java 7,您可以使用XXX模式解析它。

  • 要正確解析月份名稱,應該指定您需要英文區域設置。

  • 毫秒(S)模式解析無限數量的數字。如果您的字符串包含「08.15.00.100000000」,SimpleDateFormat會將其解析爲8:15:00和100000000ms,爲期望值增加將近28小時。如果您確定該值始終爲0,則可以忽略此問題。

如果你能接受的最後一個問題,使用Java 7,你應該使用這樣的事:

new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa XXX", Locale.ENGLISH)

+0

@Jambjo - 非常感謝Java 7特性的深入瞭解,因爲我並不知道這一點。我該如何成功地從結果集中獲取該值(從Timestamp類型的時區,在oracle數據庫中),因爲我沒有看到resultSet.getTimeStampWithTimezone或類似的結果集操作? ** while(resultSet.next()){ java.sql.Timestamp getTimeStamp = resultSet.getTimestamp(「date_val」); } ** 我目前在使用Java 6.請幫助我。我需要從數據庫中獲取數據,並將其解析爲我在問題中提到的格式並檢索一個字符串。等待一個答覆。 –

+0

爲什麼你需要數據庫中的時區? 'resultSet.getTimestamp()'有什麼問題? – jarnbjo

1

TL;博士

DateTimeFormatter f = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern ("dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ").toFormatter().withLocale (Locale.US); 
OffsetDateTime odt = OffsetDateTime.parse ("03-AUG-12 08.15.00.000000000 PM -05:00" , f); 

的對象,而不是字符串

你提到過Oracle。從數據庫檢索數據時,請使用對象而不是字符串。詢問您的ResultSet是否有java.sql.Timestamp對象。

java.sql.Timestamp ts = myResultSet.getTimestamp(…); 

將麻煩的舊日期時間類轉換爲現代java.time類型。尋找在舊類上添加的新方法以便於轉換爲java.time。

Instant instant = ts.toInstant(); 

或者優選地,如果使用JDBC 4.2或更高版本,並用Java 8或更高,則可以通過ResultSet::getObject方法來檢索一個java.time.Instant

但是,如果你必須解析一個字符串,請繼續閱讀。

避免舊日期,時間類

與Java的早期版本中捆綁的舊日期,時間類是麻煩和混亂。現在由java.time類取代。

納秒

零的那一堆必須代表一個幾分之一秒與nanosecond分辨率,高達小數的九個數字。舊的日期時間類只能處理milliseconds,但幸運的是,現代java.time類確實可以處理高達納秒的分辨率。

使用java.time

定義一個格式化模式來解析給定的輸入。順便說一下,您的數據格式不夠理想;在將來,對錶示日期時間值的字符串使用ISO 8601標準格式。

我們使用「構建器」來指定不區分大小寫的解析。正確縮寫英文的月份名稱是首字母大寫,Aug,但您的輸入使用全部大寫。

String pattern = "dd-MMM-yy hh.mm.ss.SSSSSSSSS a ZZZZZ"; 
DateTimeFormatterBuilder fb = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern (pattern); 

告訴構建者實例化我們的格式化程序。 Locale確定(a)翻譯日期名稱,月份名稱等的人類語言,以及(b)確定縮寫,大寫,標點等問題的文化規範。

Locale l = Locale.US; 
DateTimeFormatter f = fb.toFormatter().withLocale (l); 

最後,將字符串解析爲OffsetDateTime對象。

String input = "03-AUG-12 08.15.00.000000000 PM -05:00"; 
OffsetDateTime odt = OffsetDateTime.parse (input , f); 

轉儲到控制檯。請注意我們的8 PM是如何轉化爲20小時的24-hour clock的值。

System.out.println ("input: " + input + " | odt.toString(): " + odt); 

輸入:03-AUG-12 08.15.00.000000000 PM -05:00 | odt.toString():2012-08-03T20:15-05:00

time zoneoffset-from-UTC一組用於處理異常,如日光節約時間(DST)的規則。如果需要,請應用ZoneId以獲得ZonedDateTime

ZoneId z = ZoneId.of(「America/Montreal」); 
ZonedDateTime zdt = odt.atZoneSameInstant(z); 

關於java.time

java.time框架是建立在Java 8和更高版本。這些課程取代了麻煩的舊日期時間課程,如java.util.Date,.Calendar,& java.text.SimpleDateFormat

Joda-Time項目,現在在maintenance mode,建議遷移java.time。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。

大部分的java.time功能後移植到Java 6 和ThreeTenABP還適於Android(見How to use…)。

ThreeTen-Extra項目擴展java.time與其他類。這個項目是未來可能增加java.time的一個試驗場。你可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuarter,等等。

相關問題