Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")给出时区为IST

Pra*_*rde 130 java timezone date date-format simpledateformat

我有SimpleDateFormat构造函数

SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
Run Code Online (Sandbox Code Playgroud)

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

我读过这里Z表示GMT/UTC时区.但是当我在控制台上打印这个日期时,它会为返回的日期打印IST timezne.

现在我的问题是我的输出是对还是错?

Pet*_*rey 221

您还没有将时区设置为仅添加Z到日期/时间的末尾,因此它看起来像GMT日期/时间,但这不会更改值.

将时区设置为GMT,这将是正确的.

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

  • @binarygiant你必须问那些发送它的人.它可能是发件人的当地时间. (3认同)
  • 如果你有一个日期,比如2012-12-06T06:00:00没有Z,那是否代表GMT? (2认同)
  • 时区可以设置为"UTC" (2认同)
  • 不要在多个库中为不同的库设置时区并避免与您的计算机/笔记本电脑时区冲突,而是应始终通过设置user.timezone系统属性来设置JVM的默认时区:java -Duser.timezone = GMT ... (2认同)

Sub*_*Sao 84

'T''Z'在这里被视为常数.你需要在Z没有引号的情况下通过.此外,您需要在输入字符串中指定时区.

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

  • -07:00小时而不是-0700,它将如下:yyyy-MM-dd'T'HH:mm:ss.SSSXXX (9认同)

AZ_*_*AZ_ 43

从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
Run Code Online (Sandbox Code Playgroud)

如果你没有设置TimeZone.getTimeZone("GMT")那么它将输出Sun Sep 29 18:46:19 CST 2013

从Java Date Object到ISO 8601 String

要将Date对象转换为ISO 8601 Standard(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
Run Code Online (Sandbox Code Playgroud)

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

  • 它给了我 java.text.ParseException: Unparseable date: "2018-05-01T18:30:00.000Z" @AZ_ (2认同)

MyT*_*tle 36

如果你想处理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"));

  • 如果您的日期以符合 RFC822 的方式指定时区(例如“-0500”),则效果很好。但对于诸如“2013-07-15T10:22:17-05:00”(也有效的 ISO8601 TZ)之类的日期,这种情况会中断。在这种情况下,您需要使用“yyyy-MM-dd'T'HH:mm:ssXXX”。 (2认同)

Bas*_*que 16

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. 
Run Code Online (Sandbox Code Playgroud)

ISO 8601

您的字符串格式符合ISO 8601标准.该标准定义了用于将各种日期时间值表示为文本的合理格式.

java.time

旧的java.util.Date/ .Calendarjava.text.SimpleDateFormat类已被Java 8及更高版本中内置的java.time框架所取代.请参阅教程.避免使用旧类,因为它们已被证明设计糟糕,令人困惑且麻烦.

旧类中的部分糟糕设计已经咬了你,toString当生成实际上以UTC(GMT)为单位的日期时间值的文本表示时,该方法应用JVM的当前默认时区; 善意但令人困惑.

在解析/生成日期时间值的文本表示时,java.time类默认使用ISO 8601格式.因此无需指定解析模式.

An InstantUTC时间轴上的一个时刻.

Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );
Run Code Online (Sandbox Code Playgroud)

您可以根据需要应用时区来生成ZonedDateTime对象.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
Run Code Online (Sandbox Code Playgroud)


Thi*_*man 16

如果你没有选择继续使用java8,请更好地使用'yyyy-MM-dd'T'HH:mm:ssX XX ',因为这会再次被正确解析(而只有一个X可能不是这种情况). ..取决于你的解析功能)

X生成:+01

XXX生成:+01:00

  • 这真的很有帮助。我使用的日期格式为 2021-04-25T11:12:45+00:00,这个 XXX 有帮助:) (2认同)

Arv*_*ash 10

'Z'不等于Z

'Z'只是一个字符文字,而Z是零时区偏移的时区指示符。它代表祖鲁语并指定Etc/UTC时区(具有+00:00小时的时区偏移量)。

因此,不要使用'Z'in 模式进行解析/格式化。

java.time现代日期时间API

现代日期时间 API 基于ISO 8601DateTimeFormatter ,只要日期时间字符串符合 ISO 8601 标准,就不需要显式使用对象。日期时间字符串,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2013-09-29T18:46:19Z
2013-09-29T18:46:19Z
2013-09-29T18:46:19Z
Run Code Online (Sandbox Code Playgroud)

ONLINE DEMO

An表示UTCInstant时间线上的瞬时点。输出中的 是零时区偏移的时区指示符。它代表祖鲁语并指定时区(具有小时的时区偏移量)。ZEtc/UTC+00:00

注意#1:如果您需要找出Instant特定时区代表的日期和时间,您可以使用Instant#atZone例如以下代码将打印印度的日期和时间Instant

ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用以下方法将对象ZonedDateTime从一个时区转换为另一个时区:以下代码将转换为表示印度日期和时间的对象:ZonedDateTime#withZoneSameInstantzdtZonedDateTime

ZonedDateTime zdtIndia = zdt.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
Run Code Online (Sandbox Code Playgroud)

Note#2:无论出于何种原因,如果您需要将此 对象 转换Instant为 对象java.util.Date,您可以按如下方式进行操作:

Date date = Date.from(instant);
Run Code Online (Sandbox Code Playgroud)

OffsetDateTime您甚至可以将和的对象转换ZonedDateTime为 的对象java.util.Date,如下所示:

Date date = Date.from(odt.toInstant());
Run Code Online (Sandbox Code Playgroud)

&

Date date = Date.from(zdt.toInstant());
Run Code Online (Sandbox Code Playgroud)

Trail: Date Time了解有关现代日期时间 API *的更多信息。

为什么你的java.util.Date对象打印印度日期和时间?

对象仅表示自称为“纪元”的标准基准时间(即 1970 年 1 月 1 日 00:00:00 GMT(或 UTC))以来的毫秒java.util.Date数。由于它不保存任何时区信息,因此它的函数应用 JVM 的时区来返回从该毫秒值派生的格式。要以不同的格式和时区获取对象的表示,您需要使用所需的格式和适用的时区,例如toStringStringEEE MMM dd HH:mm:ss zzz yyyyStringjava.util.DateSimpleDateFormat

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);
Run Code Online (Sandbox Code Playgroud)

演示:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出(我的时区是欧洲/伦敦):

Sun Sep 29 19:46:19 BST 2013
2013-09-29T18:46:19Z
2013-09-30T00:16:19+05:30
Run Code Online (Sandbox Code Playgroud)

ONLINE DEMO


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大多数java.time功能向后移植到 Java 6 和 7。如果您正在处理 Android 项目和 Android API level 仍然不符合 Java-8,请检查通过脱糖可用的 Java 8+ API以及如何在 Android 项目中使用 ThreeTenABP


nir*_*raj 5

对于 Java 8: 您可以使用 inbuiltjava.time.format.DateTimeFormatter来减少出现拼写错误的机会,例如

DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
Run Code Online (Sandbox Code Playgroud)

ISO_ZONED_DATE_TIME 表示是 Oracle链接2011-12-03T10:15:30+01:00[Europe/Paris]提供的捆绑标准日期时间格式之一