我有SimpleDateFormat构造函数为
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
我正在解析字符串“2013-09-29T18:46:19Z”。
我读到这里Z表示GMT/UTC时区。但是当我在控制台打印这个日期时,它为返回的日期打印IST时区。
现在我的问题是我的输出是对的还是错的?
我有SimpleDateFormat构造函数为
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
我正在解析字符串“2013-09-29T18:46:19Z”。
我读到这里Z表示GMT/UTC时区。但是当我在控制台打印这个日期时,它为返回的日期打印IST时区。
现在我的问题是我的输出是对的还是错的?
“T”和“Z”在这里被认为是常数。你需要传递不带引号的Z。此外,您需要在输入字符串中指定时区。
例如:2013-09-29T18:46:19-0700 格式为"yyyy-MM-dd 'HH:mm:ssZ"
你没有设置时区,只是在日期/时间的末尾添加了一个Z,所以它看起来像一个GMT日期/时间,但这不会改变值。
将时区设置为GMT,将是正确的。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
从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字符串
将Dateobject转换为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
另外请注意,没有' ' at Z yyyy-MM-dd' t ' hh:mm:ssZ打印2015-01-22 t03 . 41:02+0000
如果你想处理日期的“标准”JSON表示,那么最好使用这个模式:"yyyy-MM-dd' t ' hh:mm:ssX"。
注意结尾的X。它将处理ISO 8601标准的时区,而ISO 8601正是在Javascript new Date().toJSON()中产生这条语句的原因。
与其他答案相比,它有一些好处:
您不需要要求您的客户端以GMT发送日期 你不需要使用这个显式地转换你的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/。Calendar和java.text. simpledateformat类已被java.text. simpledateformat类所取代。在Java 8及以后版本中内置了时间框架。看教程。避免使用旧的类,因为它们已被证明是设计糟糕、令人困惑和麻烦的。
旧类中的部分糟糕设计让您感到困扰,其中toString方法在生成日期-时间值的文本表示时应用JVM的当前默认时区,而该日期-时间值实际上是UTC (GMT);善意但令人困惑。
java。时间类在解析/生成日期-时间值的文本表示时默认使用ISO 8601格式。因此不需要指定解析模式。
一个瞬间是UTC时间轴上的一个时刻。
Instant instant = Instant.parse( "2013-09-29T18:46:19Z" );
您可以根据需要应用时区来生成一个zoneeddatetime对象。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( zoneId );
如果你没有选择去java8更好的使用 'yyyy-MM-dd' t ' hh:mm:ssXXX',因为这将再次被正确解析(而只有一个X可能不是这种情况……取决于你的解析函数)
X生成:+01
XXX生成:+01:00
对于Java 8: 你可以使用内置的java.time.format.DateTimeFormatter来减少任何输入错误的机会, 就像
DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
iso_zone_date_time代表2011-12-03T10:15:30+01:00[欧洲/巴黎],是Oracle link提供的捆绑标准DateTime格式之一
“Z”和“Z”不一样
'Z'只是一个字符文字,而Z是零时区偏移的时区指示符。它代表Zulu,并指定Etc/UTC时区(时区偏移量为+00:00小时)。
因此,不要在模式中使用'Z'进行解析/格式化。
java。time,现代的Date-Time API
现代Date-Time API基于ISO 8601,只要Date-Time字符串符合ISO 8601标准,就不需要显式使用DateTimeFormatter对象。Date-Time字符串,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
在线演示
一个瞬间表示UTC时间轴上的一个瞬时点。输出中的Z是零时区偏移的时区指示器。它代表Zulu,并指定Etc/UTC时区(时区偏移量为+00:00小时)。
注意#1:如果你需要找出一个即时在特定时区代表的日期和时间,你可以使用Instant#atZone,例如下面的代码将打印这个即时在印度的日期和时间:
ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
你甚至可以使用ZonedDateTime#withZoneSameInstant将ZonedDateTime对象从一个时区转换到另一个时区,例如下面的代码将zdt转换为代表印度日期和时间的ZonedDateTime对象:
ZonedDateTime zdtIndia = zdt.withZoneSameInstant(ZoneId.of("Asia/Kolkata"));
System.out.println(zdtIndia);
注意#2:由于任何原因,如果您需要将Instant的对象转换为java.util的对象。日期,你可以这样做:
Date date = Date.from(instant);
您甚至可以将OffsetDateTime和ZonedDateTime对象转换为java.util的对象。日期,如下:
Date date = Date.from(odt.toInstant());
&
Date date = Date.from(zdt.toInstant());
了解更多关于现代日期时间API*从Trail: Date Time。
为什么你的java.util.Date对象打印印度日期和时间?
A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
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。Java 6和7的时间功能。如果你正在为一个Android项目工作,你的Android API级别仍然不兼容Java-8,检查Java 8+ API通过desugaring和如何使用ThreeTenABP在Android项目。
现有格式化程序的参考示例:
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