簡體   English   中英

Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") 將時區作為 IST

[英]Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST

我有 SimpleDateFormat 構造函數

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")

我正在解析字符串"2013-09-29T18:46:19Z".

我讀到這里 Z 代表GMT/UTC時區。 但是當我在控制台上打印這個日期時,它會為返回的日期打印 IST timezne。

現在我的問題是我的輸出是對還是錯?

您尚未設置時區,僅在日期/時間的末尾添加了一個Z ,因此它看起來像 GMT 日期/時間,但這不會更改值。

將時區設置為 GMT,它將是正確的。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

'T''Z'在這里被視為常數。 您需要傳遞不帶引號的Z 此外,您需要在輸入字符串中指定時區。

示例: 2013-09-29T18:46:19-0700格式為"yyyy-MM-dd'T'HH:mm:ssZ"

從 ISO 8601 字符串到 Java 日期對象

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
sdf.parse("2013-09-29T18:46:19Z"); //prints-> Mon Sep 30 02:46:19 CST 2013

如果您沒有設置TimeZone.getTimeZone("GMT")那么它將輸出Sun Sep 29 18:46:19 CST 2013

從 Java 日期對象到 ISO 8601 字符串

並將Date對象轉換為 ISO 8601 標准 ( yyyy-MM-dd'T'HH:mm:ss'Z' ) 使用以下代碼

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));           
System.out.println(sdf.format(new Date())); //-prints-> 2015-01-22T03:23:26Z

另請注意,沒有' '在 Z yyyy-MM-dd'T'HH:mm:ssZ打印2015-01-22T03:41:02+0000

如果您想處理 Date 的“標准”JSON 表示,那么最好使用這種模式: "yyyy-MM-dd'T'HH:mm:ssX"

注意最后的X 它將處理 ISO 8601 標准中的時區,而 ISO 8601 正是在 Javascript new Date().toJSON()中產生此語句的原因

與其他答案相比,它有一些好處:

  1. 您不需要要求您的客戶在 GMT 中發送日期
  2. 您不需要使用以下方法將 Date 對象顯式轉換為 GMT: sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

tl;博士

從 Java 8 開始,其他答案已過時。

Instant                           // Represent a moment in UTC. 
.parse( "2013-09-29T18:46:19Z" )  // Parse text in standard ISO 8601 format where the `Z` means UTC, pronounces “Zulu”.
.atZone(                          // Adjust from UTC to a time zone. 
    ZoneId.of( "Asia/Kolkata" )
)                                 // Returns a `ZonedDateTime` object. 

ISO 8601

您的字符串格式恰好符​​合ISO 8601標准。 該標准定義了將各種日期時間值表示為文本的合理格式。

java.time

舊的java.util.Date / .Calendarjava.text.SimpleDateFormat類已被 Java 8 及更高版本中內置的 java.time 框架所取代。 請參閱教程 避免使用舊類,因為它們已被證明設計不佳、令人困惑且麻煩。

舊類中的部分糟糕設計讓您感到厭煩,其中toString方法在生成實際為 UTC (GMT) 的日期時間值的文本表示時應用 JVM 的當前默認時區; 善意但令人困惑。

java.time 類在解析/生成日期時間值的文本表示時默認使用 ISO 8601 格式。 所以不需要指定解析模式。

InstantUTC時間線上的時刻。

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );

您可以根據需要應用時區來生成ZonedDateTime對象。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );

Java 中的日期時間類型表,包括現代和傳統

如果您沒有繼續使用 java8 的選項,最好使用 'yyyy-MM-dd'T'HH:mm:ssX XX ',因為它會再次正確解析(雖然只有一個 X,但情況可能並非如此。 ..取決於您的解析功能)

X 生成:+01

XXX 生成:+01:00

'Z'Z不同

'Z'只是一個字符文字,而Z是零時區偏移的時區指示符 它代表 Zulu 並指定Etc/UTC時區(其時區偏移量為+00:00小時)。

因此,請勿在模式中使用'Z'進行解析/格式化。

java.time ,現代的日期時間 API

現代日期時間 API 基於ISO 8601 ,只要日期時間字符串符合 ISO 8601 標准,就不需要明確使用DateTimeFormatter對象。 日期時間字符串2013-09-29T18:46:19Z符合 ISO 8601 標准。

演示:

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.parse("2013-09-29T18:46:19Z");
        OffsetDateTime odt = OffsetDateTime.parse("2013-09-29T18:46:19Z");
        ZonedDateTime zdt = ZonedDateTime.parse("2013-09-29T18:46:19Z");

        System.out.println(instant);
        System.out.println(odt);
        System.out.println(zdt);
    }
}

輸出:

2013-09-29T18:46:19Z
2013-09-29T18:46:19Z
2013-09-29T18:46:19Z

在線演示

Instant表示UTC時間線上的一個瞬時點。 輸出中的Z是零時區偏移的時區指示符 它代表 Zulu 並指定Etc/UTC時區(其時區偏移量為+00:00小時)。

注意#1:如果您需要找出Instant在特定時區中表示的日期和時間,您可以使用Instant#atZone例如以下代碼將打印此Instant在印度的日期和時間:

ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);

您甚至可以使用ZonedDateTime#withZoneSameInstantZonedDateTime對象從一個時區轉換為另一個時區,例如,以下代碼會將zdt轉換為ZonedDateTime對象,表示印度的日期和時間:

ZonedDateTime zdtIndia = zdt.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);

注意#2:出於任何原因,如果您需要將此Instant對象轉換為java.util.Date對象,您可以執行以下操作:

Date date = Date.from(instant);

您甚至可以將OffsetDateTimeZonedDateTime的對象轉換為java.util.Date的對象,如下所示:

Date date = Date.from(odt.toInstant());

&

Date date = Date.from(zdt.toInstant());

Trail: Date Time了解有關現代日期時間 API *的更多信息。

為什么您的java.util.Date對象打印印度日期和時間?

java.util.Date對象僅表示自稱為“紀元”的標准基本時間(即 1970 年 1 月 1 日 00:00:00 GMT(或 UTC)以來的毫秒數。 由於它不包含任何時區信息,因此它的toString函數應用 JVM 的時區以返回格式為EEE MMM dd HH:mm:ss zzz yyyyString ,該格式源自該毫秒值。 要以不同的格式和時區獲取java.util.Date對象的String表示,您需要使用具有所需格式和適用時區的SimpleDateFormat ,例如

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
String strDate = sdf.format(date);
System.out.println(strDate);

演示:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH);
        Date date = sdf.parse("2013-09-29T18:46:19Z");

        // In JVM's timezone and default format as returned by Date#toString
        System.out.println(date);

        // In UTC and custom format
        sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        String strDate = sdf.format(date);
        System.out.println(strDate);

        // In India and custom format
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
        strDate = sdf.format(date);
        System.out.println(strDate);
    }
}

輸出(我的時區是歐洲/倫敦):

Sun Sep 29 19:46:19 BST 2013
2013-09-29T18:46:19Z
2013-09-30T00:16:19+05:30

在線演示


* 出於任何原因,如果您必須堅持使用 Java 6 或 Java 7,則可以使用ThreeTen-Backport,它將大部分java.time功能向后移植到 Java 6 和 7。如果您正在為 Android 項目和 Android API 工作level 仍然不符合 Java-8,請檢查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

對於 Java 8:您可以使用內置的java.time.format.DateTimeFormatter來減少任何拼寫錯誤的機會,例如

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;

ISO_ZONED_DATE_TIME 表示2011-12-03T10:15:30+01:00[Europe/Paris]是 Oracle 提供的捆綁標准 DateTime 格式之一鏈接

現有格式化程序的參考示例:

String date1 = "2022-06-19T01:26:05.000+00:00"; 
// internally using DateTimeFormatter.ISO_OFFSET_DATE_TIME
System.out.println(OffsetDateTime.parse(date1));

//internally using DateTimeFormatter.ISO_ZONED_DATE_TIME
System.out.println(ZonedDateTime.parse(date1));

String date2 = "2022-06-19T01:26:05"; 
//internally using DateTimeFormatter.ISO_LOCAL_DATE_TIME)
System.out.println(LocalDateTime.parse(date2)); 

String date3 = "2022-06-19T01:26:05.00Z"; 
//internally using DateTimeFormatter.ISO_INSTANT
System.out.println(Instant.parse(date3));

輸出:

2022-06-19T01:26:05Z
2022-06-19T01:26:05Z
2022-06-19T01:26:05
2022-06-19T01:26:05Z

暫無
暫無

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

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