2008-09-22 14 views
7

मैं वेब सेवा के माध्यम से कुछ वस्तुओं के आसपास गुजर रहा हूं और उनमें से कुछ में java.sql.Date शामिल है। क्योंकि तिथि में खाली कन्स्ट्रक्टर नहीं है क्योंकि यह धारावाहिक प्राप्त नहीं करना चाहता है।जावा में सीरियलाइजिंग दिनांक

एक प्रश्न का पहला भाग आसान है: ग्राहक और सेवा के बीच की तारीख को पारित करने का सबसे अच्छा तरीका क्या है?

दूसरा भाग थोड़ा चालक है: एक बार जब मैं तय करता हूं कि तारीखों को कैसे पास किया जाए, तो मैं स्पष्ट रूप से दिनांक क्षणिक घोषित कर सकता हूं और कुछ रैपर वर्ग को स्ट्रिंग या जो भी हो, तारीखों को पारित करने के लिए कर सकता हूं, लेकिन कई समाधानों के लिए पारदर्शी रूप से उसी समाधान को कैसे लागू करें कक्षाएं जिसमें तिथि शामिल है?

(मैं एक कूबड़ कि DynamicProxy thingy एक समाधान हो सकता है है, लेकिन सूर्य की साइट पर प्रलेखन पढ़ने इसलिए यदि यह वास्तव में उस दिशा में कुछ है, कुछ स्पष्टीकरण की सराहना की जाएगी, बहुत मददगार नहीं था)

संपादित करें : मैंने गलत सवाल पूछा, क्षमा करें (मेरे और सहकर्मी के बीच कुछ गलतफहमी वास्तव में एक समस्या है)। Deserializing के कारण समस्या होती है। तो एक बार जब मैं एक्सएमएल प्रारूप में डेट करता हूं तो यह खुद को ग्रेगोरियन कैलेंडर के रूप में deserialize करने की कोशिश करता है। एक प्रश्न का अन्य भाग अभी भी बनी हुई है: कुछ अलग-अलग वर्गों के लिए 10 अलग-अलग रैपर बनाने के बिना कुछ (लंबी टाइमस्टैम्प या ग्रेगोरियन कैलेंडर) प्राप्त करने और इसे एसक्यूएल तिथि में परिवर्तित करने का सबसे अच्छा तरीका क्या है। मैं कोड और wsdl पीढ़ी के लिए नेटबीन का उपयोग कर रहा हूँ।

उत्तर

2

java.sql.Date फैली java.util.Date

बस getTime का उपयोग() से लंबे मूल्य मिलता है। इसे धारावाहिक और एक नया java.sql.Date (लंबा) या नया java.util.Date (लंबा) दूसरे छोर पर बनाया जा सकता है।

+0

जैसे एंट्ज़िक ने ऊपर कहा, यह तिथि में निहित टाइमज़ोन खो देता है। – Coderer

0

सबसे पहले, यदि आप वेब सेवाओं का उपयोग कर रहे हैं, तो इसका मतलब है कि आप एक्सएमएल को क्रमबद्ध कर रहे हैं, न कि आपके नियमित जावा क्रमबद्धरण (लेकिन मार्शलिंग और अनारशलिंग के लिए कुछ अन्य लाइब्रेरी)। तो सवाल में कुछ जानकारी की कमी है।

दूसरे, आप अपने InputStream & पर नियंत्रण है, तो OutputStream ObjectOutputStream और ObjectInputStream विस्तार कोशिश करते हैं और replaceObject() और resolveObject() ओवरराइड और फिर आप java.sql.Date के लिए क्रमांकन लागू कर सकते हैं।

0

दिनांक को क्रमबद्ध/deserialize करने के लिए आपको डिफ़ॉल्ट कन्स्ट्रक्टर (खाली) की आवश्यकता नहीं है (या तो java.sql.Date या java.util.Date)। Deserialization कन्स्ट्रक्टर के दौरान कॉल नहीं किया जाता है, लेकिन ऑब्जेक्ट के गुण सीधे धारावाहिक डेटा से मूल्यों पर सेट करते हैं और आप ऑब्जेक्ट का उपयोग कर सकते हैं क्योंकि यह deserialized है।

6

पहले सुझाए गए दिनांक.getTime() द्वारा लौटाए गए लंबे समय तक सीरियलाइजिंग काम करेगा। हालांकि आपको ध्यान रखना चाहिए कि यदि आपका सर्वर क्लाइंट की तुलना में किसी अन्य समय क्षेत्र में है, तो जिस तारीख को आप दूसरी तरफ पुनर्निर्माण करेंगे, वह अलग होगी। यदि आप सटीक उसी दिनांक वस्तु को पुनर्निर्माण करना चाहते हैं तो आपको अपना समय क्षेत्र (TimeZone.getID()) भी भेजना होगा और दूसरी तरफ की तारीख को पुनर्निर्माण के लिए इसका उपयोग करना होगा।

+1

-1 - लंबा मूल्य जीएमटी है, इसे टाइमज़ोन की आवश्यकता नहीं है। –

+0

यदि आप पेरिस में 2 बजे क्रमबद्ध करते हैं तो आप 8am प्राप्त करेंगे यदि आप एनवाईसी समय क्षेत्र के लिए कॉन्फ़िगर की गई मशीन पर एक ही स्ट्रीम को deserialize करते हैं। यदि आप एक मीटिंग शेड्यूल करना चाहते हैं जो ठीक है क्योंकि आप सभी को एक ही समय में भाग लेना चाहते हैं। लेकिन अगर आपको संविदात्मक जानकारी प्रदर्शित करने की आवश्यकता है (उदा: यह विकल्प पेरिस में 2 बजे समाप्त हो जाता है) तो आपको एनवाईसी कंप्यूटर को पेरिस में 2 बजे और 8 बजे और बीटीडब्ल्यू के बारे में पता लगाने के लिए समय क्षेत्र के साथ भेजने की आवश्यकता है। दोनों स्थितियों के लिए व्यापार के मामले मौजूद हैं, समय क्षेत्र के साथ भेजना हमेशा सुरक्षित है, सिवाय इसके कि यदि आपके पास सख्त बैंडविड्थ बाधाएं हैं। – entzik

0

आप अपने ऑब्जेक्ट्स को क्रमबद्ध करने और deserialise करने के लिए एक एन्कोडर और डीकोड का उपयोग कर सकते हैं।

XMLEncoder encoder = new XMLEncoder(new FileOutputStream(file)); 
encoder.setPersistenceDelegate(
    Rectangle.class, 
    new DefaultPersistenceDelegate(new String[]{"x", "y", "width", "height"})); 
encoder.writeObject(groups); 
encoder.close(); 
1

मैं java.sql.Date के कार्यान्वयन देखा है और के रूप में मैं इसे देखना java.sql.Date विस्तार के रूप में Serializable है:

यहाँ एक उदाहरण है जो SWT आयत वर्ग serialises है java.util.Date का।

8

Joda समय

दिनांक वर्ग किसी बेकार एपीआई है। एक बेहतर कार्यान्वयन Joda-Time है।

आईएसओ 8601

Joda समय भी आप एक ISO 8601 मानक प्रारूप (: MM: SS.SSS yyyy-MM-DDThh) में अपनी तिथि परिवर्तित करने के लिए अनुमति देता है। इस मानक का उपयोग सर्वर से अपने क्लाइंट तक की तारीखों को स्थानांतरित करने के लिए एक पठनीय प्रारूप में पूर्ण तिथि शामिल करने का लाभ होता है। जब आप उदाहरण के लिए JAXB का उपयोग करते हैं, तो तिथि का एक्सएमएल प्रतिनिधित्व भी यह आईएसओ मानक है। (XMLGregorian कैलेंडर श्रेणी देखें)

+3

यह भी ध्यान रखें कि जावा 7 के लिए आगामी जेएसआर 310 दिनांक और समय API आईएसओ 8601 और जोडा समय से अवधारणाओं पर आधारित होगा। तो यह एक अच्छी भविष्य की दिशा है। –

+0

धन्यवाद! खुद को नहीं पता था। अंत में एक बेहतर तिथि कार्यान्वयन। – JeroenWyseur

+0

नए एपीआई के बारे में अच्छा लेख: http://today.java.net/pub/a/today/2008/09/18/jsr-310-new-java-date-time-api.html – JeroenWyseur

3

अपने प्रश्न के पहले भाग का उत्तर देने के लिए, मैं आईएसओ 8601 प्रारूप में एक स्ट्रिंग का सुझाव दूंगा (यह एन्कोडिंग तिथियों के लिए मानक है)।

दूसरे भाग के लिए, मुझे यकीन नहीं है कि आपको प्रॉक्सी क्लास की आवश्यकता क्यों होगी? या आपको इसका समर्थन करने के लिए तिथि वर्ग का विस्तार क्यों करना होगा। जैसे। क्या आपकी वेब सेवा नहीं जानती है कि एक निश्चित फ़ील्ड एक तिथि है और तिथि से लेकर स्ट्रिंग और बैक में रूपांतरण करता है? मुझे थोड़ी अधिक जानकारी चाहिए।

0

java.sql.Date पहले से ही ऐसा कोई जरूरत :-) इसे लागू करने के Serializable लागू करता

जहां तक ​​आपका मुख्य प्रश्न का संबंध है, मैं गहराई से प्यार में JAXB साथ हूँ के रूप में मैं में लगभग किसी भी एक्सएमएल बदल सकते हैं एक वस्तु, तो इसे देखने के लिए आपके समय के लायक हो सकता है।

0

हमम ... किसी भी कारण से नहीं सोच सकता कि किसी भी धारावाहिक ऑब्जेक्ट-इंस्टेंस (डिफ़ॉल्ट जावा तंत्र के माध्यम से क्रमबद्ध) को किसी अन्य वर्ग के उदाहरण के रूप में खुद को deserialize करना चाहिए क्योंकि कक्षा की जानकारी serialized का एक निहित हिस्सा होना चाहिए डेटा।

तो यह या तो आपके (डी-) क्रमबद्धता ढांचे की समस्या है या ढांचा "भेजने के अंत" (कैलेंडर, जावा.यूटिल.डेट इत्यादि) पर किसी भी "दिनांक-जैसी" वस्तु को स्वीकार करता है - इस प्रकार java.sql जैसे ही यह java.util.Date को बढ़ाता है), कुछ सामान्य दिनांक-प्रारूप में एक स्ट्रिंग में "धारावाहिक" करता है (इसलिए प्रकार की जानकारी खो जाती है) और प्राप्तकर्ता अंत में कैलेंडर ऑब्जेक्ट पर इसे "deserializes" कर देती है।

तो मुझे लगता है सबसे आसान तरीका java.sql.Date को पाने के लिए एक

java.sql.Date date = new java.sql.Date(calendar.getTimeInMillis);

जहां एक java.sql.Date की जरूरत है लेकिन ग्रेगोरी कैलेंडर "अक्रमांकन" से वापस मिल करना है।

1

java.sql.Date के साथ एक चेतावनी जो मुझे हाल ही में बताती है कि यह समय भाग (घंटे, मिनट, सेकंड, आदि) को केवल तारीख भाग को संग्रहीत नहीं करता है। यदि आप पूर्ण टाइमस्टैंप चाहते हैं तो आपको java.util.Date या java.sql का उपयोग करना होगा। टिमस्टैम्प

1

मैं जेरोन वाईसुर द्वारा correct answer पर विस्तार करूंगा।

आईएसओ 8601

ISO 8601 मानक प्रारूप पूरी तरह से सबसे अच्छा तरीका है डेटा विनिमय के लिए एक तिथि-समय मूल्य को क्रमानुसार करने है। प्रारूप स्पष्ट है, संस्कृतियों में लोगों के लिए सहज, और दुनिया भर में तेजी से आम है। मनुष्यों और मशीनों दोनों के लिए पढ़ने के लिए आसान है।

2015-01-16T20:15:43+02:00 
2015-01-16T18:15:43Z 

पहला उदाहरण यूटीसी से दो घंटे पहले ऑफसेट है। दूसरा उदाहरण यूटीसी को इंगित करने के लिए Z ("ज़ुलू") का सामान्य उपयोग दिखाता है, +00:00 के लिए छोटा।

Joda समय & java.time

java.util.Date & .Calendar जावा के साथ बंडल कक्षाएं कुख्यात, परेशानी भ्रामक है, और दोषपूर्ण हैं। उनसे बचें। इसके बजाय का उपयोग या तो:

  • Joda-Time पुस्तकालय
  • आईएसओ 8601
  • java.time पैकेज, जावा 8, Joda समय से प्रेरित में निर्मित, JSR द्वारा परिभाषित 310.

डिफ़ॉल्ट रूप से, दोनों पुस्तकालयों का उपयोग दोनों समय-समय पर मूल्यों के स्ट्रिंग प्रस्तुतिकरणों को पार्सिंग और उत्पन्न करने के लिए।

ध्यान दें कि जावा.टाइम proper name of the time zone, 2007-12-03T10:15:30+01:00[Europe/Paris] को जोड़कर आईएसओ 8601 प्रारूप को बढ़ाता है।

इन पुस्तकालयों के लिए अधिक चर्चा और उदाहरण कोड के साथ कई सैकड़ों प्रश्नों और उत्तरों के लिए StackOverflow.com खोजें।

बचें गणना-से-युग

अन्य उत्तर में से कुछ एक नंबर, epoch से गिनती उपयोग करना चाहिये। यह दृष्टिकोण व्यावहारिक नहीं है। यह आत्म-स्पष्ट नहीं है। यह मानव-पठनीय नहीं है, जिससे परेशानी और निराशाजनक डिबगिंग हो रही है।

कौन सा नंबर है, पूरे सेकंड जैसा कि आमतौर पर यूनिक्स में इस्तेमाल किया, java.util.Date & Joda समय में इस्तेमाल किया मिलीसेकेंड, आमतौर पर इस तरह के Postgres के रूप में डेटाबेस में इस्तेमाल माइक्रोसेकंड, या नैनोसेकंड java.time package में प्रयोग किया जाता?

couple dozen epochs में से कौन सा, यूनिक्स में इस्तेमाल 1970 के पहले क्षण, साल 1 में नेट & जाओ इस्तेमाल किया, "जनवरी 0, 1900" 1 जनवरी, 2001 लाखों Excel के (अरबों?) & लोटस स्प्रेडशीट, या में इस्तेमाल किया Cocoa द्वारा उपयोग किया जाता है?

diagram of different resolution of time tracking

अधिक चर्चा के लिए एक समान प्रश्न पर my answer देखें।

संबंधित मुद्दे