DateTimeOffset से समय क्षेत्र ऑफसेट हटाया जा रहा है। DateTimeOffset शून्य दिनांक ऑफ़सेट sql सर्वर से टाइमज़ोन ऑफ़सेट को हटाना

DateTimeOffset testDateAndTime = नया DateTimeOffset(2008, 5, 1, 8, 6, 32, नया TimeSpan(1, 0, 0)); //स्वच्छ समय और दिनांक testDateAndTime = testDateAndTime.DateTime.Date; var dateTableEntry = db.DatesTable.First(dt => dt.Id == someTestId); dateTableEntry.test= testDateAndTime; db.SaveChangesAsync();

डेटाबेस में परिणाम: 2008-05-01 00:00:00.00000000 -04:00

-4:00 से +00:00 तक कैसे सक्षम करें (सहेजने से पहले कोड से)?

मैने प्रयत्न किया:

सार्वजनिक कार्य SetTimeZoneOffsetToZero(DateTimeOffset dateTimeOffSetObj) ( TimeSpan ZeroOffsetTimeSpan = new TimeSpan(0, 0, 0, 0, 0); return dateTimeOffSetObj.ToOffset(zeroOffsetTimeSpan); )

वह कुछ नहीं करता.

अंतिम लक्ष्य केवल एक तारीख निर्धारित करना है जिसमें कोई समय या समयक्षेत्र ऑफसेट नहीं है। मैं समय को किसी अन्य समय क्षेत्र में परिवर्तित नहीं करना चाहता (अर्थात 00:00:00.0000000 मैं नहीं चाहता कि यह 00:00:00.0000000 समय से 4 घंटे घटाए और 00:00:00.0000000 निर्धारित समय को +00 से ऑफसेट करे :00, मैं बस यही चाहता हूं कि यह ऑफसेट को +00:00 पर सेट करे)। मैं शून्य ऑफसेट के साथ वर्तमान दिनांक चाहता हूँ।

संपादन करना:

यहां वह है जो आप अन्यत्र पेश कर सकते हैं:

DateTimeOffset testDateAndTime = नया DateTimeOffset(2008, 5, 1, 8, 6, 32, नया TimeSpan(1, 0, 0)); testDateAndTime = testDateAndTime.DateTime.Date; //शून्य आउट टाइम भाग testDateAndTime = DateTime.SpecifyKind(testDateAndTime.Date, DateTimeKind.Utc); //"शून्य आउट" ऑफसेट भाग

मुझे यकीन था कि SpecifyKind मेरे dateTimeOffset को SpecifyKind करेगा, जैसे कि समय और टाइमज़ोन ऑफ़सेट दोनों को बदल देगा, लेकिन जब परीक्षण किया गया, तो ऐसा लगता है कि यह केवल टाइमज़ोन ऑफ़सेट को बदलता है, जो कि मैं चाहता हूं। क्या इसमें कोई समस्या है?

1 उत्तर

समस्या का डेटाबेस से कोई लेना-देना नहीं है। यदि आपने ब्रेकप्वाइंट सेट किया है या कहीं आउटपुट पंजीकृत किया है, तो आपको इस कोड के तुरंत बाद ऑफसेट को बाध्य होते हुए देखना चाहिए:

TestDateAndTime = testDateAndTime.DateTime.Date;

आइए इसे तोड़ें:

  • आपने DateTimeOffset 2008-05-01T08:06:32+01:00 से शुरुआत की
  • फिर आपने .DateTime पर कॉल किया, जिसके परिणामस्वरूप DateTimeKind.Unspecified के साथ DateTime मान 2008-05-01T08:06:32 हो गया।
  • फिर आपने .Date पर कॉल किया, जिसके परिणामस्वरूप DateTimeKind.Unspecified के साथ DateTime मान 2008-05-01T00:00:00 हो गया।
  • आप परिणाम testDateAndTime में लौटाते हैं जो DateTimeOffset प्रकार का होता है। यह DateTime से DateTimeOffset में एक अंतर्निहित रूपांतरण का कारण बनता है जो स्थानीय समय क्षेत्र लागू होता है. आपके मामले में, ऐसा प्रतीत होता है कि आपके स्थानीय समयक्षेत्र में इस मान का ऑफसेट -04:00 है, इसलिए परिणामी मान DateTimeOffset 2008-05-01T00:00:00-04:00 है जैसा कि आपने बताया है,

आपने कहा:

अंतिम लक्ष्य केवल एक तारीख निर्धारित करना है जिसमें कोई समय या समयक्षेत्र ऑफसेट नहीं है।

खैर, वर्तमान में कोई मूल C# डेटा प्रकार नहीं है जो बिना समय के केवल एक तारीख है। Corefxlab में System.Time पैकेज में एक शुद्ध दिनांक प्रकार है, लेकिन यह एक विशिष्ट उत्पादन एप्लिकेशन के लिए बिल्कुल तैयार नहीं है। नोडा की टाइम लाइब्रेरी में लोकलडेट है, जिसे आप आज उपयोग कर सकते हैं, लेकिन डेटाबेस में सहेजने से पहले आपको अभी भी मूल प्रकार में कनवर्ट करना होगा। तो इस बीच, आप जो सबसे अच्छा कर सकते हैं वह है:

  • इस फ़ील्ड में दिनांक प्रकार का उपयोग करने के लिए अपना SQL सर्वर बदलें।
  • अपने .NET कोड में, DateTime का समय 00:00:00 और DateTimeKind.Unspecified के साथ उपयोग करें। आपको समय भाग को अनदेखा करना याद रखना होगा (क्योंकि वास्तव में कुछ निश्चित समय क्षेत्रों में स्थानीय मध्यरात्रि के बिना तिथियां होती हैं)।
  • परीक्षण अलर्ट को DateTimeOffset के बजाय DateTime में बदलें।

सामान्य तौर पर, जबकि DateTimeOffset बड़ी संख्या में परिदृश्यों (जैसे टाइमस्टैम्पिंग ईवेंट) के लिए उपयुक्त है, यह केवल दिनांक मानों के लिए उपयुक्त नहीं है।

मैं शून्य ऑफसेट के साथ वर्तमान दिनांक चाहता हूँ।

यदि आप वास्तव में इसे DateTimeOffset की तरह चाहते हैं तो आप यह करेंगे:

TestDateAndTime = नया DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);

हालाँकि, मैं इसके विरुद्ध सलाह देता हूँ। ऐसा करके आप मूल मान की स्थानीय तारीख ले रहे हैं और दावा कर रहे हैं कि यह यूटीसी में है। यदि मूल ऑफसेट शून्य के अलावा कुछ और है, तो यह एक गलत कथन होगा। यह बाद में अन्य त्रुटियों को जन्म देगा क्योंकि आप वास्तव में अपने द्वारा बनाए गए समय की तुलना में एक अलग समय बिंदु (संभवतः एक अलग तारीख के साथ) के बारे में बात कर रहे हैं।

आपके संपादन में पूछे गए अतिरिक्त प्रश्न के संबंध में - DateTimeKind.Utc निर्दिष्ट करने से अंतर्निहित कास्ट का व्यवहार बदल जाता है। स्थानीय समय क्षेत्र का उपयोग करने के बजाय, यूटीसी समय का उपयोग किया जाता है, जिसमें हमेशा शून्य ऑफसेट होता है। परिणाम वही है जो मैंने ऊपर दिया था। मैं अब भी उन्हीं कारणों से इसके विरुद्ध अनुशंसा करता हूं।

आइए 2016-12-31T22:00:00-04:00 से प्रारंभ करने का उदाहरण देखें। आपके दृष्टिकोण के अनुसार आपको डेटाबेस में 2016-12-31T00:00:00+00:00 सहेजना चाहिए। हालाँकि, ये समय के दो अलग-अलग बिंदु हैं। पहला, यूटीसी के लिए सामान्यीकृत, 2017-01-01T02:00:00+00:00 होगा, और दूसरा, दूसरे समय क्षेत्र में परिवर्तित, 2016-12-30T20:00:00-04:00 होगा। कृपया रूपांतरण में तिथियों में परिवर्तन पर ध्यान दें। यह संभवतः वह व्यवहार नहीं है जो आप अपने आवेदन में चाहेंगे।

मानवीय विकल्प ([आपको लिंक देखने के लिए पंजीकरण करना होगा])।

समस्या का सार यह है.. यदि आपने गलती से SQL सर्वर पर 0 की "दिनांक ऑफसेट" के साथ एक डेटाबेस तैनात किया है, तो एक समस्या तब उत्पन्न होती है जब डेटाबेस में TIME प्रकार के साथ एक विशेषता होती है, यानी यह विशेषता 01 पर सेट होती है /01/0001 10:30:00 या दिनांक पंजीकृत खाली 01.01.0001 00:00:00। इस तरह के विवरण दर्ज करते समय, इसे दर्ज नहीं किया जाता है।
इंटरनेट पर वे 2000 की ऑफसेट के साथ एक नया डेटाबेस बनाने का सुझाव देते हैं।
लेकिन मैं वास्तव में एक नया आधार नहीं बनाना चाहता था। और सभी उपयोगकर्ताओं के लिए डेटाबेस का पथ बदलें।
फिर मैंने उस पथ का अनुसरण किया कि यह मान SQL में कहाँ संग्रहीत है। मैंने इसे ढूंढ लिया और इसे 2000 में बदल दिया और सब कुछ ठीक था..
और अब चरण दर चरण कहां परिवर्तन करना है।

सभी उपयोगकर्ताओं को लात मारो.

ध्यान!!!

1. सबसे पहले, 1C टूल का उपयोग करके एक बैकअप प्रतिलिपि बनाएं, अर्थात। इसे *.dt पर अपलोड करें
यह "ऑफ़सेट" बदलने से पहले किया जाना चाहिए
यदि ऐसा नहीं किया जाता है, तो आपके पूरे डेटाबेस में संदर्भ, दस्तावेज़ आदि होंगे।
जहां अपेक्षित है वहां तारीख 02.10.0009 बताई जाएगी
क्या अनुमति नहीं है...
तो आपने *.dt. पर अपलोड कर दिया है

2. SQL सर्वर प्रबंधन स्टूडियो पर जाएँ
सूची में अपना आधार ढूंढें और प्लस चिह्न दबाएँ।
वहां "टेबल्स" फ़ोल्डर ढूंढें और इसे खोलें।
टेबलों का एक गुच्छा खुल जाएगा, सबसे नीचे जाएं, टेबल ढूंढें
_YearOffset, उस पर खड़े हो जाएं और दाएं बटन से "ओपन टेबल" आइटम का चयन करें, चित्र 1 देखें।
मान को 0 से 2000 में बदलें
SQL सर्वर प्रबंधन स्टूडियो बंद करें

3. कॉन्फिगरेटर पर जाएं और पहले से सहेजे गए डेटाबेस को लोड करें।

यदि ऐसा नहीं किया गया तो सभी तिथियां वर्ष 0009 के साथ होंगी।
डेटाबेस लोड होने के बाद... आप 1सी पर जा सकते हैं और सुनिश्चित कर सकते हैं कि तारीखें सामान्य हैं।
नतीजा यह हुआ कि हमने "दिनांक ऑफसेट को 0 से 2000 तक बदल दिया"

कभी-कभी ऐसा होता है कि इस विकल्प का उपयोग किसी न किसी कारण से नहीं किया जा सकता है। फिर एक अधिक कट्टर विकल्प है ([आपको लिंक देखने के लिए पंजीकरण करना होगा]):

के लिए TablesAndFields कर्सर घोषित करें

ऑब्जेक्ट नाम को टेबलनाम के रूप में, कॉलम नाम को कॉलम नाम के रूप में चुनें
Dbo.sysobjects से जैसावस्तुओं
बाईं ओर dbo.syscolumns को object.id = columns.id पर कॉलम के रूप में जोड़ें
जहां object.xtype = "U" और columns.xtype = 61

टेबल्सएंडफ़ील्ड्स खोलें

जबकि @@FETCH_STATUS = 0
आरंभ करें कार्यकारी(" अद्यतन"+ @TableName + "
तय करना " + @कॉलमनाम + " = ""2000- 01- 01 00:00:00" "
कहाँ " + @कॉलमनाम + " > ""3999- 12- 31 23:59:59" "")

इसे तब तक निष्पादित किया जाता है जब तक पिछला फ़ेच सफल नहीं हो जाता।
TablesAndFields से अगला @TableName, @ColumnName में प्राप्त करें
अंत

टेबल्सएंडफ़ील्ड्स बंद करें
डीललोकेटटेबल्सएंडफील्ड्स
जाना

किसी भी हेरफेर से पहले, डेटाबेस की प्रतियां बनाना न भूलें!

समस्या का डेटाबेस से कोई लेना-देना नहीं है। यदि आप ब्रेकप्वाइंट सेट करते हैं या कहीं आउटपुट दर्ज करते हैं, तो आपको इस कोड के तुरंत बाद ऑफसेट को स्नैप होते हुए देखना चाहिए:

TestDateAndTime = testDateAndTime.DateTime.Date;

आइए इसे तोड़ें:

  • आपने DateTimeOffset मान 2008-05-01T08:06:32+01:00 से प्रारंभ किया
  • फिर आपने .DateTime पर कॉल किया, जिसके परिणामस्वरूप DateTimeKind.Unspecified के साथ DateTime 2008-05-01T08:06:32 का मान प्राप्त हुआ।
  • फिर आपने .Date पर कॉल किया, जिसके परिणामस्वरूप DateTimeKind.Unspecified के साथ DateTime मान 2008-05-01T00:00:00 हो गया।
  • आप परिणाम testDateAndTime को निर्दिष्ट करते हैं, जो DateTimeOffset प्रकार का होता है। यह DateTime से DateTimeOffset तक एक अंतर्निहित कास्ट का कारण बनता है - , जो लागू होता है स्थानीयसमय क्षेत्र. आपके मामले में, ऐसा प्रतीत होता है कि आपके स्थानीय समय क्षेत्र में इस मान का ऑफसेट -04:00 है, इसलिए परिणामी मान 2008-05-01T00:00:00-04:00 का DateTimeOffset है जैसा कि आपने बताया है।

आपने कहा:

अंतिम लक्ष्य केवल एक तारीख निर्धारित करना है जिसमें कोई समय या समयक्षेत्र ऑफसेट नहीं है।

खैर, वहाँ है वर्तमान मेंयह मूल C# डेटा प्रकार नहीं है, जो बिना समय के केवल एक दिनांक है। इसमें एक शुद्ध दिनांक प्रकार है सिस्टम समय corefxlab में पैकेज, लेकिन यह अभी तक एक विशिष्ट उत्पादन एप्लिकेशन के लिए बिल्कुल तैयार नहीं है। नोडा टाइम लाइब्रेरी में एक लोकलडेट है जिसे आप आज उपयोग कर सकते हैं, लेकिन डेटाबेस में सहेजने से पहले आपको अभी भी मूल प्रकार में कनवर्ट करना होगा। तो इस बीच, आप जो सबसे अच्छा कर सकते हैं वह है:

  • फ़ील्ड में दिनांक प्रकार का उपयोग करने के लिए अपना SQL सर्वर बदलें।
  • अपने .NET कोड में, DateTime का समय 00:00:00 और DateTimeKind.Unspecified के साथ उपयोग करें। आपको समय भाग को अनदेखा करना याद रखना होगा (क्योंकि वास्तव में कुछ निश्चित समय क्षेत्रों में स्थानीय मध्यरात्रि के बिना तिथियां होती हैं)।
  • टेस्ट प्रॉप को DateTimeOffset के बजाय DateTime में बदलें।

सामान्य तौर पर, जबकि DateTimeOffset बड़ी संख्या में परिदृश्यों (उदाहरण के लिए) के लिए उपयुक्त है टाइम स्टाम्प्सईवेंट), यह केवल दिनांक मानों के लिए उपयुक्त नहीं है।

मैं शून्य ऑफसेट के साथ वर्तमान दिनांक चाहता हूँ।

अगर आप वास्तव में चाहते हैंयह DateTimeOffset जैसा है, आप यह कर सकते हैं:

TestDateAndTime = नया DateTimeOffset(testDateAndTime.Date, TimeSpan.Zero);

हालाँकि, मैं ऐसा करने की अनुशंसा नहीं करता। ऐसा करके आप ले स्थानीयमूल मूल्य की तारीख और दावा करें कि यह यूटीसी में है। यदि मूल ऑफसेट शून्य के अलावा कुछ और है, तो यह एक गलत कथन होगा। यह बाद में अन्य त्रुटियों को जन्म देगा क्योंकि आप वास्तव में अपने द्वारा बनाए गए समय की तुलना में एक अलग समय बिंदु (संभवतः एक अलग तारीख के साथ) के बारे में बात कर रहे हैं।

आपके बोर्ड में पूछे गए अतिरिक्त प्रश्न के संबंध में। DateTimeKind.Utc निर्दिष्ट करने से अंतर्निहित कास्ट का व्यवहार बदल जाता है। स्थानीय समय क्षेत्र का उपयोग करने के बजाय, यूटीसी समय का उपयोग किया जाता है, जिसमें हमेशा शून्य ऑफसेट होता है। परिणाम वही है जो मैंने ऊपर दिया था। मैं अब भी उन्हीं कारणों से इसके विरुद्ध अनुशंसा करता हूं।

2016-12-31T22:00:00-04:00 से शुरू होने वाले एक उदाहरण पर विचार करें। आपके दृष्टिकोण के अनुसार आपको डेटाबेस में 2016-12-31T00:00:00+00:00 सहेजना चाहिए। हालाँकि, ये समय के दो अलग-अलग बिंदु हैं। पहला, यूटीसी के लिए सामान्यीकृत, 2017-01-01T02:00:00+00:00 होगा, और दूसरा, दूसरे समय क्षेत्र में परिवर्तित, 2016-12-30T20:00:00-04:00 होगा। कृपया रूपांतरण में तिथियों में परिवर्तन पर ध्यान दें। यह संभवतः वह व्यवहार नहीं है जो आप अपने आवेदन में चाहेंगे।

विषय पर प्रकाशन