格式化XML的日期以包括UTC偏移量

时间:2011-06-12 04:43:20

标签: java groovy utc datetime-format

我正在生成一个包含有效XML格式的日期的XML,我还需要它包含UTC偏移量。

我正在使用groovy,但我会显示我正在使用的Java代码(两种语言的答案都很好):

Calendar c = Calendar.getInstance();  
long timeZoneOffset = c.timeZone.getOffset(c.getTimeInMillis())/(1000*60*60);
SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
formatter.format(c.getTime()) + "+0" + timeZoneOffset + ":00";

上面的代码给了我2011-06-12T07:23:25.000+03:00,但是这段代码有两个问题:

  1. 这很丑陋,可能不是最好的方法
  2. 它不适用于像印度这样的时区( GMT +5:30 ),尼泊尔( GMT +5:45
  3. 我尝试使用new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z")作为时区,但它给了我2011-06-12T07:23:25.000+0300这不是正确的格式(+0300而不是+03:00)。

    以我需要的方式格式化日期的任何其他方式? (最好没有第三方)

5 个答案:

答案 0 :(得分:2)

另一种选择 - 也埋在jaxb api中 - (不需要Jodatime):

    Calendar c = ...
    String printDate = javax.xml.bind.DatatypeConverter.printDateTime(c);

HTH

答案 1 :(得分:1)

我认为最优雅的方式是使用Joda-Time库。您需要ISO 8601(第5.4节)格式(由xs:dateTime XSD类型表示):

 DateTime dt = new DateTime();
 DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
 System.out.println(fmt.print(dt));

结果:

  

2011-06-12T07:36:32.294 + 02:00

答案 2 :(得分:0)

您是否尝试过使用XMLGregorianCalendar?例如:

Calendar c = ...
DataTypeFactory f = DataTypeFactory.newInstance();
XMLGregorianCalendar xc = f.newXMLGregorianCalendar(c);
String str = xc.toXMLFormat();

如果日历是具有时区偏移的日期时间,则时区偏移量应包含在根据XML数据类型规范格式化的结果字符串中。

答案 3 :(得分:0)

SimpleDataFormat http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html 支持X的格式说明符字母,其中包含时区中的冒号“:”。值得一读的关于时区的部分,特别是关于“ThreeLetterISO8601TimeZone”的部分

使用格式字符串“yyyy.MM.dd HH:mm:ss.sssXXX”给了我2015.05.07 15:06:58.058 + 10:00

答案 4 :(得分:0)

java.time

modern date-time API* 不仅使操作变得容易,而且解决方案看起来也清晰自然。

演示:

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdtNewYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
        ZonedDateTime zdtIndia = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
        ZonedDateTime zdtNepal = ZonedDateTime.now(ZoneId.of("Asia/Kathmandu"));
        System.out.println(zdtNewYork);
        System.out.println(zdtIndia);
        System.out.println(zdtNepal);

        // If you do not need to display the time zone name, convert it into
        // OffsetDateTime
        OffsetDateTime odtNewYork = zdtNewYork.toOffsetDateTime();
        System.out.println(odtNewYork);

        // Using DateTimeFormatter, you can display it in different formats
        String odtFormat = zdtNewYork.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME.withLocale(Locale.ENGLISH));
        String dayMonFullNameFormat = zdtNewYork.format(DateTimeFormatter.ofPattern("EEEE d MMMM uuuu HH:mm:ssXXX"));
        System.out.println(odtFormat);
        System.out.println(dayMonFullNameFormat);
    }
}

输出:

2021-05-09T16:41:23.683709-04:00[America/New_York]
2021-05-10T02:11:23.685131+05:30[Asia/Kolkata]
2021-05-10T02:26:23.685187+05:45[Asia/Kathmandu]
2021-05-09T16:41:23.683709-04:00
2021-05-09T16:41:23.683709-04:00
Sunday 9 May 2021 16:41:23-04:00

modern date-time API 中了解有关 Trail: Date Time* 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

相关问题