2010-11-17 71 views
9

我有一個模式yyyy-MM-dd hh:mm a 中的字符串,我可以分別獲取上述字符串表示日期的時區對象。將字符串轉換爲帶時區日期

我想將其轉換爲以下格式。 yyyy-MM-dd HH:mm:ss Z

我該怎麼做?

+0

http://joda-time.sourceforge.net/使所有日期的操作在java中多容易得多 – NimChimpsky 2010-11-17 11:09:52

+0

@Emil我才知道這個功能你說:),謝謝了。 – John 2010-11-17 11:41:33

+1

FYI時,[喬達-時間](http://www.joda.org/joda-time/)項目現在在[維護模式](https://en.wikipedia.org/wiki/Maintenance_mode)中,用該團隊建議遷移到[java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html)類。 – 2017-01-22 21:47:14

回答

5

使用SimpleDateFormat

String string1 = "2009-10-10 12:12:12 "; 
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z") 
sdf.setTimeZone(tz); 
Date date = sdf.parse(string1); 
+0

某些時候,getID()返回像這樣的字符串「America/Argentina/Ushuaia」。那麼我怎樣才能使用它 – John 2010-11-17 11:42:09

+0

-1:這將在大多數時區拋出ParseException。 – 2010-11-17 12:51:16

+0

@邁克爾Konietzka @shal我趕緊我錯過了,更新了答案 – 2010-11-17 12:59:41

0

使用日期模式創建的SimpleDateFormat一個新的實例。之後,您可以將其稱爲解析方法,以將日期字符串轉換爲java.util.Date對象。

16

您可以使用SimpleDateFormatyyyy-MM-dd HH:mm:ss並明確設置TimeZone

public static Date getSomeDate(final String str, final TimeZone tz) 
    throws ParseException { 
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm a"); 
    sdf.setTimeZone(tz); 
    return sdf.parse(str); 
} 

/** 
* @param args 
* @throws IOException 
* @throws InterruptedException 
* @throws ParseException 
*/ 
public static void main(final String[] args) throws ParseException { 
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); 
    System.out.println(sdf.format(getSomeDate(
     "2010-11-17 01:12 pm", TimeZone.getTimeZone("Europe/Berlin")))); 
    System.out.println(sdf.format(getSomeDate(
     "2010-11-17 01:12 pm", TimeZone.getTimeZone("America/Chicago")))); 
} 

打印出:

2010-11-17十三時12分00秒+0100

2010- 11-17 20:12:00 +0100

更新2010-12-01: 如果你想明確地印出特殊的時區,將其設置在SimpleDateFormat的:

sdf.setTimeZone(TimeZone .getTimeZone("IST")); 
System.out.println(sdf.format(getSomeDate(
    "2010-11-17 01:12 pm", TimeZone.getTimeZone("IST")))); 

它打印2010-11-17 13:12:00 +0530

+0

由於內容Mr.michael,日期和時間根據Timezone.Note下來+100得到改變,它不會改變區偏移 – John 2010-11-18 11:37:39

+0

@shal :對不起,我不明白你的第二句話。你認爲有什麼不對嗎? – 2010-11-18 11:55:56

+0

@邁克爾,我說的時間也越來越正確轉換,但看到日期值的「Z」部分印有「+0100」如果我從GMT轉換日期IST那麼「不changes.For如Z「部分的轉換日期必須爲」+0530「。 – John 2010-12-01 10:24:57

0

毫無疑問,這是通常使用的格式是一個形式2014-10-05T15:23:01Z(TZ)

對於一個具有使用此代碼

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); 
String dateInString = "2014-10-05T15:23:01Z"; 

try { 

    Date date = formatter.parse(dateInString.replaceAll("Z$", "+0000")); 
    System.out.println(date); 

} catch (ParseException e) { 
    e.printStackTrace(); 
} 

它的輸出將是太陽10月05日20:53:01 IST 2014

然而,我不知道爲什麼我們必須替換所有「Z」,如果你不添加replaceAll程序將失敗。

4

TL;博士

LocalDateTime.parse( // Parse string as value without time zone. 
    "2017-01-23 12:34 PM" , 
    DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm a") 
).atZone(ZoneId.of("America/Montreal")) // Assign time zone. 
.toString()    // Generate string: 2017-01-23T17:34:00Z 
.replace("T" , " ") // Substitute SPACE for 'T' in middle. 
.replace("Z" , " Z") // Insert SPACE before 'Z'. 

避免遺留日期時類

其他答案使用麻煩的舊日期時類(DateCalendar等),現在的傳統,由取代java.time類。

LocalDateTime

我在圖案YYYY-MM-DD HH的字符串:毫米

這樣的輸入字符串缺少的任何指示偏移從-UTC或時區。所以我們解析爲LocalDateTime

定義一個格式模式,以便將您的輸入與DateTimeFormatter對象相匹配。

String input = "2017-01-23 12:34 PM" ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm a"); 
LocalDateTime ldt = LocalDateTime.parse(input , f); 

ldt.toString():2017-01-23T12:34

注意,一個LocalDateTime特定時刻,只有各種可能的時刻,一個模糊的概念。例如,巴黎午夜過後幾分鐘,法國在加拿大蒙特利爾仍然是「昨天」。因此,如果沒有時區的上下文,例如Europe/ParisAmerica/Montreal,只是說「午夜後幾分鐘」沒有意義。

ZoneId

和我可以得到單獨的時區對象,其中上面的字符串表示的日期。

時區由ZoneId類表示。

continent/region的格式指定一個proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母縮寫,如ESTIST,因爲它們是而不是真正的時區,不是標準化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of("America/Montreal"); 

ZonedDateTime

應用ZoneId獲得ZonedDateTime這的確是時間軸,在歷史上的一個特定的時刻上的一個點。

ZonedDateTime zdt = ldt.atZone(z); 

zdt.toString():2017-01-23T12:34-05:00 [美國/蒙特利爾]

Instant

我想將其轉換爲下面的格式。 YYYY-MM-DD HH:MM:SSž

首先,知道一個Z文字字符是短期的和Zulu裝置UTC。換句話說,零小時的offset-from-UTC+00:00

Instant類表示UTCnanoseconds(最多9個(9)小數的位數)的分辨率在時間軸上的力矩。

您可以從ZonedDateTime中提取Instant對象。

Instant instant = zdt.toInstant(); // Extracting the same moment but in UTC. 

爲了產生在標準ISO 8601格式的字符串,如2017-01-22T18:21:13.354Z,呼叫toString。標準格式沒有空格,使用T將year-month-date與hour-minute-second分開,並將Z附加爲零的偏移量。

String output = instant.toString(); 

instant.toString():2017-01-23T17:34:00Z

我強烈建議使用標準的格式只要有可能。如果您堅持使用所需格式的空格,請在DateTimeFormatter對象中定義您自己的格式模式,或者僅對Instant::toString的輸出執行字符串操作。

String output = instant.toString() 
         .replace("T" , " ") // Substitute SPACE for T. 
         .replace("Z" , " Z"); // Insert SPACE before Z. 

輸出:

2017年1月23日17點34分00秒ž試試這個code live at IdeOne.com


關於java.time

java.time框架是建立在Java 8和更高版本。這些類取代了日期時間類legacy,如java.util.Date,Calendar,& SimpleDateFormat

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

從何處獲取java.time類?

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