Java.util.Date और XMLGregorian कैलेंडर के बीच सरल रूपांतरण


Answers

XMLGregorian कैलेंडर से java.util.Date तक आप बस कर सकते हैं:

java.util.Date dt = xmlGregorianCalendarInstance.toGregorianCalendar().getTime();  
Question

मैं java.util.Date और javax.xml.datatype.XMLGregorian कैलेंडर दोनों दिशाओं में कनवर्ट करने की एक सरल विधि की तलाश में हूं।

यहां वह कोड है जिसका मैं अब उपयोग कर रहा हूं :

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

/**
 * Utility class for converting between XMLGregorianCalendar and java.util.Date
 */
public class XMLGregorianCalendarConverter {  

    /**
     * Needed to create XMLGregorianCalendar instances
     */
    private static DatatypeFactory df = null;
    static {
        try {
            df = DatatypeFactory.newInstance();
        } catch (DatatypeConfigurationException dce) {
            throw new IllegalStateException(
                "Exception while obtaining DatatypeFactory instance", dce);
        }
    }  

    /**
     * Converts a java.util.Date into an instance of XMLGregorianCalendar
     *
     * @param date Instance of java.util.Date or a null reference
     * @return XMLGregorianCalendar instance whose value is based upon the
     *  value in the date parameter. If the date parameter is null then
     *  this method will simply return null.
     */
    public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) {
        if (date == null) {
            return null;
        } else {
            GregorianCalendar gc = new GregorianCalendar();
            gc.setTimeInMillis(date.getTime());
            return df.newXMLGregorianCalendar(gc);
        }
    }

    /**
     * Converts an XMLGregorianCalendar to an instance of java.util.Date
     *
     * @param xgc Instance of XMLGregorianCalendar or a null reference
     * @return java.util.Date instance whose value is based upon the
     *  value in the xgc parameter. If the xgc parameter is null then
     *  this method will simply return null.
     */
    public static java.util.Date asDate(XMLGregorianCalendar xgc) {
        if (xgc == null) {
            return null;
        } else {
            return xgc.toGregorianCalendar().getTime();
        }
    }
}

क्या कुछ आसान है, जैसे कि कुछ एपीआई कॉल जिन्हें मैंने अनदेखा किया है?

एक मानक एक्सएमएल दिनांक / समय और जावा डेट ऑब्जेक्ट के बीच कनवर्ट करना एक सुंदर दिनचर्या कार्य जैसा लगता है और मुझे हैरान है कि मुझे यह कोड बिल्कुल लिखना है।

कोई सुझाव?

नोट्स: मेरी जेएक्सबी कक्षाएं स्कीमा से स्वत : उत्पन्न होती हैं। मेरे प्रोजेक्ट पर बिल्ड प्रक्रिया मुझे जेनरेटेड क्लास में मैन्युअल परिवर्तन करने की अनुमति नहीं देती है। एक्सएस: जेएक्सबी कक्षाओं में XMLJregorianCalendar के रूप में XJC द्वारा डेटटाइम तत्व उत्पन्न किए जा रहे हैं। स्कीमा को समय-समय पर बढ़ाया जाता है और समय-समय पर tweaked किया जाता है, इसलिए मुझे स्कीमा एक्सएसडी फ़ाइल में सीमित परिवर्तन करने की अनुमति है।

समाधान पर अद्यतन: ब्लेज़ द्वारा प्रस्तावित समाधान ने मुझे XML सेreggianian कैलेंडर को मिश्रण से बाहर करने और इसके बजाय java.util.Calendar ऑब्जेक्ट्स के साथ सौदा करने की अनुमति दी है। मेरी स्कीमा फ़ाइल के शीर्ष पर एक जेएक्सबी बाइंडिंग क्लॉज जोड़कर, एक्सजेसी एक्सएस के लिए अधिक उपयुक्त मैपिंग उत्पन्न करने में सक्षम है: मेरे जेएक्सबी कक्षाओं में डेटटाइम। यहां कुछ स्निपेट हैं जो मेरी एक्सएसडी फ़ाइल में संशोधन दिखाते हैं।

एक्सएसडी फ़ाइल में मूल तत्व:

<xs:schema xmlns:mydata="http://my.example.com/mydata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://my.example.com/mydata" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="0.2" xml:lang="en" jaxb:version="2.0">

जेएक्सबी बाध्यकारी एनोटेशन ब्लॉक, एक्सएसडी में रूट तत्व के तुरंत बाद डाला गया:

<xs:annotation>
    <xs:appinfo>
        <jaxb:globalBindings>
            <jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
        </jaxb:globalBindings>
    </xs:appinfo>
</xs:annotation>

चूंकि एक्सएमएल एक्सएस: डेटटाइम फ़ील्ड टाइमज़ोन भी स्टोर करता है, फिर भी मेरे लिए कैलेंडर के साथ कैलेंडर के साथ काम करना बेहतर हो सकता है क्योंकि कैलेंडर ऑब्जेक्ट्स में स्थानीय और टाइमज़ोन के साथ काम करने के लिए एक बहुत अच्छा एपीआई है। किसी भी मामले में, मैं XMLGregorianCalendar की बजाय कैलेंडर ऑब्जेक्ट्स से निपटने के लिए बहुत खुश हूं। मैंने अब ऊपर सूचीबद्ध रूपांतरण विधियों की आवश्यकता नहीं है। मुझे java.util.Date के लिए सभी तरह से नहीं मिला, लेकिन पर्याप्त बंद करो!




आप java.util.Date पर डिफ़ॉल्ट मैपिंग को बदलने के लिए इस अनुकूलन का उपयोग कर सकते हैं

<xsd:annotation>
<xsd:appinfo>
    <jaxb:globalBindings>
        <jaxb:javaType name="java.util.Date" xmlType="xsd:dateTime"
                 parseMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDateTime"
                 printMethod="org.apache.cxf.xjc.runtime.DataTypeAdapter.printDateTime"/>
    </jaxb:globalBindings>
</xsd:appinfo>




मुझे इसे काम करने के लिए कुछ बदलाव करना पड़ा, क्योंकि कुछ चीजें इस दौरान बदल गई हैं:

  • xjc शिकायत करेगा कि मेरा एडाप्टर XmlAdapter का विस्तार नहीं करता है
  • कुछ विचित्र और अनियंत्रित आयात (org.w3._2001.xmlschema) में खींचे गए थे
  • स्पष्ट रूप से XmlAdapter को विस्तारित करते समय पार्सिंग विधियां स्थिर नहीं होनी चाहिए

यहां एक कामकाजी उदाहरण है, उम्मीद है कि यह मदद करता है (मैं जोडाटाइम का उपयोग कर रहा हूं लेकिन इस मामले में सरलडेट पर्याप्त होगा):

import java.util.Date;
import javax.xml.bind.DatatypeConverter;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import org.joda.time.DateTime;

public class DateAdapter extends XmlAdapter<Object, Object> {
    @Override
    public Object marshal(Object dt) throws Exception {
        return new DateTime((Date) dt).toString("YYYY-MM-dd");
    }

    @Override
        public Object unmarshal(Object s) throws Exception {
        return DatatypeConverter.parseDate((String) s).getTime();
    }
}

एक्सएसडी में, मैंने ऊपर दिए गए उत्कृष्ट संदर्भों का पालन किया है, इसलिए मैंने इस एक्सएमएल एनोटेशन को शामिल किया है:

<xsd:appinfo>
    <jaxb:schemaBindings>
        <jaxb:package name="at.mycomp.xml" />
    </jaxb:schemaBindings>
    <jaxb:globalBindings>
        <jaxb:javaType name="java.util.Date" xmlType="xsd:date"
              parseMethod="at.mycomp.xml.DateAdapter.unmarshal"
          printMethod="at.mycomp.xml.DateAdapter.marshal" />
    </jaxb:globalBindings>
</xsd:appinfo>