LANGUAGE और DATEFORMAT कौन से दिनांक / समय शाब्दिक प्रारूप सुरक्षित हैं?


24

यह प्रदर्शित करने के लिए है कि कई दिनांक / समय प्रारूपों के लिए आसान है अन्य की तुलना में निम्न दो सेट भाषा, सेट DateFormat, या एक लॉगिन की डिफ़ॉल्ट भाषा के कारण अशुद्ध अर्थ की चपेट में हैं:

yyyyMMdd                 -- unseparated, date only
yyyy-MM-ddThh:mm:ss.fff  -- date dash separated, date/time separated by T 

यहां तक ​​कि यह प्रारूप, टी के बिना, एक मान्य आईएसओ 8601 प्रारूप की तरह लग सकता है , लेकिन यह कई भाषाओं में विफल रहता है:

DECLARE @d varchar(32) = '2017-03-13 23:22:21.020';

SET LANGUAGE Deutsch;
SELECT CONVERT(datetime, @d);

SET LANGUAGE Français;
SELECT CONVERT(datetime, @d);

परिणाम:

डाइ स्प्राकेनस्टेलुंग वुर्ड औफ डिक्शन ग्रैन्डर्ट।

एमएसजी 242, लेवल 16, स्टेट 3
बीई डेर कोनवर्टेरियंग ईनिन डेटाइम-डाटेंटिप लेगट डेर वर्ट एयूएर्हल्ब डेस गुएटलजेन बेरेइच्स में वर्च-डेंटेंटिप्स को खाती है।

ले परमैत्रे डे लैंगुए इस्ट पास ए फ्रेंक।

Msg 242, स्तर 16, राज्य 3
ला रूपांतरण d'un प्रकार de données varchar en type de données datetime a créé valeur hors limites।

अब, ये विफल हो जाते हैं, जैसे कि, अंग्रेजी में, मैंने महीने और दिन का ट्रांसपोज किया था, दिनांक घटक तैयार करने के लिए yyyy-dd-mm:

DECLARE @d varchar(32) = '2017-13-03 23:22:21.020';

SET LANGUAGE us_english;
SELECT CONVERT(datetime, @d);

परिणाम:

Msg 242, Level 16, State 3
एक varchar डेटा टाइप को डेटाइम टाइम टाइप करने के लिए आउट-ऑफ-रेंज मान दिया गया।

(यह माइक्रोसॉफ्ट एक्सेस नहीं है, जो आपके लिए "अच्छा" है और आपके लिए ट्रांसपोज़ेशन को ठीक करता है। इसके अलावा, कुछ मामलों में इसी तरह की त्रुटियां हो सकती हैं SET DATEFORMAT ydm;- यह सिर्फ एक भाषा की बात नहीं है, यह सिर्फ और अधिक सामान्य परिदृश्य है जहां ये हैं ब्रेक्जिट होता है - और हमेशा ध्यान नहीं दिया जाता है क्योंकि कभी-कभी वे त्रुटियां नहीं होती हैं, यह सिर्फ इतना है कि 7 अगस्त 8 जुलाई बन गया और किसी ने भी नहीं देखा।)

तो, सवाल:

अब जब मुझे पता है कि असुरक्षित प्रारूपों का एक समूह है, तो क्या कोई अन्य प्रारूप हैं जो किसी भी भाषा और डेटफ़ॉर्मैट संयोजन के लिए सुरक्षित होंगे?

जवाबों:


26

में प्रलेखन , यह बहुत स्पष्ट रूप से कहा गया है कि केवल सुरक्षित प्रारूपों उनके जो मेरे सवाल का बहुत शुरुआत में प्रदर्शित कर रहे हैं:

yyyyMMdd                 -- unseparated, date only
yyyy-MM-ddThh:mm:ss.fff  -- date dash separated, date/time separated by T 

हालाँकि, यह हाल ही में मेरे ध्यान में लाया गया था कि एक तीसरा प्रारूप है जो किसी भी भाषा या डेटफ़ॉर्मेट सेटिंग्स के लिए समान रूप से प्रतिरक्षा है:

yyyyMMdd hh:mm:ss.fff    -- unseparated date, no T separator

टीएल; डीआर: यह सच है। के लिए datetimeऔर smalldatetime

लंबे संस्करण के लिए आगे पढ़ें, और जितना प्रमाण आप प्राप्त करने जा रहे हैं, उतना ही।


एक लूपहोल है जो इसे समझाता है - जबकि मुख्य पाठ निकाय yyyyMMdd hh:...ट्रांसपोज़्ड भाषा या दिनांक प्रारूप व्याख्याओं से सुरक्षित एक प्रारूप के रूप में स्वीकार करने में विफल रहता है , थोड़ा धुंधला है जो कहता है कि इस तरह के स्ट्रिंग के तारीख वाले भाग को तारीख सेटिंग्स के आधार पर मान्य नहीं किया गया है:

यहाँ छवि विवरण दर्ज करें

यह आमतौर पर मेरे विपरीत है, बस इसके शब्द पर प्रलेखन लेने के लिए, आमतौर पर। आप कह सकते हैं कि मुझे थोड़ा संदेह है। और भाषा यहां अस्पष्ट है, भी - यह सिर्फ यह बताता है कि यह तारीख और समय के संयोजन के बारे में है, अंतरिक्ष को स्पष्ट रूप से नहीं बुला रहा है (यह एक गाड़ी वापसी हो सकती है, सभी के लिए मुझे पता है)। यह भी कहता है कि यह बहु-भाषा नहीं है, जिसका अर्थ है कि यह कुछ विशेष भाषाओं में विफल हो सकता है, लेकिन हम जल्द ही पता लगा लेंगे कि यह गलत भी है।

इसलिए मैंने यह साबित करने के लिए यह निर्धारित किया कि भाषा / डेटफॉर्मेट का कोई भी संयोजन इस विशिष्ट प्रारूप को विफल नहीं कर सकता।

सबसे पहले, मैंने प्रत्येक भाषा के लिए डायनेमिक SQL का थोड़ा ब्लॉक बनाया:

EXEC sys.sp_executesql @sql, N'@lang sysname', N'us_english';

इसने आउटपुट की 34 पंक्तियों को इस तरह उत्पादित किया:

EXEC sys.sp_executesql @sql, N'@lang sysname', N'us_english';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'Deutsch';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'Français';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'日本語';
...
EXEC sys.sp_executesql @sql, N'@lang sysname', N'简体中文';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'Arabic';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'ไทย';
EXEC sys.sp_executesql @sql, N'@lang sysname', N'norsk (bokmål)';    

मैंने उस आउटपुट को एक नई क्वेरी विंडो में कॉपी किया, और उसके ऊपर, मैंने यह कोड बनाया, जो उम्मीद करता था कि उसी महीने (13 मार्च को) को कम से कम एक मामले में 13 वें महीने के तीसरे दिन में बदलने की कोशिश करेंगे:

DECLARE @sql nvarchar(max) = N'
SET LANGUAGE @lang;
SET DATEFORMAT ydm;
SELECT @@LANGUAGE, CONVERT(datetime, ''20170313 23:22:21.020'');';

नहींं, हर भाषा ने सिर्फ खोजने का काम किया ydm। मैंने हर दूसरे प्रारूप को भी आजमाया, और हर तारीख / समय डेटा प्रकार को भी। 34 सफल रूपांतरण 13 मार्च को, हर बार।

इसलिए, मैं @AndriyM और @EricE को मानता हूं कि, वास्तव में, तीसरा सुरक्षित प्रारूप है। मैं भविष्य के पदों के लिए इसे ध्यान में रखूंगा, लेकिन मैंने कई स्थानों पर अन्य दो के बारे में ढोल पीटा है, मैं उन सभी का शिकार नहीं करने जा रहा हूं और उन्हें अब ठीक करूंगा।


विस्तार से, आपको लगता है कि यह सुरक्षित होगा, लेकिन नहीं:

yyyyMMddThh:mm:ss.fff    -- unseparated date, T separator

मुझे लगता है कि हर भाषा में, इस के बराबर होगा:

Msg 241, स्तर 16, राज्य 1, पंक्ति 8
रूपांतरण दिनांक और / या वर्ण स्ट्रिंग से समय परिवर्तित करते समय विफल रहा।


पूर्णता के लिए, वहाँ एक चौथी सुरक्षित प्रारूप है, लेकिन यह नए दिनांक / समय प्रकारों में रूपांतरण के लिए केवल सुरक्षित है ( date, datetime2, datetimeoffset)। इन मामलों में भाषा सेटिंग्स हस्तक्षेप नहीं कर सकती हैं:

yyyy-MM-dd hh:mm:...

हालांकि, मैं इसके उपयोग के खिलाफ अत्यधिक सलाह देता हूं क्योंकि यह केवल नए प्रकारों के लिए काम करता है, और पुराने लोग अभी भी मेरे अनुभव में बड़े पैमाने पर उपयोग करते हैं। जब हर जगह बाकी (या वास्तव में उसी कोड में, यदि डेटा प्रकार बदलता है) तो आपको उन्हें क्यों निकालना होगा?

SET LANGUAGE Deutsch;
DECLARE @dashes char(10) = '2017-03-07 03:34';
DECLARE @d date = @dashes, @dt datetime = @dashes, @dt2 datetime2 = @dashes;

SELECT DATENAME(MONTH,@d), DATENAME(MONTH,@dt), DATENAME(MONTH,@dt2);

यहां तक ​​कि समान स्रोत स्ट्रिंग दिए जाने पर , रूपांतरणों में काफी भिन्न परिणाम मिले:

März    Juli    März

प्रारूप जो डेटाइम ( yyyyMMdd) के लिए काम करता है, वह हमेशा दिनांक और अन्य नए प्रकारों के लिए भी काम करेगा । तो, IMHO, बस हमेशा उस का उपयोग करें। और तारीख / समय ( yyyyMMdd hh:...) के साथ प्रकारों के लिए तीसरा प्रारूप दिया गया है , यह वास्तव में आपको अधिक सुसंगत बनाने की अनुमति देगा - भले ही दिनांक घटक हमेशा थोड़ा कम पठनीय हो।


अब मुझे तारीखों के स्ट्रिंग प्रतिनिधित्व के बारे में बात करने में तीन सुरक्षित स्वरूपों को प्रदर्शित करने की आदत डालने में मुझे बस कुछ साल लगेंगे, देना या लेना होगा ।


यह कि तीसरे प्रारूप नहीं हो सकता है बन असुरक्षित जब एक नई भाषा कुछ भविष्य के रिलीज में एसक्यूएल सर्वर से जोड़ा जाता है?
कुबा व्यारोसेक

@ कूबा मुझे पूरा विश्वास है कि Microsoft ने इस बारे में अपना सबक जान लिया है। किसी ने बहुत ही घटिया निर्णय लिया, इन सभी भाषाओं में yyyy-dd-MM की व्याख्या की गई है, ऐसा प्रारूप जो मुझे नहीं लगता कि पृथ्वी पर किसी ने कभी भी उपयोग किया है।
हारून बर्ट्रेंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.