3

I'm generating an XML which contains a date in a valid XML format, and I need it to include a UTC offset as well.

I'm ussing groovy but I'll show the Java code I'm using instead (an answer in either language is good):

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";

The above code give4s me 2011-06-12T07:23:25.000+03:00, but this code has two problems:

  1. It is ugly, and probably not the best way to do this
  2. It won't work for timezones like India (GMT +5:30), Nepal (GMT +5:45)

I tried using new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss Z") for the timezone, but it gave me 2011-06-12T07:23:25.000+0300 which is not a correct format (+0300 instead of +03:00).

Any other way to format the date the way I need it? (preferably without 3rd parties)

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
RonK
  • 9,472
  • 8
  • 51
  • 87

5 Answers5

2

One other alternative - also buried inside jaxb api - (not needing Jodatime):

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

HTH

laher
  • 8,860
  • 3
  • 29
  • 39
  • Thanks - this is the simplest solution which is available everywhere JRE6 is installed. – RonK Jun 12 '11 at 12:23
1

I think that most elegant way is to use Joda-Time library. You need ISO 8601 (Section 5.4) format (as represented by xs:dateTime XSD type):

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

Result:

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

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
0

SimpleDataFormat http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html supports a format specifier letter of X which includes the colon ":" in the time zone. Its worth reading the sectiona about time zones and in particular the part about "ThreeLetterISO8601TimeZone"

Using the format string "yyyy.MM.dd HH:mm:ss.sssXXX" gave me 2015.05.07 15:06:58.058+10:00

TJA
  • 2,969
  • 2
  • 25
  • 32
0

Have you tried using XMLGregorianCalendar? For example:

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

If the calendar is a date-time with a timezone offset, then the timezone offset should be included in the result String formatted as per the XML Datatypes specification.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

java.time

The modern date-time API* not only makes it easy to do but the solution also looks lucid and natural.

Demo:

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

Output:

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

Learn more about the the modern date-time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110