Java 7在
这种新格式是
1. “分钟”字段是可选的(即有效的2位数字时区而不是4位数字) 2. 冒号字符(“:”)可用于将2位数字的“小时”字段与2位数字的“分钟”字段分隔开。
因此,正如人们可以从 Java 7关于
1. -08 2. -0800 3. -08:00
请注意,上述子类化的
在上述早期问题中,建议使用正则表达式
显然,成功运行这两个替换可以用于实现完整功能。因此,在重写的
使用
SimpleDateFormat
类中引入了对ISO 8601格式的支持,使用字符X
(而不是小写或大写的Z
)。在Java 6中支持这种格式需要预处理,因此最好的方法是提出问题。这种新格式是
Z
(大写Z)的超集,有两个附加变体:1. “分钟”字段是可选的(即有效的2位数字时区而不是4位数字) 2. 冒号字符(“:”)可用于将2位数字的“小时”字段与2位数字的“分钟”字段分隔开。
因此,正如人们可以从 Java 7关于
SimpleDateFormat
的文档中观察到的那样,现在有效的有以下3种格式(而不仅仅是Java 6中由Z
覆盖的第二种格式),当然,它们是等效的:1. -08 2. -0800 3. -08:00
如之前问题提到的,关于支持这种“扩展”的时区格式的特殊情况,始终使用':'作为分隔符,将Java 7的功能回溯到Java 6的最佳方法是子类化SimpleDateformat
类并覆盖其parse()
方法,即:
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
的模式进行初始化,即如果子类是ExtendedSimpleDateformat
并且您想解析符合模式yyyy-MM-dd'T'HH:mm:ssX
的日期,则应使用实例化的对象。new ExtendedSimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
在上述早期问题中,建议使用正则表达式
:(?=[0-9]{2}$)
来去掉':',在类似的问题中,建议使用正则表达式(?<=[+-]\d{2})$
来添加"minute"字段为00
(如果需要)。显然,成功运行这两个替换可以用于实现完整功能。因此,在重写的
parse()
方法中,iso
本地变量将被设置为:iso = date.replaceFirst(":(?=[0-9]{2}$)","");
或者
iso = iso.replaceFirst("(?<=[+-]\\d{2})$", "00");
使用
if
检查,确保稍后也正确设置了pos
值,并且在早期的length()
比较中也是如此。问题是:我们可以使用单个正则表达式来实现相同的效果,包括所需的信息以避免不必要地检查长度并正确设置几行后的pos
吗?该实现旨在用于读取数量非常大的字符串字段(可以是任何格式,甚至是完全非日期格式)的代码,仅选择符合格式的字段并返回解析后的Java Date
对象。因此,精度和速度都非常重要(即,如果使用两个步骤更快,则应优先考虑此方法)。
Date
对象呢? - Michael-Ojava.time
类比旧的遗留日期时间类(Date
,Calendar
等)和Joda-Time更加容易。许多java.time
功能在ThreeTen-Backport中被移植到Java 6和7,并在ThreeTenABP中进一步适用于Android。 - Basil Bourque