簡體   English   中英

Java轉換時區

[英]Java Convert TimeZone

我已經看到了幾個類似的問題,但是我不能完全正確地進行轉換。 我想轉換如下日期

20121116203036Z

2012-11-16 15:30:36

我有以下代碼

    dateStringTime.set( year, mon-1 , day, hour, minute, second );

    Date date = dateStringTime.getTime();

    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    formatter.setTimeZone(TimeZone.getTimeZone("EST"));

    String output = formatter.format();
    return output;

可行,但它給了我以下

2012-11-16 20:30:36

關於如何獲得15而不是20的任何建議?

首先,您的代碼未格式化“日期”,請嘗試以下操作:

  String output = formatter.format(date);

我還注意到您沒有向我們展示如何創建dateStringTime (我假設它是Calendar 我注意到Calendar.getInstance()方法還接受一個可能會影響時區的Locale

我的代碼:

    Calendar dateStringTime = Calendar.getInstance();

    //convert 20121116203036Z       
    int year = 2012;
    int mon = 11;
    int day = 16;
    int hour = 20;
    int minute = 30;
    int second = 36;

    dateStringTime.set( year, mon-1 , day, hour, minute, second );

    Date date = dateStringTime.getTime();

    DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    formatter.setTimeZone(TimeZone.getTimeZone("EST"));

    String output = formatter.format(date);
    System.out.println(output);     

我的輸出:

2012-11-16 21:30:36

您注意到小時會休息一小時嗎? 那是因為我在中央時區,而當我要求輸入“ EST”時,JVM會將其考慮在內。 它認為原始時間在當前時區。

當您注釋掉時會發生什么

        //formatter.setTimeZone(TimeZone.getTimeZone("EST"));

時區。 getDefault()將給出運行時時區。 如果要從date刪除getRawOffet值,則將具有UTC。 另一步驟是從UTC添加/刪除EST值,然后完成轉換

您的問題是您在錯誤的時區中輸入日期。 當你這樣做

dateStringTime.set(year, month-1 , day, hour, minute, second);

您實際上是使用默認時區輸入日期,在您的情況下,這不太可能是UTC。 在幕后,Java Date表示為UTC,因此它將日期/時間轉換為UTC,而不是直接在UTC中輸入。

基本上,它執行以下時區轉換序列:EST-> UTC-> EST

如果打算使用UTC指定日期/時間,則應執行以下操作:

dateStringTime.setTimeZone(TimeZone.getTimeZone("UTC"));
dateStringTime.set(year, month-1 , day, hour, minute, second);

然后,您只需要從UTC-> EST開始,就應該獲得正確的輸出。

TL;博士

OffsetDateTime.parse(
    "20121116203036Z" , 
    DateTimeFormatter.ofPattern( "yyyyMMddHHmmssX" ) 
).toLocalDateTime()
 .toString()
 .replace( "T" , " " )

java.time

Java內置的java.time類使此操作變得容易。 避免麻煩的舊日期時間類,例如DateDateFormat ,現在是舊的。

String input = "20121116203036Z";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "yyyyMMddHHmmssX" );
OffsetDateTime odt = OffsetDateTime.parse( input , f );

odt.toString():2012-11-16T20:30:36Z

要獲取輸出,您可以定義一個自定義DateTimeFormatter 一種比較懶惰的方法是將轉換為LocalDateTime只是在最后丟失Z ,這表示從UTC偏移( ZZulu縮寫,表示UTC)。 然后使用toString生成ISO 8601格式的字符串,除了用空格代替中間的T

String output = odt.toLocalDateTime().toString().replace( "T" , " " );

2012-11-16 20:30:36

請參閱IdeOne.com中的實時代碼

ISO 8601

我建議不要將您的格式用於此類日期時間值,而應使用ISO 8601標准格式。 該值的通常格式為2016-11-16T02:45:02Z 注意中間年月日與小時-分鍾-秒之間的T 另外,該標准允許最小化分隔符的使用,認為分隔符是“基本”版本: 20161116T024502Z但將T保留在中間。

java.time類可以解析並生成擴展版本,但不能解析基本版本。


關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊日期時間類,例如java.util.Date.Calendarjava.text.SimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。

大部分的java.time功能后移植到Java 6和7 ThreeTen,反向移植 ,並進一步適應的AndroidThreeTenABP (見如何使用...... )。

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM