2012-05-16 7 views
28

Ich versuche, ein W3C XML-Schema-Datum wie folgtJava Simple Muster für W3C XML Termine mit Zeitzone

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

, die mit dem ISO 8601-Version der W3C XML Schema dateTime Spezifikation entspricht zu analysieren.

In dem oben genannten Datum ist der Zeitzonenbezeichner "+03:00", aber kein SimpleDateFormat Muster existiert anscheinend, um es darzustellen.

Wenn die Zeitzone war "+0300", dann Z (Groß-) anwendbar wäre und das SimpleDateFormat Muster

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

ähnlich wäre, wenn die Zeitzone "GMT+03:00" ist, dann z (klein geschrieben) anwendbar wäre und die SimpleDateFormat Muster würde

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

(Groß 'Z' funktioniert auch, nebenbei bemerkt) sein.

Gibt es also ein SimpleDateFormat Muster oder Workaround, um das obige Datum ohne Vorverarbeitung der Datumszeichenfolge darzustellen?

+0

Eigentlich, das Eingabezeichenfolge ist in einem Format von der [ISO 8601] (https://en.wikipedia.org/wiki/ISO_8601) Standard (eine Familie von Datum-Zeit-Formaten). –

Antwort

23

Wie wäre es so etwas wie:

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

Das ist genial! – adarshr

+0

Clever, elegant und funktional. Vielen Dank! – PNS

+1

Wer die ParsePosition nach parse() wieder verwenden muss, muss den Index möglicherweise um eins in parse() anpassen, da die Quelle tatsächlich 1 länger ist, also etwas wie pos.setIndex (pos.getIndex() + 1). – PNS

1

Ich bin mir nicht ganz sicher, ob das für Sie funktioniert oder nicht. Aber hier habe ich den Code versucht, während ich das Datum von einer Zeitzone in eine andere Zeitzone umwandele. Kann ein Teil des Codes Ihnen helfen.

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

Hoffe das hilft Ihnen. Prost. :)

+0

Ich wollte etwas einfacheres, aber danke für die Mühe. :-) – PNS

3

Nein, es gibt keine Problemumgehung, SimpleDateFormat verstehen dieses Format ohne Vorverarbeitung der Zeichenfolge (zum Beispiel durch Entfernen der : aus der Zeichenfolge). (Bearbeiten: außer wenn Sie Java 7 oder neuer verwenden, wie von assylias angegeben).

Es sieht so aus, als ob Sie Strings im Standard-XML-Format nach Datum und Uhrzeit analysieren möchten (ISO 8601). Ich würde empfehlen, die Joda Time Bibliothek zu verwenden, die support for this format hat. Wenn Sie Joda Time aus irgendeinem Grund nicht verwenden können oder wollen, können Sie Klassen aus dem Paket javax.xml.datatype verwenden, um Zeitstempel in diesem Format zu analysieren und zu formatieren. Zum Beispiel:

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(); 
+0

JodaTime unterstützt nicht alle Muster, die Java SimpleDateFormat Klasse unterstützt. – PNS

+0

@PNS Ja, aber Sie haben speziell nach dem ISO 8601-Format gefragt. – Jesper

+0

Sicher, ich habe nur auf die Begrenzung hingewiesen. Ansonsten wäre JodaTime wahrscheinlich der richtige Weg. – PNS

10

Hmmm das Datumsformat sieht aus wie XML Datetime Format Format? Wenn es XML-Datetime-Datentyp-Format ist, können Sie javax.xml.datatype.DatatypeFactory verwenden XMLGregorianCalendar

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

Die obige Anruf-Instanz erstellen von XMLGregorianCalendar kehrt das Objekt verwenden kann, um andere Java-Datetime-Objekte wie GregorianCalendar zu konvertieren.

33

Wenn Sie Java 7+ verwenden, sollte dieses Muster arbeiten (X ist für die ISO-8601-Zeitzone):

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

Das ist sehr nett zu wissen. Ich bin immer noch fest mit Java 1.6- :( – Alvin

+1

Das gleiche hier über Java 6, aber danke für die Notiz. – PNS

+1

Das richtige Muster für das Datum Beispiel dieser Frage sollte wahrscheinlich sein "JJJJ-MM-TT'T'HH: mm : ssX "(dh nur ein 'X'). – PNS

1

In Bezug Sie Simple habe bereits erwähnt die Formatmuster, die zur Verfügung stehen und sie sind definiert in: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

Wenn Sie mehr mit Ihrem Date machen wollen GregorianCalendar gibt Ihnen mehr Möglichkeiten dann, zB:

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

Der beste Weg ist die

des Joda verwenden
org.joda.time.format.ISODateTimeFormat 

Grüße,

1

Sie so etwas wie versuchen:

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

Sicher, aber ich frage mich, ob es ohne Vorverarbeitung gemacht werden kann. – PNS

3

Verwenden Sie Apache commons DateUtils mit möglichen Mustern. Ex:

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