W3C XML的Java SimpleDateFormat模式带有时区

时间:2012-05-16 08:33:14

标签: java date simpledateformat iso8601

我正在尝试解析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模式或变通方法来表示上述日期而不预先处理日期字符串?

9 个答案:

答案 0 :(得分:34)

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

SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");

答案 1 :(得分:24)

如下:

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);
    }
};

答案 2 :(得分:11)

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

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

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

答案 3 :(得分:3)

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

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

如果由于某种原因你不能或不想使用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();

答案 4 :(得分: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;
              }

答案 5 :(得分:2)

最好的方法是使用Joda的

org.joda.time.format.ISODateTimeFormat

此致

答案 6 :(得分: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;
    }

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

答案 7 :(得分:1)

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

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

TimeZone zone = TimeZone.getTimeZone(TimeZone.getTimeZone("GMT-8").getID());
GregorianCalendar calendar = new GregorianCalendar(zone);
calendar.setTime(new Date(SomeDate));

答案 8 :(得分:1)

您可以尝试以下内容:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
Date date = df.parse(stringDate.replaceAll("\\+", "GMT+"));