如何将UTC日期/时间(字符串)解析为更具可读性的内容?

时间:2022-01-25 02:15:58

I have a String of a date and time like this: 2011-04-15T20:08:18Z. I don't know much about date/time formats, but I think, and correct me if I'm wrong, that's its UTC format.

我有一个日期和时间的字符串:2011-04-15T20:08:18Z。我不太了解日期/时间格式,但我认为,如果我错了,请纠正我,这是它的UTC格式。

My question: what's the easiest way to parse this to a more normal format, in Java?

我的问题:在Java中,将这种解析为更正常的格式的最简单方法是什么?

9 个解决方案

#1


27  

What you have is an ISO-8601 date format which means you can just use SimpleDateFormat

你拥有的是ISO-8601日期格式,这意味着你可以使用SimpleDateFormat

DateFormat m_ISO8601Local = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

And then you can just use SimpleDateFormat.parse(). Also, here is a blog post with some examples that might help.

然后你可以使用SimpleDateFormat.parse()。此外,这是一篇博客文章,其中包含一些可能有用的示例。

Update:

Read the comments below before using this solution.

使用此解决方案之前,请阅读以下注释。

#2


31  

Use JodaTime

I kept getting parsing errors using the other solutions with the Z at the end of the format.

我一直在使用格式末尾的Z的其他解决方案来解析错误。

Instead, I opted to leverage JodaTime's excellent parsing functionality and was able to do the following very easily:

相反,我选择利用JodaTime优秀的解析功能,并且能够非常轻松地执行以下操作:

String timestamp = "2011-04-15T20:08:18Z";

DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

This correctly recognizes the UTC timezone and allows you to then use JodaTime's extensive manipulation methods to get what you want out of it.

这正确识别UTC时区,然后允许您使用JodaTime的大量操作方法来获取您想要的内容。

Hope this helps others.

希望这有助于其他人。

JP

#3


24  

tl;dr

String output = 
    Instant.parse ( "2011-04-15T20:08:18Z" )
           .atZone ( ZoneId.of ( "America/Montreal" ) )
           .format ( 
               DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL )
                                .withLocale ( Locale.CANADA_FRENCH ) 
           )
;

vendredi 15 avril 2011 16 h 08 EDT

vendredi 15 avril 2011 16 h 08 EDT

Details

The answer by Josh Pinter is correct, but could be even simpler.

Josh Pinter的答案是正确的,但可能更简单。

java.time

In Java 8 and later, the bundled java.util.Date/Calendar classes are supplanted by the java.time framework defined by JSR 310. Those classes are inspired by Joda-Time but are entirely re-architected.

在Java 8及更高版本中,捆绑的java.util.Date/Calendar类被JSR 310定义的java.time框架取代。这些类的灵感来自Joda-Time,但完全重新构建。

The java.time framework is the official successor to Joda-Time. The creators of Joda-Time have advised we should migrate to java.time as soon as is convenient. Joda-Time continues to be updated and tweaked, but further innovation will be done only in java.time and its extensions in the ThreeTen-Extra project.

java.time框架是Joda-Time的官方继承者。 Joda-Time的创建者建议我们应该尽快迁移到java.time。 Joda-Time不断更新和调整,但进一步的创新只能在java.time及其在ThreeTen-Extra项目中的扩展中完成。

The bulk of java.time functionality has been back-ported to Java 6 & 7 in the ThreeTen-Backport project, and further adapted to Android in ThreeTenABP project.

大部分java.time功能已经在ThreeTen-Backport项目中反向移植到Java 6和7,并在ThreeTenABP项目中进一步适应Android。

The equivalent for the Joda-Time code above is quite similar. Concepts are similar. And like Joda-Time, the java.time classes by default use ISO 8601 formats when parsing/generating textual representations of date-time values.

上面的Joda-Time代码的等价物非常相似。概念类似。和Joda-Time一样,java.time类在解析/生成日期时间值的文本表示时默认使用ISO 8601格式。

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds (versus milliseconds used by Joda-Time & java.util.Date).

Instant是UTC时间轴上的一个时刻,分辨率为纳秒(相对于Joda-Time和java.util.Date使用的毫秒数)。

Instant instant = Instant.parse( "2011-04-15T20:08:18Z" );

Apply a time zone (ZoneId) to get a ZonedDateTime.

应用时区(ZoneId)以获取ZonedDateTime。

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Adjust into yet another time zone.

调整到另一个时区。

ZoneId zoneId_NewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt.withZoneSameInstant( zoneId_NewYork );

To create strings in other formats beyond those of the toString methods, use the java.time.format classes. You can specify your own formatting pattern or let java.time localize automatically. Specify a Locale for (a) the human language used in translation of name of month/day-of-week, and (b) cultural norms for period-versus-comma, order of the parts, and such.

要创建超出toString方法的其他格式的字符串,请使用java.time.format类。您可以指定自己的格式设置模式,也可以让java.time自动进行本地化。为(a)用于翻译月份/星期几的人类语言和(b)时期与逗号的文化规范,部分顺序等指定语言环境。

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( Locale.US );
String output = zdt_NewYork.format( formatter );

Friday, April 15, 2011 4:08:18 PM EDT

美国东部时间2011年4月15日星期五下午4:08:18


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,如java.util.Date,Calendar和SimpleDateFormat。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql。*类。

Where to obtain the java.time classes?

从哪里获取java.time类?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。

    • Java 9 adds some minor features and fixes.
    • Java 9增加了一些小功能和修复。

  • Java SE 8,Java SE 9,Java SE 10和更高版本内置。带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。

  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Java SE 6和Java SE 7许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • 更高版本的Android捆绑java.time类的实现。

    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
    • 对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....

  • Android更新版本的Android捆绑java.time类的实现。对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,如Interval,YearWeek,YearQuarter等。


Joda-Time

UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact for history.

更新:Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。此部分保留完整的历史记录。

Pass String To Constructor

Joda-Time can take that string directly. Simply pass to a constructor on the DateTime class.

Joda-Time可以直接使用该字符串。只需传递给DateTime类的构造函数。

Joda-Time understands the standard ISO 8601 format of date-times, and uses that format as its default.

Joda-Time了解日期时间的标准ISO 8601格式,并将该格式用作默认格式。

Example Code

Here is example code in Joda-Time 2.3 running in Java 7 on a Mac.

以下是在Mac上用Java 7运行的Joda-Time 2.3中的示例代码。

I show how to pass the string to a DateTime constructor, in two ways: With and without a time zone. Specifying a time zone solves many problems people encounter in doing date-time work. If left unspecified, you get the default time zone which can bring surprises when placed into production.

我将以两种方式展示如何将字符串传递给DateTime构造函数:有和没有时区。指定时区解决了人们在进行日期工作时遇到的许多问题。如果未指定,您将获得默认时区,这可能会在投入生产时带来意外。

I also show how specify no time zone offset (UTC/GMT) using the built-in constant DateTimeZone.UTC. That's what the Z on the end, short for Zulu time, means: No time zone offset (00:00).

我还展示了如何使用内置常量DateTimeZone.UTC指定无时区偏移量(UTC / GMT)。这就是最后的Z,祖鲁时间的缩写,意思是:没有时区偏移(00:00)。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Default time zone.
DateTime dateTime = new DateTime( "2011-04-15T20:08:18Z" );

// Specified time zone.
DateTime dateTimeInKolkata = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeInNewYork = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "America/New_York" ) );

// In UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTimeInKolkata.toDateTime( DateTimeZone.UTC );

// Output in localized format.
DateTimeFormatter formatter = DateTimeFormat.shortDateTime().withLocale( Locale.US );
String output_US = formatter.print( dateTimeInNewYork );

Dump to console…

转储到控制台......

System.out.println("dateTime: " + dateTime );
System.out.println("dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println("dateTimeInNewYork: " + dateTimeInNewYork );
System.out.println("dateTimeUtc: " + dateTimeUtc );
System.out.println("dateTime in US format: " + output_US );

When run…

dateTime: 2011-04-15T13:08:18.000-07:00
dateTimeInKolkata: 2011-04-16T01:38:18.000+05:30
dateTimeInNewYork: 2011-04-15T16:08:18.000-04:00
dateTimeUtc: 2011-04-15T20:08:18.000Z
dateTime in US format: 4/15/11 4:08 PM

#4


7  

The Java 7 version of SimpleDateFormat supports ISO-8601 time zones using the uppercase letter X.

SimpleDateFormat的Java 7版本使用大写字母X支持ISO-8601时区。

String string = "2011-04-15T20:08:18Z";
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = iso8601.parse(string);

If you're stuck with Java 6 or earlier, the answer recommending JodaTime is a safe bet.

如果你坚持使用Java 6或更早版本,推荐JodaTime的答案是一个安全的选择。

#5


4  

Already has lot of answer but just wanted to update with java 8 in case any one faced issues while parsing string date.

已经有很多答案,但只是想用java 8更新以防任何人在解析字符串日期时遇到问题。

Generally we face two problems with dates

一般来说,我们面临两个日期问题

  1. Parsing String to Date
  2. 解析字符串到日期

  3. Display Date in desired string format
  4. 以所需的字符串格式显示日期

DateTimeFormatter class in Java 8 can be used for both of these purpose. Below methods try to provide solution to these issues.

Java 8中的DateTimeFormatter类可用于这两个目的。以下方法尝试为这些问题提供解决方案。

Method 1: Convert your UTC string to Instant. Using Instant you can create Date for any time-zone by providing time-zone string and use DateTimeFormatter to format date for display as you wish.

方法1:将您的UTC字符串转换为Instant。使用Instant,您可以通过提供时区字符串为任何时区创建日期,并使用DateTimeFormatter格式化日期以供显示。

String dateString = "2016-07-13T18:08:50.118Z";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
ZoneId zoneId = ZoneId.of(tz);

Instant instant = Instant.parse(dateString);

ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);

System.out.println(dateTimeInTz.format(dtf));

Method 2:

Use DateTimeFormatter built in constants e.g ISO_INSTANT to parse string to LocalDate. ISO_INSTANT can parse dates of pattern

使用内置常量的DateTimeFormatter(例如ISO_INSTANT)将字符串解析为LocalDate。 ISO_INSTANT可以解析模式的日期

yyyy-MM-dd'T'HH:mm:ssX e.g '2011-12-03T10:15:30Z'

yyyy-MM-dd'T'HH:mm:ssX例如'2011-12-03T10:15:30Z'

LocalDate parsedDate
  = LocalDate.parse(dateString, DateTimeFormatter.ISO_INSTANT);

DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(parsedDate.format(displayFormatter));

Method 3:

If your date string has much precision of time e.g it captures fraction of seconds as well as in this case 2016-07-13T18:08:50.118Z then method 1 will work but method 2 will not work. If you try to parse it will throw DateTimeException Since ISO_INSTANT formatter will not be able to parse fraction of seconds as you can see from its pattern. In this case you will have to create a custom DateTimeFormatter by providing date pattern as below.

如果您的日期字符串具有很高的时间精度,例如它捕获几分之一秒以及在这种情况下2016-07-13T18:08:50.118Z那么方法1将起作用但方法2将不起作用。如果你试图解析它将抛出DateTimeException,因为ISO_INSTANT格式化程序将无法解析从其模式中看到的秒数。在这种情况下,您必须通过提供如下日期模式来创建自定义DateTimeFormatter。

LocalDate localDate 
= LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));

Taken from a blog link written by me.

取自我写的博客链接。

#6


1  

You have to give the following format:

您必须提供以下格式:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parse = simpleDateFormat.parse( "2011-04-15T20:08:18Z" );

#7


1  

I had a parse error in Andrew White solution. Adding the single quote around the Z solved the issue

我在Andrew White解决方案中遇到了解析错误。在Z周围添加单引号解决了这个问题

DateFormat m_ISO8601Local = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss'Z'");

#8


0  

For all the older versions of JDK (6 down) it may be useful.

对于所有旧版本的JDK(6 down),它可能很有用。

Getting rid of trailing 'Z' and replacing it literally with 'UTC' timezone display name - then parsing the whole string using proper simple date formatter.

摆脱尾随'Z'并用'UTC'时区显示名称替换它 - 然后使用适当的简单日期格式化器解析整个字符串。

String timeZuluVal = "2011-04-15T20:08:18Z";
timeZuluVal = timeZuluVal.substring( 0, timeZuluVal.length() - 2 ); // strip 'Z';
timeZuluVal += " " + TimeZone.getTimeZone( "UTC" ).getDisplayName();
DateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss zzzz" );
Date dateVal = simpleDateFormat.parse( timeZuluVal );

#9


0  

the pattern in @khmarbaise answer worked for me, here's the utility method I extracted (note that the Z is omitted from the pattern string):

@khmarbaise中的模式答案对我有用,这里是我提取的实用方法(注意模式字符串中省略了Z):

/**
 * Converts an ISO-8601 formatted UTC timestamp.
 *
 * @return The parsed {@link Date}, or null.
 */
@Nullable
public static Date fromIsoUtcString(String isoUtcString) {
    DateFormat isoUtcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
    isoUtcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    try {
        return isoUtcFormat.parse(isoUtcString);
    } catch (ParseException e) {
        e.printStackTrace();
        return null;
    }
}

#1


27  

What you have is an ISO-8601 date format which means you can just use SimpleDateFormat

你拥有的是ISO-8601日期格式,这意味着你可以使用SimpleDateFormat

DateFormat m_ISO8601Local = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

And then you can just use SimpleDateFormat.parse(). Also, here is a blog post with some examples that might help.

然后你可以使用SimpleDateFormat.parse()。此外,这是一篇博客文章,其中包含一些可能有用的示例。

Update:

Read the comments below before using this solution.

使用此解决方案之前,请阅读以下注释。

#2


31  

Use JodaTime

I kept getting parsing errors using the other solutions with the Z at the end of the format.

我一直在使用格式末尾的Z的其他解决方案来解析错误。

Instead, I opted to leverage JodaTime's excellent parsing functionality and was able to do the following very easily:

相反,我选择利用JodaTime优秀的解析功能,并且能够非常轻松地执行以下操作:

String timestamp = "2011-04-15T20:08:18Z";

DateTime dateTime = ISODateTimeFormat.dateTimeParser().parseDateTime(timestamp);

This correctly recognizes the UTC timezone and allows you to then use JodaTime's extensive manipulation methods to get what you want out of it.

这正确识别UTC时区,然后允许您使用JodaTime的大量操作方法来获取您想要的内容。

Hope this helps others.

希望这有助于其他人。

JP

#3


24  

tl;dr

String output = 
    Instant.parse ( "2011-04-15T20:08:18Z" )
           .atZone ( ZoneId.of ( "America/Montreal" ) )
           .format ( 
               DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL )
                                .withLocale ( Locale.CANADA_FRENCH ) 
           )
;

vendredi 15 avril 2011 16 h 08 EDT

vendredi 15 avril 2011 16 h 08 EDT

Details

The answer by Josh Pinter is correct, but could be even simpler.

Josh Pinter的答案是正确的,但可能更简单。

java.time

In Java 8 and later, the bundled java.util.Date/Calendar classes are supplanted by the java.time framework defined by JSR 310. Those classes are inspired by Joda-Time but are entirely re-architected.

在Java 8及更高版本中,捆绑的java.util.Date/Calendar类被JSR 310定义的java.time框架取代。这些类的灵感来自Joda-Time,但完全重新构建。

The java.time framework is the official successor to Joda-Time. The creators of Joda-Time have advised we should migrate to java.time as soon as is convenient. Joda-Time continues to be updated and tweaked, but further innovation will be done only in java.time and its extensions in the ThreeTen-Extra project.

java.time框架是Joda-Time的官方继承者。 Joda-Time的创建者建议我们应该尽快迁移到java.time。 Joda-Time不断更新和调整,但进一步的创新只能在java.time及其在ThreeTen-Extra项目中的扩展中完成。

The bulk of java.time functionality has been back-ported to Java 6 & 7 in the ThreeTen-Backport project, and further adapted to Android in ThreeTenABP project.

大部分java.time功能已经在ThreeTen-Backport项目中反向移植到Java 6和7,并在ThreeTenABP项目中进一步适应Android。

The equivalent for the Joda-Time code above is quite similar. Concepts are similar. And like Joda-Time, the java.time classes by default use ISO 8601 formats when parsing/generating textual representations of date-time values.

上面的Joda-Time代码的等价物非常相似。概念类似。和Joda-Time一样,java.time类在解析/生成日期时间值的文本表示时默认使用ISO 8601格式。

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds (versus milliseconds used by Joda-Time & java.util.Date).

Instant是UTC时间轴上的一个时刻,分辨率为纳秒(相对于Joda-Time和java.util.Date使用的毫秒数)。

Instant instant = Instant.parse( "2011-04-15T20:08:18Z" );

Apply a time zone (ZoneId) to get a ZonedDateTime.

应用时区(ZoneId)以获取ZonedDateTime。

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Adjust into yet another time zone.

调整到另一个时区。

ZoneId zoneId_NewYork = ZoneId.of( "America/New_York" );
ZonedDateTime zdt_NewYork = zdt.withZoneSameInstant( zoneId_NewYork );

To create strings in other formats beyond those of the toString methods, use the java.time.format classes. You can specify your own formatting pattern or let java.time localize automatically. Specify a Locale for (a) the human language used in translation of name of month/day-of-week, and (b) cultural norms for period-versus-comma, order of the parts, and such.

要创建超出toString方法的其他格式的字符串,请使用java.time.format类。您可以指定自己的格式设置模式,也可以让java.time自动进行本地化。为(a)用于翻译月份/星期几的人类语言和(b)时期与逗号的文化规范,部分顺序等指定语言环境。

DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
formatter = formatter.withLocale( Locale.US );
String output = zdt_NewYork.format( formatter );

Friday, April 15, 2011 4:08:18 PM EDT

美国东部时间2011年4月15日星期五下午4:08:18


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗留日期时间类,如java.util.Date,Calendar和SimpleDateFormat。

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

现在处于维护模式的Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。不需要字符串,不需要java.sql。*类。

Where to obtain the java.time classes?

从哪里获取java.time类?

  • Java SE 8, Java SE 9, Java SE 10, and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • 带有捆绑实现的标准Java API的一部分。

    • Java 9 adds some minor features and fixes.
    • Java 9增加了一些小功能和修复。

  • Java SE 8,Java SE 9,Java SE 10和更高版本内置。带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。

  • Java SE 6 and Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • 许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Java SE 6和Java SE 7许多java.time功能都被反向移植到ThreeTen-Backport中的Java 6和7。

  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • 更高版本的Android捆绑java.time类的实现。

    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
    • 对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....

  • Android更新版本的Android捆绑java.time类的实现。对于早期的Android(<26),ThreeTenABP项目采用ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP ....

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。您可以在这里找到一些有用的课程,如Interval,YearWeek,YearQuarter等。


Joda-Time

UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This section left intact for history.

更新:Joda-Time项目现在处于维护模式,团队建议迁移到java.time类。此部分保留完整的历史记录。

Pass String To Constructor

Joda-Time can take that string directly. Simply pass to a constructor on the DateTime class.

Joda-Time可以直接使用该字符串。只需传递给DateTime类的构造函数。

Joda-Time understands the standard ISO 8601 format of date-times, and uses that format as its default.

Joda-Time了解日期时间的标准ISO 8601格式,并将该格式用作默认格式。

Example Code

Here is example code in Joda-Time 2.3 running in Java 7 on a Mac.

以下是在Mac上用Java 7运行的Joda-Time 2.3中的示例代码。

I show how to pass the string to a DateTime constructor, in two ways: With and without a time zone. Specifying a time zone solves many problems people encounter in doing date-time work. If left unspecified, you get the default time zone which can bring surprises when placed into production.

我将以两种方式展示如何将字符串传递给DateTime构造函数:有和没有时区。指定时区解决了人们在进行日期工作时遇到的许多问题。如果未指定,您将获得默认时区,这可能会在投入生产时带来意外。

I also show how specify no time zone offset (UTC/GMT) using the built-in constant DateTimeZone.UTC. That's what the Z on the end, short for Zulu time, means: No time zone offset (00:00).

我还展示了如何使用内置常量DateTimeZone.UTC指定无时区偏移量(UTC / GMT)。这就是最后的Z,祖鲁时间的缩写,意思是:没有时区偏移(00:00)。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Default time zone.
DateTime dateTime = new DateTime( "2011-04-15T20:08:18Z" );

// Specified time zone.
DateTime dateTimeInKolkata = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "Asia/Kolkata" ) );
DateTime dateTimeInNewYork = new DateTime( "2011-04-15T20:08:18Z", DateTimeZone.forID( "America/New_York" ) );

// In UTC/GMT (no time zone offset).
DateTime dateTimeUtc = dateTimeInKolkata.toDateTime( DateTimeZone.UTC );

// Output in localized format.
DateTimeFormatter formatter = DateTimeFormat.shortDateTime().withLocale( Locale.US );
String output_US = formatter.print( dateTimeInNewYork );

Dump to console…

转储到控制台......

System.out.println("dateTime: " + dateTime );
System.out.println("dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println("dateTimeInNewYork: " + dateTimeInNewYork );
System.out.println("dateTimeUtc: " + dateTimeUtc );
System.out.println("dateTime in US format: " + output_US );

When run…

dateTime: 2011-04-15T13:08:18.000-07:00
dateTimeInKolkata: 2011-04-16T01:38:18.000+05:30
dateTimeInNewYork: 2011-04-15T16:08:18.000-04:00
dateTimeUtc: 2011-04-15T20:08:18.000Z
dateTime in US format: 4/15/11 4:08 PM

#4


7  

The Java 7 version of SimpleDateFormat supports ISO-8601 time zones using the uppercase letter X.

SimpleDateFormat的Java 7版本使用大写字母X支持ISO-8601时区。

String string = "2011-04-15T20:08:18Z";
DateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
Date date = iso8601.parse(string);

If you're stuck with Java 6 or earlier, the answer recommending JodaTime is a safe bet.

如果你坚持使用Java 6或更早版本,推荐JodaTime的答案是一个安全的选择。

#5


4  

Already has lot of answer but just wanted to update with java 8 in case any one faced issues while parsing string date.

已经有很多答案,但只是想用java 8更新以防任何人在解析字符串日期时遇到问题。

Generally we face two problems with dates

一般来说,我们面临两个日期问题

  1. Parsing String to Date
  2. 解析字符串到日期

  3. Display Date in desired string format
  4. 以所需的字符串格式显示日期

DateTimeFormatter class in Java 8 can be used for both of these purpose. Below methods try to provide solution to these issues.

Java 8中的DateTimeFormatter类可用于这两个目的。以下方法尝试为这些问题提供解决方案。

Method 1: Convert your UTC string to Instant. Using Instant you can create Date for any time-zone by providing time-zone string and use DateTimeFormatter to format date for display as you wish.

方法1:将您的UTC字符串转换为Instant。使用Instant,您可以通过提供时区字符串为任何时区创建日期,并使用DateTimeFormatter格式化日期以供显示。

String dateString = "2016-07-13T18:08:50.118Z";
String tz = "America/Mexico_City";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMM d yyyy hh:mm a");
ZoneId zoneId = ZoneId.of(tz);

Instant instant = Instant.parse(dateString);

ZonedDateTime dateTimeInTz =ZonedDateTime.ofInstant(instant, zoneId);

System.out.println(dateTimeInTz.format(dtf));

Method 2:

Use DateTimeFormatter built in constants e.g ISO_INSTANT to parse string to LocalDate. ISO_INSTANT can parse dates of pattern

使用内置常量的DateTimeFormatter(例如ISO_INSTANT)将字符串解析为LocalDate。 ISO_INSTANT可以解析模式的日期

yyyy-MM-dd'T'HH:mm:ssX e.g '2011-12-03T10:15:30Z'

yyyy-MM-dd'T'HH:mm:ssX例如'2011-12-03T10:15:30Z'

LocalDate parsedDate
  = LocalDate.parse(dateString, DateTimeFormatter.ISO_INSTANT);

DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("yyyy MM dd");
System.out.println(parsedDate.format(displayFormatter));

Method 3:

If your date string has much precision of time e.g it captures fraction of seconds as well as in this case 2016-07-13T18:08:50.118Z then method 1 will work but method 2 will not work. If you try to parse it will throw DateTimeException Since ISO_INSTANT formatter will not be able to parse fraction of seconds as you can see from its pattern. In this case you will have to create a custom DateTimeFormatter by providing date pattern as below.

如果您的日期字符串具有很高的时间精度,例如它捕获几分之一秒以及在这种情况下2016-07-13T18:08:50.118Z那么方法1将起作用但方法2将不起作用。如果你试图解析它将抛出DateTimeException,因为ISO_INSTANT格式化程序将无法解析从其模式中看到的秒数。在这种情况下,您必须通过提供如下日期模式来创建自定义DateTimeFormatter。

LocalDate localDate 
= LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSX"));

Taken from a blog link written by me.

取自我写的博客链接。

#6


1  

You have to give the following format:

您必须提供以下格式:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date parse = simpleDateFormat.parse( "2011-04-15T20:08:18Z" );

#7


1  

I had a parse error in Andrew White solution. Adding the single quote around the Z solved the issue

我在Andrew White解决方案中遇到了解析错误。在Z周围添加单引号解决了这个问题

DateFormat m_ISO8601Local = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss'Z'");

#8


0  

For all the older versions of JDK (6 down) it may be useful.

对于所有旧版本的JDK(6 down),它可能很有用。

Getting rid of trailing 'Z' and replacing it literally with 'UTC' timezone display name - then parsing the whole string using proper simple date formatter.

摆脱尾随'Z'并用'UTC'时区显示名称替换它 - 然后使用适当的简单日期格式化器解析整个字符串。

String timeZuluVal = "2011-04-15T20:08:18Z";
timeZuluVal = timeZuluVal.substring( 0, timeZuluVal.length() - 2 ); // strip 'Z';
timeZuluVal += " " + TimeZone.getTimeZone( "UTC" ).getDisplayName();
DateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss zzzz" );
Date dateVal = simpleDateFormat.parse( timeZuluVal );

#9


0  

the pattern in @khmarbaise answer worked for me, here's the utility method I extracted (note that the Z is omitted from the pattern string):

@khmarbaise中的模式答案对我有用,这里是我提取的实用方法(注意模式字符串中省略了Z):

/**
 * Converts an ISO-8601 formatted UTC timestamp.
 *
 * @return The parsed {@link Date}, or null.
 */
@Nullable
public static Date fromIsoUtcString(String isoUtcString) {
    DateFormat isoUtcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
    isoUtcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    try {
        return isoUtcFormat.parse(isoUtcString);
    } catch (ParseException e) {
        e.printStackTrace();
        return null;
    }
}