java.util। XMLGregorianCalendar पर जाएं


600

वहाँ एक java.util से प्राप्त करने का एक सुविधाजनक तरीका नहीं है। XMLGregorianCalendar पर जाएं?


FYI करें: इन दोनों भयानक वर्गों को जेएसआर 310 में परिभाषित java.time कक्षाओं द्वारा वर्षों पहले दबा दिया गया था । देखें ZonedDateTimeवर्ग, और नए रूपांतरण तरीके विरासत कक्षाओं में जोड़े गए हैं। इस उत्तर में विवरण ओले वीवी
बेसिल बॉर्क

जवाबों:


35

मुझे इस 10 साल पुराने प्रश्न पर एक कदम पीछे हटना चाहिए और एक आधुनिक रूप देना चाहिए। उल्लिखित कक्षाएं, Dateऔर XMLGregorianCalendar, अब पुरानी हैं। मैं उनके उपयोग को चुनौती देता हूं और विकल्प प्रस्तुत करता हूं।

  • Dateहमेशा खराब डिज़ाइन किया गया था और 20 साल से अधिक पुराना है। यह सरल है: इसका उपयोग न करें।
  • XMLGregorianCalendarपुराना भी है और एक पुराने ढंग का डिजाइन है। जैसा कि मैं इसे समझता हूं, इसका उपयोग XML दस्तावेजों के लिए XML प्रारूप में दिनांक और समय के उत्पादन के लिए किया गया था। जैसा 2009-05-07T19:05:45.678+02:00या 2009-05-07T17:05:45.678Z। ये प्रारूप आईएसओ 8601 के साथ पर्याप्त रूप से सहमत हैं कि java.time, आधुनिक जावा तिथि और समय एपीआई की कक्षाएं, उन्हें उत्पादन कर सकती हैं, जिसे हम पसंद करते हैं।

कोई रूपांतरण आवश्यक नहीं

कई (सबसे?) उद्देश्यों के लिए एक के लिए आधुनिक प्रतिस्थापन एक Dateहोगा Instant। एक Instantसमय में एक बिंदु (बस एक के रूप Dateमें) है।

    Instant yourInstant = // ...
    System.out.println(yourInstant);

इस स्निपेट से एक उदाहरण आउटपुट:

2009-05-07T17: 05: 45.678Z

यह XMLGregorianCalendarऊपर के मेरे उदाहरण के तार के समान है। जैसा कि आप में से अधिकांश जानते हैं, यह Instant.toStringअंतर्निहित रूप से कहा जाता है System.out.println। Java.time के साथ, कई मामलों में हम रूपांतरण पुराने दिनों में हम के बीच किया जाता है कि की जरूरत नहीं है Date, Calendar, XMLGregorianCalendarऔर अन्य वर्गों (कुछ मामलों में हम जरूरत रूपांतरण कर में, हालांकि, मैं तुम्हें अगले भाग में एक जोड़े को दिखा रहा) ।

ऑफसेट नियंत्रित करना

न तो एक Dateऔर न ही में Instantएक समय क्षेत्र मिल गया है और न ही एक यूटीसी ऑफसेट। बेन नोलैंड द्वारा पहले स्वीकार किए गए और अभी भी सबसे अधिक वोट किए गए उत्तर का उपयोग ऑफ़सेट के चयन के लिए जेवीएम वर्तमान डिफ़ॉल्ट समय क्षेत्र का उपयोग करता है XMLGregorianCalendar। एक आधुनिक वस्तु में एक ऑफसेट को शामिल करने के लिए हम एक का उपयोग करते हैं OffsetDateTime। उदाहरण के लिए:

    ZoneId zone = ZoneId.of("America/Asuncion");
    OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
    System.out.println(dateTime);

2009-05-07T13: 05: 45.678-04: 00

फिर से यह XML प्रारूप के अनुरूप है। यदि आप वर्तमान जेवीएम टाइम ज़ोन सेटिंग का फिर से उपयोग करना चाहते हैं, तो सेट zoneकरें ZoneId.systemDefault()

क्या होगा अगर मुझे XMLGregorianCalendar की आवश्यकता है?

में परिवर्तित Instantकरने के और भी तरीके हैं XMLGregorianCalendar। मैं एक युगल पेश करूंगा, प्रत्येक इसके पेशेवरों और विपक्षों के साथ। सबसे पहले, जैसे XMLGregorianCalendarएक स्ट्रिंग पैदा करता है 2009-05-07T17:05:45.678Z, यह भी इस तरह के एक स्ट्रिंग से बनाया जा सकता है:

    String dateTimeString = yourInstant.toString();
    XMLGregorianCalendar date2
            = DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
    System.out.println(date2);

2009-05-07T17: 05: 45.678Z

प्रो: यह छोटा है और मुझे नहीं लगता कि यह कोई आश्चर्य की बात है। Con: मेरे लिए यह ऐसा लगता है जैसे अपशिष्ट एक स्ट्रिंग में तत्काल स्वरूपण करता है और इसे वापस पार्स करता है।

    ZonedDateTime dateTime = yourInstant.atZone(zone);
    GregorianCalendar c = GregorianCalendar.from(dateTime);
    XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
    System.out.println(date2);

2009-05-07T13: 05: 45.678-04: 00

प्रो: यह आधिकारिक रूपांतरण है। ऑफसेट को नियंत्रित करना स्वाभाविक रूप से आता है। Con: यह अधिक चरणों से गुजरता है और इसलिए अधिक लंबा है।

अगर हमें तारीख मिल गई तो क्या होगा?

यदि आपको Dateविरासत एपीआई से एक पुराने जमाने की वस्तु मिली है जिसे आप अभी नहीं बदल सकते हैं, तो इसे इसमें परिवर्तित करें Instant:

    Instant i = yourDate.toInstant();
    System.out.println(i);

आउटपुट पहले जैसा ही है:

2009-05-07T17: 05: 45.678Z

यदि आप ऑफ़सेट को नियंत्रित करना चाहते हैं, तो OffsetDateTimeऊपर की तरह उसी रूप में परिवर्तित करें ।

यदि आपको एक पुराने जमाने का है Dateऔर आपको पुराने जमाने की जरूरत है XMLGregorianCalendar, तो बस बेन नॉलैंड के जवाब का उपयोग करें।

लिंक


1034
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);

5
क्या यह getInstance () को कुछ कनवर्टर वर्ग में एक स्थिर चर के रूप में सहेजने के लिए सहेजता है? मैंने इसे JavaDoc में देखने की कोशिश की, लेकिन कुछ भी नहीं मिला। यह जानने के लिए मुश्किल है कि क्या समवर्ती उपयोग में समस्याएं होंगी?
मार्टिन

36
यदि आप JodaTime का उपयोग करने के लिए तैयार हैं, तो आप इसे एक पंक्ति में कर सकते हैं: DatatypeFactory.newInstance ()। newXMLGregorianCalendar (नया DateTime () .GregorianCalendar ())
निकोलस ममॉर्ट्स 15'13

3
XMLGregorianCalendar date2 = DatatypeFactory.newInstance ()। newXMLGregorianCalendar (नए ग्रेगोरियन कैलेंडर (YYYY, MM, DD));
जंकेन लियू

3
कृपया ध्यान रखें कि कैलेंडर थ्रेडसेफ़ नहीं है और इसलिए ग्रेगोरियन कैलेंडर भी नहीं है। यह भी देखें stackoverflow.com/questions/12131324/…
प्रश्नावली

एक पंक्ति संस्करण - DatatypeFactory.newInstance ()। NewXMLGregorianCalendar (नया ग्रेगोरियन कैलेन्डर () {{setTime (yourDate);}}))
एलेक्स वैयाल जार

205

उन है कि यहाँ खत्म हो सकता है (से विपरीत रूपांतरण की तलाश के लिए XMLGregorianCalendarकरने के लिए Date):

XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();

31

यहाँ एक ग्रेगोरियन कैलेन्डर से XMLGregorianCalendar में परिवर्तित करने की एक विधि है; मैं आपके लिए एक व्यायाम के रूप में एक java.util.Date से ग्रेगोरियन कैलेन्डर में परिवर्तित होने का हिस्सा छोड़ दूंगा:

import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateTest {

   public static void main(final String[] args) throws Exception {
      GregorianCalendar gcal = new GregorianCalendar();
      XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gcal);
      System.out.println(xgcal);
   }

}

संपादित करें: Slooow :-)


6
यह ग्रेगोरियन
कैलेन्डर


12

बस मैंने सोचा कि मैं नीचे अपना समाधान जोड़ दूंगा, क्योंकि ऊपर दिए गए उत्तर मेरी सटीक जरूरतों को पूरा नहीं करते हैं। मेरे Xml स्कीमा को अलग दिनांक और समय के तत्वों की आवश्यकता है, न कि एक सिंग डेट डेट फ़ील्ड। ऊपर उपयोग किया गया मानक XMLGregorianCalendar निर्माता एक DateTime फ़ील्ड जनरेट करेगा

ध्यान दें कि गोथका के कुछ जोड़े हैं, जैसे कि महीने में एक को जोड़ना (क्योंकि जावा 0 से महीनों की गणना करता है)।

GregorianCalendar cal = new GregorianCalendar();
cal.setTime(yourDate);
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), 0);
XMLGregorianCalendar xmlTime = DatatypeFactory.newInstance().newXMLGregorianCalendarTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0);

10

मुझे उम्मीद है कि मेरी एन्कोडिंग यहाँ सही है; डी इसे और तेज़ बनाने के लिए बस निर्माता के बजाय ग्रेगोरियन कैलेन्डर के बदसूरत getInstance () कॉल का उपयोग करें:

import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateTest {

   public static void main(final String[] args) throws Exception {
      // do not forget the type cast :/
      GregorianCalendar gcal = (GregorianCalendar) GregorianCalendar.getInstance();
      XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
            .newXMLGregorianCalendar(gcal);
      System.out.println(xgcal);
   }

}

14
-1 .get उपयोग के लिए ()। GregorianCalendar.getInstance()के बराबर है Calendar.getInstance()Calendar.getInstance(), यह तेजी से कर सकते हैं नहीं है क्योंकि यह एक ही उपयोग करता है new GregorianCalendar(), लेकिन इससे पहले यह भी डिफ़ॉल्ट स्थान की जांच करता है और बदले में जापानी या Buddish कैलेंडर बना सकते हैं, इसलिए कुछ भाग्यशाली उपयोगकर्ताओं के लिए यह हो जाएगा ClassCastException!
कान

6

मान लें कि आप xml को डिकोड या एन्कोडिंग कर रहे हैं और उपयोग कर रहे हैं JAXB, तो यह संभव है कि डेटाइम बाइंडिंग को पूरी तरह से बदल दिया जाए और स्कीमा में प्रत्येक तिथि के लिए `XMLGregorianCalendar’ के अलावा किसी अन्य चीज़ का उपयोग किया जाए।

इस तरह से आप कर सकते हैं JAXB दोहराव वाले सामान कर सकते हैं, जबकि आप मूल्य वितरित करने वाले भयानक कोड लिखने में समय बिता सकते हैं।

उदाहरण के लिए जद्दोजहद DateTime: (java.util.Date के साथ ऐसा करना भी काम करेगा - लेकिन कुछ सीमाओं के साथ। मैं jodatime पसंद करता हूं और इसे मेरे कोड से कॉपी किया जाता है, इसलिए मुझे पता है कि यह काम करता है ...)

<jxb:globalBindings>
    <jxb:javaType name="org.joda.time.LocalDateTime" xmlType="xs:dateTime"
        parseMethod="test.util.JaxbConverter.parseDateTime"
        printMethod="se.seb.bis.test.util.JaxbConverter.printDateTime" />
    <jxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
        parseMethod="test.util.JaxbConverter.parseDate"
        printMethod="test.util.JaxbConverter.printDate" />
    <jxb:javaType name="org.joda.time.LocalTime" xmlType="xs:time"
        parseMethod="test.util.JaxbConverter.parseTime"
        printMethod="test.util.JaxbConverter.printTime" />
    <jxb:serializable uid="2" />
</jxb:globalBindings>

और कनवर्टर:

public class JaxbConverter {
static final DateTimeFormatter dtf = ISODateTimeFormat.dateTimeNoMillis();
static final DateTimeFormatter df = ISODateTimeFormat.date();
static final DateTimeFormatter tf = ISODateTimeFormat.time();

public static LocalDateTime parseDateTime(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        LocalDateTime r = dtf.parseLocalDateTime(s);
        return r;
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printDateTime(LocalDateTime d) {
    try {
        if (d == null)
            return null;
        return dtf.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static LocalDate parseDate(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        return df.parseLocalDate(s);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printDate(LocalDate d) {
    try {
        if (d == null)
            return null;
        return df.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static String printTime(LocalTime d) {
    try {
        if (d == null)
            return null;
        return tf.print(d);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

public static LocalTime parseTime(String s) {
    try {
        if (StringUtils.trimToEmpty(s).isEmpty())
            return null;
        return df.parseLocalTime(s);
    } catch (Exception e) {
        throw new IllegalArgumentException(e);
    }
}

यहाँ देखें: XmlGregorianCalendar को तारीख से कैसे बदलें?

यदि आप टाइमज़ोन + टाइमस्टैम्प के आधार पर सिर्फ एक मैप के लिए खुश हैं, और मूल टाइमज़ोन वास्तव में प्रासंगिक नहीं है, तो java.util.Dateशायद ठीक भी है।


0

इस कोड को देखें: -

/* Create Date Object */
Date date = new Date();
XMLGregorianCalendar xmlDate = null;
GregorianCalendar gc = new GregorianCalendar();

gc.setTime(date);

try{
    xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
}
catch(Exception e){
    e.printStackTrace();
}

System.out.println("XMLGregorianCalendar :- " + xmlDate);

आप यहां पूरा उदाहरण देख सकते हैं


मुझे नहीं लगता कि यह उत्तर कुछ नया नहीं प्रदान करता है .. शायद आप पिछले उत्तर को एक और पोस्ट के बजाय लगभग एक ही संपादित कर सकते हैं।
सर्दी

1
XMLGregorianCalendar के लिए डेटफ़ॉर्म कैसे करें?
पैनाडोल चोंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.