33

我正在尝试解析W3C XML Schema 日期,如下所示

"2012-05-15T07:08:09+03:00"

它符合W3C XML Schema dateTime规范的 ISO 8601 版本。

在上述日期中,时区标识符为"+03:00",但SimpleDateFormat显然不存在表示它的模式。

如果时区是"+0300",那么Z(大写)将适用并且SimpleDateFormat模式将是

yyyy-MM-dd'T'HH:mm:ssZ

同样,如果时区为"GMT+03:00",则z(小写) 将适用并且SimpleDateFormat模式将是

yyyy-MM-dd'T'HH:mm:ssz

(顺便说一句,大写'Z'也可以)。

那么,是否有一种SimpleDateFormat模式或解决方法来表示上述日期而不对日期字符串进行预处理?

4

9 回答 9

37

如果您使用 Java 7+,则此模式应该有效(X适用于 ISO 8601 时区):

SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
于 2012-05-16T08:46:35.257 回答
26

怎么样:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"){ 
    public Date parse(String source,ParsePosition pos) {    
        return super.parse(source.replaceFirst(":(?=[0-9]{2}$)",""),pos);
    }
};
于 2012-05-16T08:51:35.857 回答
11

嗯,日期格式看起来像 XML 日期时间数据类型格式?如果是 XML 日期时间数据类型格式,您可以使用javax.xml.datatype.DatatypeFactory来创建XMLGregorianCalendar

DatatypeFactory
  .newInstance()
  .newXMLGregorianCalendar("2012-05-15T07:08:09+03:00");

上面的调用返回实例,XMLGregorianCalendar您可以使用该对象转换为其他 Java 日期时间对象,如GregorianCalendar.

于 2012-05-16T08:44:26.643 回答
3

不,没有解决方法可以在SimpleDateFormat不预处理字符串的情况下理解这种格式(例如通过:从字符串中删除)。(编辑:除非您使用的是 assylias 指出的 Java 7 或更新版本)。

看起来您正在尝试以标准 XML 格式解析日期和时间 (ISO 8601) 的字符串。我建议使用支持这种格式的Joda Time库。

如果由于某种原因您不能或不想使用 Joda Time,那么您可以使用包中的类javax.xml.datatype来解析和格式化这种格式的时间戳。例如:

DatatypeFactory factory = DatatypeFactory.newInstance();

// Parses a string in ISO 8601 format to an XMLGregorianCalendar
XMLGregorianCalendar xmlCal = factory.newXMLGregorianCalendar("2012-05-16T10:39:00+03:00");

// Convert it to a regular java.util.Calendar
Calendar cal = xmlCal.toGregorianCalendar();
于 2012-05-16T08:43:16.117 回答
3

将 Apache commons DateUtils 与可能的模式一起使用。前任:

private static final String[] DATE_FORMATS = new String[] {
            "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ssz",
            "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-ddz", "yyyy-MM-ddZ" };


    public Date parse(String date) {

        Date parsedDate = null;
        try {
            parsedDate = DateUtils.parseDate(date, DATE_FORMATS);
        } catch (ParseException e) {
            logger.error("dates should be in valid format" + e);
            return null;
        }
               return parsedDate;
              }
于 2013-09-05T10:24:06.903 回答
2

最好的方法是使用 Joda 的

org.joda.time.format.ISODateTimeFormat

问候,

于 2012-05-16T09:19:34.553 回答
1

我不太确定这是否适合您。但是这里是我在将日期从一个时区转换为另一个时区时尝试过的代码。可能某些部分代码可以帮助您。

public Date convertToUserTimezone(long dateToConvert, String timezoneOffset){
        java.text.DateFormat format = SimpleDateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);/*new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");*/
        // java.util.Calendar cal = Calendar.getInstance(new
        // SimpleTimeZone(0, "GMT+05:30"));
        TimeZone gmtTime = TimeZone.getTimeZone("GMT"+timezoneOffset);


        format.setTimeZone(gmtTime);
        java.util.Date date1 = new Date(format.format(new Date(dateToConvert)));

        return date1;
    }

希望这对您有所帮助。干杯。:)

于 2012-05-16T08:42:00.597 回答
1

关于 SimpleDateFormat,您已经提到了可用的格式模式,它们定义在:http ://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

如果你想用你的 Date 做更多的事情,那么 GregorianCalendar 会给你更多的选择,例如:

TimeZone zone = TimeZone.getTimeZone(TimeZone.getTimeZone("GMT-8").getID());
GregorianCalendar calendar = new GregorianCalendar(zone);
calendar.setTime(new Date(SomeDate));
于 2012-05-16T09:06:03.787 回答
1

您可以尝试以下方法:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
Date date = df.parse(stringDate.replaceAll("\\+", "GMT+"));
于 2012-05-16T09:22:54.443 回答