11

我有以下Java.lang.String值,表示String的值爲TIMESTAMPTZ。我需要將這些Java.lang.String轉換爲oracle.sql.TIMESTAMPTZ將`Java.lang.String`轉換爲`oracle.sql.TIMESTAMPTZ`

"2016-04-19 17:34:43.781 Asia/Calcutta", 
"2016-04-30 20:05:02.002 8:00", 
"2003-11-11 00:22:15.0 -7:00", 
"2003-01-01 02:00:00.0 -7:00", 
"2007-06-08 15:01:12.288 Asia/Bahrain", 
"2016-03-08 17:17:35.301 Asia/Calcutta", 
"1994-11-24 11:57:17.303" 

我嘗試了很多方法。

樣品1:

java.text.ParseException: Unparseable date: "2016-04-19 17:34:43.781 Asia/Calcutta" 
    at java.text.DateFormat.parse(DateFormat.java:357) 

樣品2:

通過使用SimpleDateFormat

String[] timeZoneValues = new String[]{"2016-04-19 17:34:43.781 Asia/Calcutta", "2016-04-30 20:05:02.002 8:00", "2003-11-11 00:22:15.0 -7:00", "2003-01-01 02:00:00.0 -7:00", "2007-06-08 15:01:12.288 Asia/Bahrain", "2016-03-08 17:17:35.301 Asia/Calcutta", "1994-11-24 11:57:17.303"}; 
     for(String timeZoneValue: timeZoneValues){ 
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS XXX"); 
      try { 
       simpleDateFormat.parse(timeZoneValue); 
      } catch (ParseException e) { 
       e.printStackTrace(); 
      } 
     } 

即拋出異常試了

通過直接將這些String值試了一下到Timestamporacle.sql.TIMESTAMPTZ

String parse = "2016-04-19 17:34:43.781 8:00"; 
     try { 
      Timestamp timestamp = Timestamp.valueOf("2016-04-19 17:34:43.781 8:00"); 
     }catch (Exception ex){ 
      ex.printStackTrace(); 
     } 

例外:

java.lang.NumberFormatException: For input string: "781 8:000" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Integer.parseInt(Integer.java:492) 
    at java.lang.Integer.parseInt(Integer.java:527) 
    at java.sql.Timestamp.valueOf(Timestamp.java:253) 

樣品3:

String parse = "2016-04-19 17:34:43.781 Asia/Calcutta"; 
DateTimeFormatter dateTimeFormatter = ISODateTimeFormat.dateTimeNoMillis(); 
DateTime dateTime = dateTimeFormatter.parseDateTime(parse); 
Timestamp timeStamp = new Timestamp(dateTime.getMillis()); 

例外:

Invalid format: "2016-04-19 17:34:43.781 Asia/Calcutta" is malformed at " 17:34:43.781 Asia/Calcutta" 

樣品4:

try { 
TIMESTAMPTZ timestamptz = new TIMESTAMPTZ(connection, (String) colValue); 
}catch (Exception ex){ 
ex.printStackTrace(); 
} 

例外:

java.lang.IllegalArgumentException: Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff] 
    at java.sql.Timestamp.valueOf(Timestamp.java:249) 
    at oracle.sql.TIMESTAMPTZ.toBytes(TIMESTAMPTZ.java:1919) 
    at oracle.sql.TIMESTAMPTZ.<init>(TIMESTAMPTZ.java:253) 

我試圖插入TIMESTAMPTZ值到Oracle數據庫使用Apache Metamodel和我已經安裝在系統上Java 1.7

+1

輸入中沒有一致的日期格式。這將很難處理轉換。 – Mubin

+0

@Mubin即使字符串不一致,你能建議所有可能的解決方案嗎? –

+0

恐怕您可能需要創建自己的'DateFormat'實現 – user902383

回答

2

您的時間戳不是標準的Java可解析格式。所以爲了解析它們,你需要編寫處理這種格式的自定義代碼。

情侶觀察:

亞洲/加爾各答是不是一個有效的可解析的時區,因此你需要一些 機制來獲得相應的時區。

8:00也沒有一個有效的可解析時區在Java中,因此你需要 某種機制將其在一個有效的值+08格式:00

記住以上幾點,下面的代碼會做對你的需要。

SimpleDateFormat dateFormatTZGeneral = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z"); 
    SimpleDateFormat dateFormatTZISO = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS XXX"); 
    SimpleDateFormat dateFormatWithoutTZ = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 


    String[][] zoneStrings = DateFormatSymbols.getInstance().getZoneStrings(); 

    Date date = null; 

    String[] timeStampSplits = timestamp.split(" "); 
    if(timeStampSplits.length>2) { 

     String timezone = timeStampSplits[2]; 
     //First Case Asia/Calcutta 
     if(Character.isAlphabetic(timezone.charAt(timezone.length()-1))) { 

      for(String[] zoneString: zoneStrings) { 
       if(zoneString[0].equalsIgnoreCase(timezone)) { 
        timeStampSplits[2] = zoneString[2]; 
        break; 
       } 
      } 

      timestamp = createString(timeStampSplits," "); 
      date = getDate(timestamp, dateFormatTZGeneral); 
     } else { 
      //Second Case 8:00 
      timeStampSplits[2] = formatTimeZone(timeStampSplits[2]); 

      timestamp = createString(timeStampSplits," "); 
      date = getDate(timestamp, dateFormatTZISO); 
     } 

    } else { 
     // Third Case without timezone 
     date = getDate(timestamp, dateFormatWithoutTZ); 
    } 

    System.out.println(date); 

    TIMESTAMPTZ oraTimeStamp = new TIMESTAMPTZ(<connection object>,new java.sql.Timestamp(date.getTime()); 

上面的代碼使用以下實用方法

private static Date getDate(String timestamp, SimpleDateFormat dateFormat) { 
    Date date = null; 
    try { 
     date = dateFormat.parse(timestamp); 
    } catch (ParseException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return date; 
} 

private static String createString(String[] contents, String separator) { 
    StringBuilder builder = new StringBuilder(); 
    for (String content : contents) { 
     builder.append(content).append(separator); 
    } 
    builder.deleteCharAt(builder.length()-separator.length()); 

    return builder.toString(); 
} 

private static String formatTimeZone(String timeZone) { 
    String[] timeZoneSplits = timeZone.split(":"); 
    DecimalFormat formatter = new DecimalFormat("+##;-#"); 
    formatter.setMinimumIntegerDigits(2); 

    timeZoneSplits[0] = formatter.format(Integer.parseInt(timeZoneSplits[0])); 
    return createString(timeZoneSplits, ":"); 
} 

這段代碼是專門編寫滿足您的時間戳的例子,任何偏離可能無法通過這種處理,它需要更多的定製。

希望這可以幫助你。

+0

它確實有助於解析,但我仍然在插入'TIMESTAMPTZ'的值時遇到問題。它會自動將這些不同的時區值轉換爲默認數據庫的時區。例如插入數據庫的值應該是'2003-01-01 02:59:04.123 -08:00' ,但是它被插入爲'2003-01-01 16:29:04.123 Asia/Calcutta'。它根據'Asia/Calcutta'時區轉換值 –

+0

我從來沒有使用過TIMESTAMPTZ。無論何時我們需要在特定時區保存日期,我們都會使用字符串來保存它們。 – Sanjeev

0

的時間戳字符串都在不同的格式,

Ex-Here SimpleDateFormat uses pattern : 
'yyyy-MM-dd HH:mm:ss.SSS XXX' 

where X is to represent timezone in [ISO 8601 time zone][1] format.For this  
timezone valid Timestamp Strings are (-08; -0800; -08:00).So,'Asia/Kolkata' 
will not be parsed for Sample 1. 

There are three type of Timezone pattern to be assigned to SimpleDateFormat. 
**'Z'** - RFC 822 time zone. 
**'z'** - General time zone. 
**'X'** - ISO 8601 time zone. 

因此,無論是使用不同的SimpleDateFormat的,或者將所有時間戳的時區到時區的相同的模式,並使用一個單一的SimpleDateFormat。

+0

在SimpleDateFormat中有不同的標籤,其中一些是大寫字母和小寫字母。所以要小心使用它們 – Hailey

1

您必須根據即將到來的數據解析日期,即動態。有關使用何種常數由Android的信息,你必須遵循你必須遵循link 這裏link 和Java中的情況下,是一些不同格式的代碼片段 樣品1

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzzz"); 
    Date date = null; 
    try { 
     date = sdf.parse("2016-04-19 17:34:43.781 Pacific Standard Time"); 
     Log.e("date",""+date); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    sdf.setTimeZone(TimeZone.getTimeZone("IST")); 
    System.out.println(sdf.format(date)); 

樣品2

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z"); 
    Date date = null; 
    try { 
     date = sdf.parse("2016-04-19 17:34:43.781 -08:00"); 
     Log.e("date",""+date); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    sdf.setTimeZone(TimeZone.getTimeZone("IST")); 
    System.out.println(sdf.format(date)); 

樣品3

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
    Date date = null; 
    try { 
     date = sdf.parse("2016-04-19 17:34:43.781"); 
     Log.e("date",""+date); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    sdf.setTimeZone(TimeZone.getTimeZone("IST")); 
    System.out.println(sdf.format(date)); 

因此,作爲每噸這三組樣本可以解析任何類型的日期時間,除了一個格式,即亞洲/加爾各答或亞洲/巴林不能被android讀取的時區「2016-04-19 17:34:43.781 Asia/Calcutta」或Java。根據我的理解,這是PHP支持的格式。所以如果你想解析這些類型的格式,那麼我想你必須編寫自定義的SimpleDateFormat,並且必須識別這些內容並根據你的需要進行計算。

相關問題