简体   繁体   English

将符合 ISO 8601 的字符串转换为 java.util.Date

[英]Converting ISO 8601-compliant String to java.util.Date

I am trying to convert an ISO 8601 formatted String to a java.util.Date .我正在尝试将ISO 8601格式的 String 转换为java.util.Date

I found the pattern yyyy-MM-dd'T'HH:mm:ssZ to be ISO8601-compliant if used with a Locale (compare sample).如果与区域设置(比较示例)一起使用,我发现模式yyyy-MM-dd'T'HH:mm:ssZ符合 ISO8601 标准。

However, using the java.text.SimpleDateFormat , I cannot convert the correctly formatted String 2010-01-01T12:00:00+01:00 .但是,使用java.text.SimpleDateFormat ,我无法转换格式正确的 String 2010-01-01T12:00:00+01:00 I have to convert it first to 2010-01-01T12:00:00+0100 , without the colon.我必须先将其转换为2010-01-01T12:00:00+0100 ,不带冒号。

So, the current solution is所以,目前的解决方案是

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

which obviously isn't that nice.这显然不是那么好。 Am I missing something or is there a better solution?我错过了什么还是有更好的解决方案?


Answer回答

Thanks to JuanZe's comment, I found the Joda-Time magic, it is also described here .感谢 JuanZe 的评论,我找到了Joda-Time 的魔法, 这里也有描述

So, the solution is所以,解决方案是

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

Or more simply, use the default parser via the constructor:或者更简单地说,通过构造函数使用默认解析器:

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

To me, this is nice.对我来说,这很好。

Unfortunately, the time zone formats available to SimpleDateFormat (Java 6 and earlier) are not ISO 8601 compliant.不幸的是, SimpleDateFormat (Java 6 和更早版本)可用的时区格式不符合 ISO 8601 SimpleDateFormat understands time zone strings like "GMT+01:00" or "+0100", the latter according to RFC # 822 . SimpleDateFormat 理解时区字符串,如“GMT+01:00”或“+0100”,后者根据RFC # 822

Even if Java 7 added support for time zone descriptors according to ISO 8601, SimpleDateFormat is still not able to properly parse a complete date string, as it has no support for optional parts.即使 Java 7 根据 ISO 8601 添加了对时区描​​述符的支持,SimpleDateFormat 仍然无法正确解析完整的日期字符串,因为它不支持可选部分。

Reformatting your input string using regexp is certainly one possibility, but the replacement rules are not as simple as in your question:使用正则表达式重新格式化您的输入字符串当然是一种可能性,但替换规则并不像您的问题那么简单:

  • Some time zones are not full hours off UTC , so the string does not necessarily end with ":00".某些时区不是UTC的完整小时,因此字符串不一定以“:00”结尾。
  • ISO8601 allows only the number of hours to be included in the time zone, so "+01" is equivalent to "+01:00" ISO8601 只允许时区包含小时数,因此“+01”等价于“+01:00”
  • ISO8601 allows the usage of "Z" to indicate UTC instead of "+00:00". ISO8601 允许使用“Z”而不是“+00:00”来表示 UTC。

The easier solution is possibly to use the data type converter in JAXB, since JAXB must be able to parse ISO8601 date string according to the XML Schema specification.更简单的解决方案可能是使用 JAXB 中的数据类型转换器,因为 JAXB 必须能够根据 XML Schema 规范解析 ISO8601 日期字符串。 javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z") will give you a Calendar object and you can simply use getTime() on it, if you need a Date object. javax.xml.bind.DatatypeConverter.parseDateTime("2010-01-01T12:00:00Z")会给你一个Calendar对象,如果你需要一个Date对象,你可以简单地使用 getTime() 。

You could probably use Joda-Time as well, but I don't know why you should bother with that (Update 2022; maybe because the entire javax.xml.bind section is missing from Android's javax.xml package).您也可以使用Joda-Time ,但我不知道您为什么要为此烦恼(2022 年更新;可能是因为 Android 的javax.xml包中缺少整个javax.xml.bind部分)。

The way that is blessed by Java 7 documentation : Java 7 文档所祝福的方式:

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String string1 = "2001-07-04T12:08:56.235-0700";
Date result1 = df1.parse(string1);

DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
String string2 = "2001-07-04T12:08:56.235-07:00";
Date result2 = df2.parse(string2);

You can find more examples in section Examples at SimpleDateFormat javadoc .您可以在SimpleDateFormat javadoc示例部分中找到更多示例。

UPD 02/13/2020: There is a completely new way to do this in Java 8 UPD 2020 年 2 月 13 日: Java 8 中有一种全新的方法可以做到这一点

Okay, this question is already answered, but I'll drop my answer anyway.好的,这个问题已经回答了,但无论如何我都会放弃我的答案。 It might help someone.它可能会帮助某人。

I've been looking for a solution for Android (API 7).我一直在寻找适用于 Android (API 7) 的解决方案

  • Joda was out of the question - it is huge and suffers from slow initialization. Joda 是不可能的 - 它很大并且初始化缓慢。 It also seemed a major overkill for that particular purpose.对于该特定目的,这似乎也是一个重大的过度杀伤力。
  • Answers involving javax.xml won't work on Android API 7.涉及javax.xml的答案不适用于 Android API 7。

Ended up implementing this simple class.最终实现了这个简单的类。 It covers only the most common form of ISO 8601 strings, but this should be enough in some cases (when you're quite sure that the input will be in this format).仅涵盖最常见的 ISO 8601 字符串形式,但在某些情况下应该足够了(当您非常确定输入将采用这种格式时)。

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * Helper class for handling a most common subset of ISO 8601 strings
 * (in the following format: "2008-03-01T13:00:00+01:00"). It supports
 * parsing the "Z" timezone, but many other less-used features are
 * missing.
 */
public final class ISO8601 {
    /** Transform Calendar to ISO 8601 string. */
    public static String fromCalendar(final Calendar calendar) {
        Date date = calendar.getTime();
        String formatted = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
            .format(date);
        return formatted.substring(0, 22) + ":" + formatted.substring(22);
    }

    /** Get current date and time formatted as ISO 8601 string. */
    public static String now() {
        return fromCalendar(GregorianCalendar.getInstance());
    }

    /** Transform ISO 8601 string to Calendar. */
    public static Calendar toCalendar(final String iso8601string)
            throws ParseException {
        Calendar calendar = GregorianCalendar.getInstance();
        String s = iso8601string.replace("Z", "+00:00");
        try {
            s = s.substring(0, 22) + s.substring(23);  // to get rid of the ":"
        } catch (IndexOutOfBoundsException e) {
            throw new ParseException("Invalid length", 0);
        }
        Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
        calendar.setTime(date);
        return calendar;
    }
}

Performance note: I instantiate new SimpleDateFormat every time as means to avoid a bug in Android 2.1.性能说明:我每次都实例化新的 SimpleDateFormat 以避免 Android 2.1 中的错误 If you're as astonished as I was, see this riddle .如果你和我一样惊讶,看看这个谜语 For other Java engines, you may cache the instance in a private static field (using ThreadLocal, to be thread safe).对于其他 Java 引擎,您可以将实例缓存在私有静态字段中(使用 ThreadLocal,以保证线程安全)。

java.time java.time

The java.time API (built into Java 8 and later), makes this a little easier. java.time API (内置于 Java 8 及更高版本)使这更容易一些。

If you know the input is in UTC , such as the Z (for Zulu) on the end, the Instant class can parse.如果您知道输入是UTC 格式,例如末尾的Z (代表 Zulu),则Instant类可以解析。

java.util.Date date = Date.from( Instant.parse( "2014-12-12T10:39:40Z" ));

If your input may be another offset-from-UTC values rather than UTC indicated by the Z (Zulu) on the end, use the OffsetDateTime class to parse.如果您的输入可能是另一个从 UTC 偏移的值,而不是最后由Z (Zulu) 指示的UTC ,请使用OffsetDateTime类进行解析。

OffsetDateTime odt = OffsetDateTime.parse( "2010-01-01T12:00:00+01:00" );

Then extract an Instant , and convert to a java.util.Date by calling from .然后提取Instant ,并通过调用from转换为java.util.Date

Instant instant = odt.toInstant();  // Instant is always in UTC.
java.util.Date date = java.util.Date.from( instant );

tl;dr tl;博士

OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" )

Using java.time使用 java.time

The new java.time package in Java 8 and later was inspired by Joda-Time. Java 8 及更高版本中新的java.time包的灵感来自 Joda-Time。

The OffsetDateTime class represents a moment on the timeline with an offset-from-UTC but not a time zone. OffsetDateTime类表示时间轴上具有与UTC 偏移但不是时区的时刻。

OffsetDateTime odt = OffsetDateTime.parse ( "2010-01-01T12:00:00+01:00" );

Calling toString generates a string in standard ISO 8601 format:调用toString生成标准 ISO 8601 格式的字符串:

2010-01-01T12:00+01:00 2010-01-01T12:00+01:00

To see the same value through the lens of UTC, extract an Instant or adjust the offset from +01:00 to 00:00 .要通过 UTC 的镜头查看相同的值,请提取Instant或将偏移量从+01:00调整为00:00

Instant instant = odt.toInstant();  

…or… …或者…

OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC );

Adjust into a time zone if desired.如果需要,调整到时区。 A time zone is a history of offset-from-UTC values for a region, with a set of rules for handling anomalies such as Daylight Saving Time (DST).时区是一个区域与UTC 值的偏移历史,具有一组用于处理异常的规则,例如夏令时 (DST)。 So apply a time zone rather than a mere offset whenever possible.因此,尽可能应用时区而不是单纯的偏移量。

ZonedDateTime zonedDateTimeMontréal = odt.atZoneSameInstant( ZoneId.of( "America/Montreal" ) );

For a date-only value, use LocalDate .对于仅日期值,请使用LocalDate

LocalDate ld = LocalDate.of( 2010 , Month.JANUARY , 1 ) ;

Or:或者:

LocalDate ld = LocalDate.parse( "2010-01-01" ) ;

About java.time关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于 Java 8 及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat .这些类取代了麻烦的日期时间类,例如java.util.DateCalendarSimpleDateFormat

To learn more, see the Oracle Tutorial .要了解更多信息,请参阅Oracle 教程 And search Stack Overflow for many examples and explanations.并在 Stack Overflow 上搜索许多示例和解释。 Specification is JSR 310 .规范是JSR 310

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes.现在处于维护模式Joda-Time项目建议迁移到java.time类。

You may exchange java.time objects directly with your database.您可以直接与您的数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later.使用符合JDBC 4.2或更高版本的JDBC 驱动程序 No need for strings, no need for java.sql.* classes.不需要字符串,不需要java.sql.*类。 Hibernate 5 & JPA 2.2 support java.time . Hibernate 5 & JPA 2.2 支持java.time

Where to obtain the java.time classes?从哪里获得 java.time 类?


The Jackson-databind library also has ISO8601DateFormat class that does that (actual implementation in ISO8601Utils . Jackson-databind 库还具有执行此操作的ISO8601DateFormat 类(在ISO8601Utils中的实际实现。

ISO8601DateFormat df = new ISO8601DateFormat();
Date d = df.parse("2010-07-28T22:25:51Z");

Starting from Java 8, there is a completely new officially supported way to do this:从 Java 8 开始,有一种全新的官方支持方式来执行此操作:

    String s = "2020-02-13T18:51:09.840Z";
    TemporalAccessor ta = DateTimeFormatter.ISO_INSTANT.parse(s);
    Instant i = Instant.from(ta);
    Date d = Date.from(i);

For Java version 7对于 Java 版本 7

You can follow Oracle documentation: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html您可以关注 Oracle 文档: http ://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

X - is used for ISO 8601 time zone X - 用于 ISO 8601 时区

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);

The DatatypeConverter solution doesn't work in all VMs. DatatypeConverter 解决方案不适用于所有 VM。 The following works for me:以下对我有用:

javax.xml.datatype.DatatypeFactory.newInstance().newXMLGregorianCalendar("2011-01-01Z").toGregorianCalendar().getTime()

I've found that joda does not work out of the box (specifically for the example I gave above with the timezone on a date, which should be valid)我发现 joda 不能开箱即用(特别是对于我上面给出的示例,其中包含日期的时区,这应该是有效的)

I think we should use我认为我们应该使用

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

for Date 2010-01-01T12:00:00Z对于日期2010-01-01T12:00:00Z

Another very simple way to parse ISO8601 timestamps is to use org.apache.commons.lang.time.DateUtils :解析 ISO8601 时间戳的另一种非常简单的方法是使用org.apache.commons.lang.time.DateUtils

import static org.junit.Assert.assertEquals;

import java.text.ParseException;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
import org.junit.Test;

public class ISO8601TimestampFormatTest {
  @Test
  public void parse() throws ParseException {
    Date date = DateUtils.parseDate("2010-01-01T12:00:00+01:00", new String[]{ "yyyy-MM-dd'T'HH:mm:ssZZ" });
    assertEquals("Fri Jan 01 12:00:00 CET 2010", date.toString());
  }
}

The workaround for Java 7+ is using SimpleDateFormat: Java 7+ 的解决方法是使用 SimpleDateFormat:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);

This code can parse ISO8601 format like:此代码可以解析 ISO8601 格式,如:

  • 2017-05-17T06:01:43.785Z
  • 2017-05-13T02:58:21.391+01:00

But on Java6, SimpleDateFormat doesn't understand X character and will throw但是在 Java6 上, SimpleDateFormat不理解X字符并且会抛出
IllegalArgumentException: Unknown pattern character 'X'
We need to normalize ISO8601 date to the format readable in Java 6 with SimpleDateFormat .我们需要使用SimpleDateFormat将 ISO8601 日期标准化为 Java 6 中可读的格式。

public static Date iso8601Format(String formattedDate) throws ParseException {
    try {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);
        return df.parse(formattedDate);
    } catch (IllegalArgumentException ex) {
        // error happen in Java 6: Unknown pattern character 'X'
        if (formattedDate.endsWith("Z")) formattedDate = formattedDate.replace("Z", "+0000");
        else formattedDate = formattedDate.replaceAll("([+-]\\d\\d):(\\d\\d)\\s*$", "$1$2");
        DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
        return df1.parse(formattedDate);
    }
}

Method above to replace [ Z with +0000 ] or [ +01:00 with +0100 ] when error occurs in Java 6 (you can detect Java version and replace try/catch with if statement).当 Java 6 中发生错误时,上述方法将 [ Z替换为+0000 ] 或 [ +01:00替换为+0100 ](您可以检测 Java 版本并将 try/catch 替换为 if 语句)。

After I searched a lot to convert ISO8601 to date I suddenly found a java class that is ISO8601Util.java and this was part of com.google.gson.internal.bind.util .在我搜索了很多以将 ISO8601 转换为最新版本后,我突然发现了一个 java 类ISO8601Util.java ,这是com.google.gson.internal.bind.util的一部分。 So you can use it to convert dates.所以你可以用它来转换日期。

ISO8601Utils.parse("2010-01-01T12:00:00Z" , ParsePosition(0))

and you can simply use this kotlin extension function你可以简单地使用这个 kotlin 扩展功能

fun String.getDateFromString() : Date? = ISO8601Utils.parse(this , 
ParsePosition(0))

Java 8+ Java 8+

Simple one liner that I didn't found in answers:我在答案中没有找到的简单的一个衬里:

Date date = Date.from(ZonedDateTime.parse("2010-01-01T12:00:00+01:00").toInstant());

Date doesn't contain timezone, it will be stored in UTC, but will be properly converted to your JVM timezone even during simple output with System.out.println(date) . Date 不包含时区,它将以 UTC 格式存储,但即使在使用System.out.println(date)进行简单输出时也会正确转换为您的 JVM 时区。

java.time java.time

Note that in Java 8, you can use the java.time.ZonedDateTime class and its static parse(CharSequence text) method.请注意,在 Java 8 中,您可以使用java.time.ZonedDateTime类及其静态parse(CharSequence text)方法。

I faced the same problem and solved it by the following code .我遇到了同样的问题并通过以下代码解决了它。

 public static Calendar getCalendarFromISO(String datestring) {
    Calendar calendar = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault()) ;
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
    try {
        Date date = dateformat.parse(datestring);
        date.setHours(date.getHours() - 1);
        calendar.setTime(date);

        String test = dateformat.format(calendar.getTime());
        Log.e("TEST_TIME", test);

    } catch (ParseException e) {
        e.printStackTrace();
    }

    return calendar;
}

Earlier I was using SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault());早些时候我使用SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.getDefault());

But later i found the main cause of the exception was the yyyy-MM-dd'T'HH:mm:ss.SSSZ ,但后来我发现异常的主要原因是yyyy-MM-dd'T'HH:mm:ss.SSSZ

So i used所以我用

SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());

It worked fine for me .它对我来说很好。

Java has a dozen different ways to parse a date-time, as the excellent answers here demonstrate.正如这里的优秀答案所示,Java 有十几种不同的方法来解析日期时间。 But somewhat amazingly, none of Java's time classes fully implement ISO 8601!但有点令人惊讶的是,Java 的时间类都没有完全实现 ISO 8601!

With Java 8, I'd recommend:对于 Java 8,我建议:

ZonedDateTime zp = ZonedDateTime.parse(string);
Date date = Date.from(zp.toInstant());

That will handle examples both in UTC and with an offset, like "2017-09-13T10:36:40Z" or "2017-09-13T10:36:40+01:00".这将处理 UTC 和偏移量的示例,例如“2017-09-13T10:36:40Z”或“2017-09-13T10:36:40+01:00”。 It will do for most use cases.它适用于大多数用例。

But it won't handle examples like "2017-09-13T10:36:40+01", which is a valid ISO 8601 date-time.但它不会处理像“2017-09-13T10:36:40+01”这样的示例,这一个有效的 ISO 8601 日期时间。
It also won't handle date only, eg "2017-09-13".它也不会只处理日期,例如“2017-09-13”。

If you have to handle those, I'd suggest using a regex first to sniff the syntax.如果你必须处理这些,我建议先使用正则表达式来嗅探语法。

There's a nice list of ISO 8601 examples here with lots of corner cases: https://www.myintervals.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ I'm not aware of any Java class that could cope with all of them.这里有一个很好的 ISO 8601 示例列表,其中包含许多极端案例: https ://www.myintervals.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/ 我是不知道任何可以处理所有这些的 Java 类。

Also you can use the following class -您也可以使用以下课程 -

org.springframework.extensions.surf.util.ISO8601DateFormat


Date date = ISO8601DateFormat.parse("date in iso8601");

Link to the Java Doc - Hierarchy For Package org.springframework.extensions.surf.maven.plugin.util链接到 Java Doc - Hierarchy For Package org.springframework.extensions.surf.maven.plugin.util

I am trying to convert an ISO 8601 formatted String to a java.util.Date .我正在尝试将ISO 8601格式的String转换为java.util.Date

I found the pattern yyyy-MM-dd'T'HH:mm:ssZ to be ISO8601-compliant if used with a Locale (compare sample).如果与区域设置(比较示例)一起使用,我发现模式yyyy-MM-dd'T'HH:mm:ssZ符合ISO8601。

However, using the java.text.SimpleDateFormat , I cannot convert the correctly formatted String 2010-01-01T12:00:00+01:00 .但是,使用java.text.SimpleDateFormat不能转换格式正确的String 2010-01-01T12:00:00+01:00 I have to convert it first to 2010-01-01T12:00:00+0100 , without the colon.我必须先将其转换为2010-01-01T12:00:00+0100 ,而不能使用冒号。

So, the current solution is所以,目前的解决方案是

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

which obviously isn't that nice.显然不是那么好。 Am I missing something or is there a better solution?我是否缺少某些东西或有更好的解决方案?


Answer回答

Thanks to JuanZe's comment, I found the Joda-Time magic, it is also described here .感谢JuanZe的评论,我找到了Joda-Time魔术, 这里也对此进行了描述

So, the solution is因此,解决方案是

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

Or more simply, use the default parser via the constructor:或更简单地说,通过构造函数使用默认解析器:

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

To me, this is nice.对我来说,这很好。

As others have mentioned Android does not have a good way to support parsing/formatting ISO 8601 dates using classes included in the SDK.正如其他人所提到的,Android 没有很好的方法来支持使用 SDK 中包含的类解析/格式化 ISO 8601 日期。 I have written this code multiple times so I finally created a Gist that includes a DateUtils class that supports formatting and parsing ISO 8601 and RFC 1123 dates.我已经多次编写此代码,因此我最终创建了一个 Gist,其中包含一个支持格式化和解析 ISO 8601 和 RFC 1123 日期的 DateUtils 类。 The Gist also includes a test case showing what it supports. Gist 还包括一个测试用例,显示它支持的内容。

https://gist.github.com/mraccola/702330625fad8eebe7d3 https://gist.github.com/mraccola/702330625fad8eebe7d3

SimpleDateFormat for JAVA 1.7 has a cool pattern for ISO 8601 format. SimpleDateFormat for JAVA 1.7 有一个很酷的 ISO 8601 格式模式。

Class SimpleDateFormat 类 SimpleDateFormat

Here is what I did:这是我所做的:

Date d = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
         Locale.ENGLISH).format(System.currentTimeMillis());

使用像LocalDate.parse(((String) data.get("d_iso8601")),DateTimeFormatter.ISO_DATE)这样的字符串

I am surprised that not even one java library supports all ISO 8601 date formats as per https://en.wikipedia.org/wiki/ISO_8601 .我很惊讶,甚至没有一个 java 库支持https://en.wikipedia.org/wiki/ISO_8601中的所有 ISO 8601 日期格式。 Joda DateTime was supporting most of them, but not all and hence I added custom logic to handle all of them. Joda DateTime 支持其中的大多数,但不是全部,因此我添加了自定义逻辑来处理所有这些。 Here is my implementation.这是我的实现。

 import java.text.ParseException; import java.util.Date; import org.apache.commons.lang3.time.DateUtils; import org.joda.time.DateTime; public class ISO8601DateUtils { /** * It parses all the date time formats from https://en.wikipedia.org/wiki/ISO_8601 and returns Joda DateTime. * Zoda DateTime does not support dates of format 20190531T160233Z, and hence added custom logic to handle this using SimpleDateFormat. * @param dateTimeString ISO 8601 date time string * @return */ public static DateTime parse(String dateTimeString) { try { return new DateTime( dateTimeString ); } catch(Exception e) { try { Date dateTime = DateUtils.parseDate(dateTimeString, JODA_NOT_SUPPORTED_ISO_DATES); return new DateTime(dateTime.getTime()); } catch (ParseException e1) { throw new RuntimeException(String.format("Date %s could not be parsed to ISO date", dateTimeString)); } } } private static String[] JODA_NOT_SUPPORTED_ISO_DATES = new String[] { // upto millis "yyyyMMdd'T'HHmmssSSS'Z'", "yyyyMMdd'T'HHmmssSSSZ", "yyyyMMdd'T'HHmmssSSSXXX", "yyyy-MM-dd'T'HHmmssSSS'Z'", "yyyy-MM-dd'T'HHmmssSSSZ", "yyyy-MM-dd'T'HHmmssSSSXXX", // upto seconds "yyyyMMdd'T'HHmmss'Z'", "yyyyMMdd'T'HHmmssZ", "yyyyMMdd'T'HHmmssXXX", "yyyy-MM-dd'T'HHmmss'Z'", "yyyy-MM-dd'T'HHmmssZ", "yyyy-MM-dd'T'HHmmssXXX", // upto minutes "yyyyMMdd'T'HHmm'Z'", "yyyyMMdd'T'HHmmZ", "yyyyMMdd'T'HHmmXXX", "yyyy-MM-dd'T'HHmm'Z'", "yyyy-MM-dd'T'HHmmZ", "yyyy-MM-dd'T'HHmmXXX", //upto hours is already supported by Joda DateTime }; }

Do it like this:像这样做:

public static void main(String[] args) throws ParseException {

    String dateStr = "2016-10-19T14:15:36+08:00";
    Date date = javax.xml.bind.DatatypeConverter.parseDateTime(dateStr).getTime();

    System.out.println(date);

}

Here is the output:这是输出:

Wed Oct 19 15:15:36 CST 2016 2016 年 10 月 19 日星期三 15:15:36 CST

A little test that shows how to parse a date in ISO8601 and that LocalDateTime does not handle DSTs.一个小测试展示了如何解析 ISO8601 中的日期并且 LocalDateTime 不处理 DST。

 @Test
    public void shouldHandleDaylightSavingTimes() throws ParseException {

        //ISO8601 UTC date format
        SimpleDateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

        // 1 hour of difference between 2 dates in UTC happening at the Daylight Saving Time
        Date d1 = utcFormat.parse("2019-10-27T00:30:00.000Z");
        Date d2 = utcFormat.parse("2019-10-27T01:30:00.000Z");

        //Date 2 is before date 2
        Assert.assertTrue(d1.getTime() < d2.getTime());
        // And there is 1 hour difference between the 2 dates
        Assert.assertEquals(1000*60*60, d2.getTime() - d1.getTime());

        //Print the dates in local time
        SimpleDateFormat localFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm z Z", Locale.forLanguageTag("fr_CH"));
        localFormat.setTimeZone(TimeZone.getTimeZone("Europe/Zurich"));

        //Both dates are at 02h30 local time (because of DST), but one is CEST +0200 and the other CET +0100 (clock goes backwards)
        Assert.assertEquals("2019-10-27 02:30 CEST +0200", localFormat.format(d1));
        Assert.assertEquals("2019-10-27 02:30 CET +0100", localFormat.format(d2));

        //Small test that shows that LocalDateTime does not handle DST (and should not be used for storing timeseries data)
        LocalDateTime ld1 = LocalDateTime.ofInstant(d1.toInstant(), ZoneId.of("Europe/Zurich"));
        LocalDateTime ld2 = LocalDateTime.ofInstant(d2.toInstant(), ZoneId.of("Europe/Zurich"));

        //Note that a localdatetime does not handle DST, therefore the 2 dates are the same
        Assert.assertEquals(ld1, ld2);

        //They both have the following local values
        Assert.assertEquals(2019, ld1.getYear());
        Assert.assertEquals(27, ld1.getDayOfMonth());
        Assert.assertEquals(10, ld1.getMonthValue());
        Assert.assertEquals(2, ld1.getHour());
        Assert.assertEquals(30, ld1.getMinute());
        Assert.assertEquals(0, ld1.getSecond());

    }

When want to convert from UTC to format that we want.当想要从 UTC 转换为我们想要的格式时。 It will change depend on the zone/location we stay它会根据我们停留的区域/位置而改变

//utcDate = "2021-06-05T02:46:29Z"
fun converterUtcToReadableDateTime(utcDate: String): String {
    val offsetDateTime = OffsetDateTime.ofInstant(Instant.parse(utcDate), ZoneId.systemDefault())
    val patternDate = "dd MMM yyyy h:mm a"
    return DateTimeFormatter.ofPattern(patternDate).format(offsetDateTime)
}

fun converterUtcToReadableDate(utcDate: String): String {
    val offsetDateTime = OffsetDateTime.ofInstant(Instant.parse(utcDate), ZoneId.systemDefault())
    val patternDate = "d MMM yyyy"
    return DateTimeFormatter.ofPattern(patternDate).format(offsetDateTime)
}

fun converterUtcToReadableTime(utcDate: String): String {
    val offsetDateTime = OffsetDateTime.ofInstant(Instant.parse(utcDate), ZoneId.systemDefault())
    val patternDate = "h:mm a"
    return DateTimeFormatter.ofPattern(patternDate).format(offsetDateTime)
}

I had a similar need: I needed to be able to parse any date ISO8601 compliant without knowing the exact format in advance, and I wanted a lightweight solution which would also work on Android.我也有类似的需求:我需要能够在事先不知道确切格式的情况下解析任何符合 ISO8601 的日期,并且我想要一个也可以在 Android 上运行的轻量级解决方案。

When I googled my needs I stumbled upon this question, and noticed that AFAIU, no answer completely fit my needs.当我搜索我的需求时,我偶然发现了这个问题,并注意到 AFAIU,没有答案完全符合我的需求。 So I developed jISO8601 and pushed it on maven central.所以我开发了jISO8601并将它推到了 maven central 上。

Just add in you pom.xml :只需添加你pom.xml

<dependency>
  <groupId>fr.turri</groupId>
  <artifactId>jISO8601</artifactId>
  <version>0.2</version>
</dependency>

and then you're good to go:然后你就可以走了:

import fr.turri.jiso8601.*;
...
Calendar cal = Iso8601Deserializer.toCalendar("1985-03-04");
Date date = Iso8601Deserializer.toDate("1985-03-04T12:34:56Z");

Hopes it help.希望它有所帮助。

To just format a date like this the following worked for me in a Java 6 based application.要像这样格式化日期,以下在基于 Java 6 的应用程序中对我有用。 There is a DateFormat class JacksonThymeleafISO8601DateFormat in the thymeleaf project which inserts the missing colon:在 thymeleaf 项目中有一个DateFormatJacksonThymeleafISO8601DateFormat插入缺少的冒号:

https://github.com/thymeleaf/thymeleaf/blob/40d27f44df7b52eda47d1bc6f1b3012add6098b3/src/main/java/org/thymeleaf/standard/serializer/StandardJavaScriptSerializer.java https://github.com/thymeleaf/thymeleaf/blob/40d27f44df7b52eda47d1bc6f1b3012add6098b3/src/main/java/org/thymeleaf/standard/serializer/StandardJavaScriptSerializer.java

I used it for ECMAScript date format compatibilty.我将它用于 ECMAScript 日期格式兼容性。

Here is a Kotlin based approach using Java 7. You can pass your custom patterns or just use the default ISO8601 pattern. 这是使用Java 7的基于Kotlin的方法。您可以传递自定义模式,也可以仅使用默认的ISO8601模式。 You probably need to handle parsing errors though. 但是,您可能需要处理解析错误。

object DateUtil {

    private const val ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSX"

    fun convertDateToTimestamp(date: Date, pattern: String = ISO_8601_PATTERN): String {
        val df = SimpleDateFormat(pattern, Locale.getDefault()).apply {
            timeZone = TimeZone.getTimeZone("UTC")
        }
        return df.format(date)
    }

    fun convertTimestampToDate(timestamp: String, pattern: String = ISO_8601_PATTERN): Date {
        val formatter = SimpleDateFormat(pattern, Locale.getDefault()).apply {
            timeZone = TimeZone.getTimeZone("UTC")
        }
        return formatter.parse(timestamp) ?: Date(0)
    }
}

I couldn't use Java 8 features, so only java.util.Date was available.我不能使用 Java 8 的特性,所以只有java.util.Date可用。 I already had a dependency on gson library but didn't want to use ISO8601Utils directly.我已经依赖于 gson 库,但不想直接使用ISO8601Utils ISO8601Utils is an internal API, gson's authors warns not to use it . ISO8601Utils是一个内部 API, gson 的作者警告不要使用它

I parsed a ISO8601 date using gson's public API:我使用 gson 的公共 API 解析了 ISO8601 日期:

fun parseISO8601DateToLocalTimeOrNull(date: String): Date? {
    return try {
        GsonBuilder()
            .create()
            .getAdapter(Date::class.java)
            .fromJson("\"$date\"")
     } catch (t: Throwable) {
        null
     }
}

Under the hood, the adapter still uses ISO8601Utils .在引擎盖下,适配器仍然使用ISO8601Utils But if you're using the adapter you can be sure that a different compatible version of gson won't break your project.但是,如果您使用的是适配器,您可以确定不同的兼容版本的 gson 不会破坏您的项目。

I worried that creation of adapter may be slow so I measured execution time on Pixel 3a with debuggable=false .我担心适配器的创建可能会很慢,所以我用debuggable=false测量了 Pixel 3a 上的执行时间。 parseISO8601DateToLocalTimeOrNull took ~0.5 milliseconds to parse a date. parseISO8601DateToLocalTimeOrNull需要大约 0.5 毫秒来解析日期。

Base Function Courtesy : @wrygiel.基本功能礼貌:@wrygiel。

This function can convert ISO8601 format to Java Date which can handle the offset values.该函数可以将 ISO8601 格式转换为可以处理偏移值的 Java 日期。 As per the definition of ISO 8601 the offset can be mentioned in different formats.根据ISO 8601 的定义,偏移量可以以不同的格式提及。

±[hh]:[mm]
±[hh][mm]
±[hh]

Eg:  "18:30Z", "22:30+04", "1130-0700", and "15:00-03:30" all mean the same time. - 06:30PM UTC

This class has static methods to convert这个类有静态方法来转换

  • ISO8601 string to Date(Local TimeZone) object ISO8601 字符串到日期(本地时区)对象
  • Date to ISO8601 string日期转 ISO8601 字符串
  • Daylight Saving is automatically calc夏令时自动计算

Sample ISO8601 Strings示例 ISO8601 字符串

/*       "2013-06-25T14:00:00Z";
         "2013-06-25T140000Z";
         "2013-06-25T14:00:00+04";
         "2013-06-25T14:00:00+0400";
         "2013-06-25T140000+0400";
         "2013-06-25T14:00:00-04";
         "2013-06-25T14:00:00-0400";
         "2013-06-25T140000-0400";*/


public class ISO8601DateFormatter {

private static final DateFormat DATE_FORMAT_1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private static final DateFormat DATE_FORMAT_2 = new SimpleDateFormat("yyyy-MM-dd'T'HHmmssZ");
private static final String UTC_PLUS = "+";
private static final String UTC_MINUS = "-";

public static Date toDate(String iso8601string) throws ParseException {
    iso8601string = iso8601string.trim();
    if(iso8601string.toUpperCase().indexOf("Z")>0){
        iso8601string = iso8601string.toUpperCase().replace("Z", "+0000");
    }else if(((iso8601string.indexOf(UTC_PLUS))>0)){
        iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_PLUS));
        iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_PLUS), UTC_PLUS);
    }else if(((iso8601string.indexOf(UTC_MINUS))>0)){
        iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_MINUS));
        iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_MINUS), UTC_MINUS);
    }

    Date date = null;
    if(iso8601string.contains(":"))
        date = DATE_FORMAT_1.parse(iso8601string);
    else{
        date = DATE_FORMAT_2.parse(iso8601string);
    }
    return date;
}

public static String toISO8601String(Date date){
    return DATE_FORMAT_1.format(date);
}

private static String replaceColon(String sourceStr, int offsetIndex){
    if(sourceStr.substring(offsetIndex).contains(":"))
        return sourceStr.substring(0, offsetIndex) + sourceStr.substring(offsetIndex).replace(":", "");
    return sourceStr;
}

private static String appendZeros(String sourceStr, int offsetIndex, String offsetChar){
    if((sourceStr.length()-1)-sourceStr.indexOf(offsetChar,offsetIndex)<=2)
        return sourceStr + "00";
    return sourceStr;
}

} }

I am trying to convert an ISO 8601 formatted String to a java.util.Date .我正在尝试将ISO 8601格式的String转换为java.util.Date

I found the pattern yyyy-MM-dd'T'HH:mm:ssZ to be ISO8601-compliant if used with a Locale (compare sample).如果与区域设置(比较示例)一起使用,我发现模式yyyy-MM-dd'T'HH:mm:ssZ符合ISO8601。

However, using the java.text.SimpleDateFormat , I cannot convert the correctly formatted String 2010-01-01T12:00:00+01:00 .但是,使用java.text.SimpleDateFormat不能转换格式正确的String 2010-01-01T12:00:00+01:00 I have to convert it first to 2010-01-01T12:00:00+0100 , without the colon.我必须先将其转换为2010-01-01T12:00:00+0100 ,而不能使用冒号。

So, the current solution is所以,目前的解决方案是

SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.GERMANY);
String date = "2010-01-01T12:00:00+01:00".replaceAll("\\+0([0-9]){1}\\:00", "+0$100");
System.out.println(ISO8601DATEFORMAT.parse(date));

which obviously isn't that nice.显然不是那么好。 Am I missing something or is there a better solution?我是否缺少某些东西或有更好的解决方案?


Answer回答

Thanks to JuanZe's comment, I found the Joda-Time magic, it is also described here .感谢JuanZe的评论,我找到了Joda-Time魔术, 这里也对此进行了描述

So, the solution is因此,解决方案是

DateTimeFormatter parser2 = ISODateTimeFormat.dateTimeNoMillis();
String jtdate = "2010-01-01T12:00:00+01:00";
System.out.println(parser2.parseDateTime(jtdate));

Or more simply, use the default parser via the constructor:或更简单地说,通过构造函数使用默认解析器:

DateTime dt = new DateTime( "2010-01-01T12:00:00+01:00" ) ;

To me, this is nice.对我来说,这很好。

I think what a lot of people want to do is parse JSON date strings.我认为很多人想要做的是解析 JSON 日期字符串。 There is a good chance if you come to this page that you might want to convert a JavaScript JSON date to a Java date.如果您来到此页面,您很有可能希望将 JavaScript JSON 日期转换为 Java 日期。

To show what a JSON date string looks like:要显示 JSON 日期字符串的样子:

    var d=new Date();
    var s = JSON.stringify(d);

    document.write(s);
    document.write("<br />"+d);


    "2013-12-14T01:55:33.412Z"
    Fri Dec 13 2013 17:55:33 GMT-0800 (PST)

The JSON date string is 2013-12-14T01:55:33.412Z. JSON 日期字符串为 2013-12-14T01:55:33.412Z。

Dates are not covered by JSON spec per say, but the above is a very specific ISO 8601 format, while ISO_8601 is much much bigger and that is a mere subset albeit a very important one. JSON规范不包括日期,但上面是一种非常具体的ISO 8601格式,而ISO_8601要大得多,尽管它是一个非常重要的子集,但它只是一个子集。

See http://www.json.org See http://en.wikipedia.org/wiki/ISO_8601 See http://www.w3.org/TR/NOTE-datetimehttp://www.json.orghttp://en.wikipedia.org/wiki/ISO_8601http://www.w3.org/TR/NOTE-datetime

As it happens I wrote a JSON parser and a PLIST parser both of which use ISO-8601 but not the same bits.碰巧我写了一个 JSON 解析器和一个 PLIST 解析器,它们都使用 ISO-8601 但不同的位。

/*
    var d=new Date();
    var s = JSON.stringify(d);

    document.write(s);
    document.write("<br />"+d);


    "2013-12-14T01:55:33.412Z"
    Fri Dec 13 2013 17:55:33 GMT-0800 (PST)


 */
@Test
public void jsonJavaScriptDate() {
    String test =  "2013-12-14T01:55:33.412Z";

    Date date = Dates.fromJsonDate ( test );
    Date date2 = Dates.fromJsonDate_ ( test );

    assertEquals(date2.toString (), "" + date);

    puts (date);
}

I wrote two ways to do this for my project.我为我的项目写了两种方法来做到这一点。 One standard, one fast.一种标准,一种快速。

Again, JSON date string is a very specific implementation of ISO 8601....同样,JSON 日期字符串是 ISO 8601 的一个非常具体的实现......

(I posted the other one in the other answer which should work for PLIST dates, which are a different ISO 8601 format). (我在另一个答案中发布了另一个答案,它应该适用于 PLIST 日期,这是一种不同的 ISO 8601 格式)。

The JSON date is as follows: JSON日期如下:

public static Date fromJsonDate_( String string ) {

    try {

        return new SimpleDateFormat ( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX").parse ( string );
    } catch ( ParseException e ) {
        return Exceptions.handle (Date.class, "Not a valid JSON date", e);
    }


}

PLIST files (ASCII non GNUNext) also uses ISO 8601 but no miliseconds so... not all ISO-8601 dates are the same. PLIST 文件(ASCII 非 GNUNext)也使用 ISO 8601,但没有毫秒,所以......并非所有 ISO-8601 日期都是相同的。 (At least I have not found one that uses milis yet and the parser I have seen skip the timezone altogether OMG). (至少我还没有找到一个使用 milis 的解析器,而且我看到的解析器完全跳过了时区 OMG)。

Now for the fast version (you can find it in Boon).现在是快速版本(您可以在 Boon 中找到它)。

public static Date fromJsonDate( String string ) {

    return fromJsonDate ( Reflection.toCharArray ( string ), 0, string.length () );

}

Note that Reflection.toCharArray uses unsafe if available but defaults to string.toCharArray if not.请注意, Reflection.toCharArray 如果可用则使用 unsafe,但如果不可用则默认为 string.toCharArray。

(You can take it out of the example by replacing Reflection.toCharArray ( string ) with string.toCharArray()). (您可以通过将 Reflection.toCharArray ( string ) 替换为 string.toCharArray() 来将其从示例中删除)。

public static Date fromJsonDate( char[] charArray, int from, int to ) {

    if (isJsonDate ( charArray, from, to )) {
        int year = CharScanner.parseIntFromTo ( charArray, from + 0, from + 4 );
        int month = CharScanner.parseIntFromTo ( charArray,  from +5,  from +7 );
        int day = CharScanner.parseIntFromTo ( charArray,  from +8,  from +10 );
        int hour = CharScanner.parseIntFromTo ( charArray,  from +11,  from +13 );

        int minute = CharScanner.parseIntFromTo ( charArray,  from +14,  from +16 );

        int second = CharScanner.parseIntFromTo ( charArray,  from +17,  from +19 );

        int miliseconds = CharScanner.parseIntFromTo ( charArray,  from +20,  from +23 );

        TimeZone tz = TimeZone.getTimeZone ( "GMT" );


        return toDate ( tz, year, month, day, hour, minute, second, miliseconds );

    }   else {
        return null;
    }

}

The isJsonDate is implemented as follows: isJsonDate 实现如下:

public static boolean isJsonDate( char[] charArray, int start, int to ) {
    boolean valid = true;
    final int length = to -start;

    if (length != JSON_TIME_LENGTH) {
        return false;
    }

    valid &=  (charArray [ start + 19 ]  == '.');

    if (!valid) {
        return false;
    }


    valid &=  (charArray[  start +4 ]  == '-') &&
            (charArray[  start +7 ]  == '-') &&
            (charArray[  start +10 ] == 'T') &&
            (charArray[  start +13 ] == ':') &&
            (charArray[  start +16 ] == ':');

    return valid;
}

Anyway... my guess is that quite a few people who come here.. might be looking for the JSON Date String and although it is an ISO-8601 date, it is a very specific one that needs a very specific parse.无论如何......我的猜测是,很多人来到这里......可能正在寻找 JSON 日期字符串,虽然它是一个 ISO-8601 日期,但它是一个非常具体的日期,需要非常具体的解析。

public static int parseIntFromTo ( char[] digitChars, int offset, int to ) {
    int num = digitChars[ offset ] - '0';
    if ( ++offset < to ) {
        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
        if ( ++offset < to ) {
            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
            if ( ++offset < to ) {
                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                if ( ++offset < to ) {
                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                    if ( ++offset < to ) {
                        num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                        if ( ++offset < to ) {
                            num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                            if ( ++offset < to ) {
                                num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                if ( ++offset < to ) {
                                    num = ( num * 10 ) + ( digitChars[ offset ] - '0' );
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return num;
}

See https://github.com/RichardHightower/boon Boon has a PLIST parser (ASCII) and a JSON parser.请参阅https://github.com/RichardHightower/boon Boon 有一个 PLIST 解析器 (ASCII) 和一个 JSON 解析器。

The JSON parser is the fastest Java JSON parser that I know of. JSON 解析器是我所知道的最快的 Java JSON 解析器。

Independently verified by the Gatling Performance dudes.由 Gatling Performance 帅哥独立验证。

https://github.com/gatling/json-parsers-benchmark https://github.com/gatling/json-parsers-benchmark

Benchmark                               Mode Thr     Count  Sec         Mean   Mean error        Units
BoonCharArrayBenchmark.roundRobin      thrpt  16        10    1   724815,875    54339,825    ops/s
JacksonObjectBenchmark.roundRobin      thrpt  16        10    1   580014,875   145097,700    ops/s
JsonSmartBytesBenchmark.roundRobin     thrpt  16        10    1   575548,435    64202,618    ops/s
JsonSmartStringBenchmark.roundRobin    thrpt  16        10    1   541212,220    45144,815    ops/s
GSONStringBenchmark.roundRobin         thrpt  16        10    1   522947,175    65572,427    ops/s
BoonDirectBytesBenchmark.roundRobin    thrpt  16        10    1   521528,912    41366,197    ops/s
JacksonASTBenchmark.roundRobin         thrpt  16        10    1   512564,205   300704,545    ops/s
GSONReaderBenchmark.roundRobin         thrpt  16        10    1   446322,220    41327,496    ops/s
JsonSmartStreamBenchmark.roundRobin    thrpt  16        10    1   276399,298   130055,340    ops/s
JsonSmartReaderBenchmark.roundRobin    thrpt  16        10    1    86789,825    17690,031    ops/s

It has the fastest JSON parser for streams, readers, bytes[], char[], CharSequence (StringBuilder, CharacterBuffer), and String.它具有最快的 JSON 解析器,可用于流、读取器、bytes[]、char[]、CharSequence(StringBuilder、CharacterBuffer)和 String。

See more benchmarks at:在以下位置查看更多基准:

https://github.com/RichardHightower/json-parsers-benchmark https://github.com/RichardHightower/json-parsers-benchmark

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM