在Java 6中通用支持ISO 8601格式 [英] Generic support for ISO 8601 format in Java 6

查看:183
本文介绍了在Java 6中通用支持ISO 8601格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 7通过字符 X (而不是以 X )在 SimpleDateFormat 类中引入了对ISO 8601格式的支持较低或大写 Z )。在Java 6中支持这样的格式需要预处理,所以最好的方法是问题。

Java 7 has introduced support in the SimpleDateFormat class for ISO 8601 format, via the character X (instead of lower or upper case Z). Supporting such formats in Java 6 requires preprocessing, so the best approach is the question.

这个新格式是 Z (大写字母Z),另有两个变体:

This new format is a superset of Z (uppercase Z), with 2 additional variations:


  1. 分钟字段是可选的(即2位数字而不是4位数的时区有效)

  2. 可以使用冒号字符(':')将2位小时字段从2位数分钟字段中分离出来。

所以,从 SimpleDateFormat 的Java 7文档,以下3种格式现在有效只有Java 6中的 Z 覆盖的第二个),当然等价的:

So, as one can observe from the Java 7 documentation of SimpleDateFormat, the following 3 formats are now valid (instead of only the second one covered by Z in Java 6) and, of course, equivalent:


  1. -08

  2. -0800

  3. -08:00

早期问题,始终以:作为分隔符,是最佳方法将Java 7功能转移到Java 6中是将 SimpleDateformat 类子化,并覆盖其 parse()方法,即:公开日期解析(字符串日期,ParsePosition pos)
{
String iso = ... / ...

As discussed in an earlier question about a special case of supporting such an "expanded" timezone format, always with ':' as a separator, the best approach for backporting the Java 7 functionality into Java 6 is to subclass the SimpleDateformat class and override its parse() method, i.e:

public Date parse(String date, ParsePosition pos)
{
    String iso = ... // Replace the X with a Z timezone string, using a regex

    if (iso.length() == date.length())
    {
        return null; // Not an ISO 8601 date
    }

    Date parsed = super.parse(iso, pos);

    if (parsed != null)
    {
        pos.setIndex(pos.getIndex()+1); // Adjust for ':'
    }

    return parsed;
}

请注意,子类 SimpleDateFormat Z 类型来初始化上面的c>对象,即如果子类是 ExtendedSimpleDateformat 并且你想要解析符合模式的日期 yyyy-MM-dd'T'HH:mm:ssX ,那么您应该使用实例化的对象

Note that the subclassed SimpleDateFormat objects above must be initialized with the corresponding Z-based pattern, i.e. if the subclass is ExtendedSimpleDateformat and you want to parse dates complying to the pattern yyyy-MM-dd'T'HH:mm:ssX, then you should use objects instantiated as

new ExtendedSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");

在上述早期问题正则表达式:(?= [0-9] {2} $)已被建议摆脱':',并在类似问题建议将正则表达式(?<= [+ - ] \d {2})$ 添加为$ c $ c> 00 ,如果需要。

In the aforementioned earlier question the regex :(?=[0-9]{2}$) has been suggested for getting rid of the ':' and in a similar question the regex (?<=[+-]\d{2})$ has been suggested for appending the "minute" field as 00, if needed.

显然,成功运行2个替换可以用于实现全部功能。因此,覆盖的 parse()方法中的 iso local变量将被设置为

Obviously, running the 2 replacements successfully can be used for achieving full functionality. So, the iso local variable in the overridden parse() method would be set as

iso = date.replaceFirst(":(?=[0-9]{2}$)","");

iso = iso.replaceFirst("(?<=[+-]\\d{2})$", "00");

如果签入之间进行确保 pos 值稍后也可以正确设置,并且还可以为 length()进行比较。

with an if check in between to make sure that the pos value is also set properly later on and also for the length() comparison earlier.

问题是:我们可以使用单个正则表达式来实现相同的效果,包括不必要的检查长度和正确设置所需的信息

The question is: can we use a single regular expression to achieve the same effect, including the information needed for not unnecessarily checking the length and for correctly setting pos a few lines later?

该实现旨在用于读取大量字符串字段的代码,可以以任何格式(甚至完全非日期),仅选择符合格式并返回解析的Java Date 对象的那些。

The implementation is intended for code that reads very large numbers of string fields that can be in any format (even totally non-date), selects only those which comply to the format and returns the parsed Java Date object.

所以,准确度速度是至关重要的(即如果使用2次传递更快,这种方法更可取)。 >

So, both accuracy and speed are of paramount importance (i.e., if using the 2 passes is faster, this approach is preferrable).

推荐答案

似乎可以使用这个:

import java.util.Calendar;
import javax.xml.bind.DatatypeConverter;

public class TestISO8601 {
    public static void main(String[] args) {
        parse("2012-10-01T19:30:00+02:00"); // UTC+2
        parse("2012-10-01T19:30:00Z");      // UTC
        parse("2012-10-01T19:30:00");       // Local
    }
    public static Date parse(final String str) {
        Calendar c = DatatypeConverter.parseDateTime(str);
        System.out.println(str + "\t" + (c.getTime().getTime()/1000));
        return c.getTime();
    }
}

这篇关于在Java 6中通用支持ISO 8601格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆