2011-03-20 22 views
109

मैं दिनांक और समय एक स्ट्रिंग में तरह स्वरूपित किया है कि एक:पार्स स्ट्रिंग

"2011-03-21 13:26" //year-month-day hour:minute 

मैं इसे कैसे System.DateTime को पार्स कर सकते हैं?

यदि संभव हो तो DateTime.Parse() या DateTime.ParseExact() जैसे कार्यों का उपयोग करना चाहते हैं, मैन्युअल रूप से दिनांक के प्रारूप को निर्दिष्ट करने में सक्षम होने के लिए।

+17

तो क्यों आप DateTime.Parse का उपयोग नहीं करते पर

अधिक जानकारी? –

+7

मैं डाउनवॉटर में से एक था। ऐसा इसलिए था क्योंकि आपका मूल प्रश्न (http://stackoverflow.com/revisions/3c6789f2-8a6b-4557-bafc-1b8eb4d5f8c4/view-source) ने कहा था कि आप डेटटाइम का उपयोग करना चाहते हैं। पर्स() लेकिन आपने यह नहीं बताया कि आप क्यों इसका इस्तेमाल नहीं कर सका इसने इसे बकवास प्रश्न की तरह प्रतीत किया, खासकर जब से एक साधारण चेक ने यह स्पष्ट कर दिया होगा कि कैकोइस सही था: आपकी स्ट्रिंग "2011-03-21 13:26" डेटटाइम के लिए कोई समस्या नहीं है। पर्स()। अंत में, आपने अपने मूल प्रश्न में ParseExact() का कोई उल्लेख नहीं किया है। * संपादन के बाद * मिच के जवाब के बाद * आप प्रतीक्षा कर रहे थे। – anon

+1

मैं सिर्फ उन लोगों से प्यार करता हूं जो टिप्पणी में कोई कारण बताए बिना कम-से-कम प्रश्न पूछते हैं। – Hooch

उत्तर

183

DateTime.Parse() दिए गए दिनांक के प्रारूप को समझने का प्रयास करेगा, और यह आमतौर पर एक अच्छी नौकरी करता है। आप हमेशा किसी दिए गए प्रारूप में होगा दिनांकों गारंटी ले सकते हैं तो आप ParseExact() उपयोग कर सकते हैं:

string s = "2011-03-21 13:26"; 

DateTime dt = 
    DateTime.ParseExact(s, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture); 

(लेकिन ध्यान दें कि यह मामले में TryParse एक विधि का उपयोग करने के लिए आम तौर पर सुरक्षित है एक तारीख की उम्मीद स्वरूप में नहीं है)

प्रारूप स्ट्रिंग का निर्माण करते समय Custom Date and Time Format Strings जांचना सुनिश्चित करें, विशेष रूप से अक्षरों और मामले (यानी "एमएम" और "मिमी" का अर्थ बहुत अलग चीजों पर ध्यान देना)।

सी # प्रारूप तार के लिए एक और उपयोगी संसाधन String Formatting in C#

+3

सुधार - यह हमेशा सुरक्षित है;) यदि आप अपवाद के साथ एक विधि को बुला रहे हैं, तो हमेशा संभव होने पर अपवाद स्थिति को पहले जांचें। – Gusdor

+2

मैं कहूंगा कि हमेशा अपनी संस्कृति को पार करना सुरक्षित है। मुझे "01-02-2013" को जनवरी के पहले या फरवरी के पहले के रूप में गलत व्याख्या करने के बजाय अपवाद होना चाहिए। – Carra

+1

@ कररा: आईएसओ 8601 प्रारूप में दिनांक (यानी yyyy-mm-dd 'हमेशा सही तरीके से व्याख्या की जाती है। यही कारण है कि हम ISO8601 प्रारूप दिनांकों का उपयोग करते हैं ... –

9
var dateStr = @"2011-03-21 13:26"; 
var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture); 

चेक बाहर अन्य प्रारूप स्ट्रिंग्स के लिए इस link है!

+1

एचएच = घंटे, एसएस = सेकेंड .... –

3

इस तरह कोड के साथ एक नेट दिनांक समय में एक मानव पठनीय स्ट्रिंग के मूल्य रखो:

DateTime.ParseExact("April 16, 2011 4:27 pm", "MMMM d, yyyy h:mm tt", null); 
32

मैं बाद में समझा रहा हूँ के रूप में, मैं हमेशा TryParse और TryParseExact तरीकों एहसान होगा। क्योंकि वे एक सा उपयोग करने के लिए भारी होते हैं, मैं एक विस्तार विधि जो बहुत आसान पार्स करने बनाता लिखा है:

var dtStr = "2011-03-21 13:26"; 
DateTime? dt = dtStr.toDate("yyyy-MM-dd HH:mm"); 

Parse के विपरीत, ParseExact आदि यह एक अपवाद फेंक नहीं है, और आप

के माध्यम से जांच करने के लिए अनुमति देता है

if (dt.HasValue) { // continue processing } else { // do error handling }

कि क्या रूपांतरण सफल रहा था या नहीं (इस मामले dt में आप dt.Value के माध्यम से उपयोग कर सकते हैं एक मूल्य है) (इस मामले में, यह null है)।

कि यहां तक ​​कि उदाहरण के लिए, "एल्विस" -operator ?. की तरह सुंदर शॉर्टकट का उपयोग करने की अनुमति देता है:

int? year = dtStr?.toDate("yyyy-MM-dd HH:mm")?.Year; 

यहाँ आप भी अगर रूपांतरण सफल जाँच करने के लिए year.HasValue उपयोग कर सकते हैं, और अगर यह तो सफल नहीं हो सका year में null, अन्यथा तिथि का वर्ष हिस्सा होगा। रूपांतरण विफल होने पर कोई अपवाद नहीं फेंक दिया गया है।

Try it in .NetFiddle

public static class Extensions 
{ 
    public static DateTime? toDate(this string dateTimeStr, string[] dateFmt) 
    { 
     // example: var dt = "2011-03-21 13:26".toDate(new string[]{"yyyy-MM-dd HH:mm", 
     //             "M/d/yyyy h:mm:ss tt"}); 
     const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces; 
     if (dateFmt == null) 
     { 
     var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat; 
     dateFmt=dateInfo.GetAllDateTimePatterns(); 
     } 
     DateTime? result = null; 
     DateTime dt; 
     if (DateTime.TryParseExact(dateTimeStr, dateFmt, 
     CultureInfo.InvariantCulture, style, out dt)) result = dt; 
     return result; 
    } 

    public static DateTime? toDate(this string dateTimeStr, string dateFmt=null) 
    { 
     // example: var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm"); 
     // or simply var dt="2011-03-21 13:26".toDate();   
     // call overloaded function with string array param 
     string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt }; 
     return toDate(dateTimeStr, dateFmtArr); 
    } 
} 

अद्यतन:.toDate() (पैरामीटर के बिना) अब धागा की वर्तमान संस्कृति के सभी आम दिनांक/समय पैटर्न के लिए चूक।
नोट कि हम result और dt एक साथ की जरूरत है, क्योंकि TryParseExactDateTime? है, जो हम वापसी करने का इरादा उपयोग करने के लिए अनुमति नहीं है। सी में # संस्करण 7 इस प्रकार आप toDate समारोह थोड़ा आसान बनाने में कर सकते हैं:

// in C#7 only: "DateTime dt;" - no longer required, declare implicitly 
if (DateTime.TryParseExact(dateTimeStr, dateFmt, 
    CultureInfo.InvariantCulture, style, out var dt)) result = dt; 

(यह भी out DateTime dt बजाय out var dt लिखने के लिए अनुमति दी जाएगी।)

उदाहरण:

var dtStr="2011-03-21 13:26";  
var dt=dtStr.toDate("yyyy-MM-dd HH:mm"); 
if (dt.HasValue) 
{ 
    Console.WriteLine("Successful!"); 
    // ... dt.Value now contains the converted DateTime ... 
} 
else 
{ 
    Console.WriteLine("Invalid date format!"); 
} 

जैसा कि आप देख सकते हैं, यह उदाहरण सिर्फ dt.HasValue से पूछताछ करता है कि रूपांतरण क्या है या नहीं सफल था या नहीं। अतिरिक्त बोनस के रूप में, TryParseExact सख्त DateTimeStyles निर्दिष्ट करने की अनुमति देता है ताकि आपको पता चले कि उचित दिनांक/समय स्ट्रिंग पास हो गई है या नहीं।


एनबी। ओवरलोडेड फ़ंक्शन आपको मान्य प्रारूपों की सरणी को here दिखाए गए दिनांकों के रूप में के रूप में उपयोग करने की अनुमति देता है (TryParseExact सीधे इसका समर्थन करता है), उदा।

string[] dateFmt = {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
        "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
        "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
        "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
        "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm"}; 
var dtStr="5/1/2009 6:32 PM"; 
var dt=dtStr.toDate(dateFmt); 

हालांकि, ताकि कोड कम रखने के लिए, मैं सिर्फ TryParseExact की स्ट्रिंग सरणी अधिभार का उपयोग कर रहा है, क्योंकि यह एक सामान्य पैरामीटर के साथ काम नहीं किया।

उन्नत उदाहरण:
आप एक असफल-सुरक्षित प्रारूप, जैसे डिफ़ॉल्ट ?? ऑपरेटर का उपयोग कर सकते हैं

var dtStr = "2017-12-30 11:37:00"; 
var dt = (dtStr.toDate()) ?? dtStr.toDate("yyyy-MM-dd HH:mm:ss"); 

इस मामले में, .toDate() आम स्थानीय संस्कृति तिथि प्रारूप का प्रयोग करेंगे, और यदि इन सभी में विफल रहा है, यह एक fallback के रूप में ISO standard प्रारूप "yyyy-MM-dd HH:mm:ss" उपयोग करने के लिए कोशिश करेंगे। इस तरह, एक्सटेंशन फ़ंक्शन आसानी से विभिन्न फ़ॉलबैक स्वरूपों को "चेन" करने की अनुमति देता है।


अंत में, पृष्ठभूमि के बारे में कुछ टिप्पणियां यहां दी गई हैं (यानी।कारण है कि मैं इसे इस तरह से लिखा है):

मैं इस विस्तार विधि में TryParseExact पसंद करते हैं रहा हूँ, क्योंकि आप से बचने के अपवाद हैंडलिंग - आप read in Eric Lippert's article about exceptions तुम क्यों नहीं बल्कि पार्स से TryParse का उपयोग करना चाहिए, मैं उसके बारे में बोली कर सकते हैं उस विषय: 2)

यह दुर्भाग्यपूर्ण डिज़ाइन निर्णय1) [एनोटेशन: को पार्स विधि एक अपवाद फेंक देना] निश्चित रूप से कि इतने अप्रिय था फ्रेमवर्क टीम ने जल्द ही को सही तरीके से ट्राईपर्स लागू किया जो सही काम करता है।

यह करता है, लेकिन TryParse और TryParseExact दोनों अभी भी उपयोग करने के लिए एक बहुत आरामदायक की तुलना में कम कर रहे हैं: वे आप एक out पैरामीटर जो व्यर्थ नहीं होना चाहिए और जब तक आप बदल रहे आप की जरूरत के रूप में एक गैर-आरंभिकृत चर का उपयोग करने के लिए मजबूर बुलियन रिटर्न वैल्यू का मूल्यांकन करें - या तो आपको तुरंत if कथन का उपयोग करना होगा या आपको अतिरिक्त बूलियन वैरिएबल में रिटर्न वैल्यू स्टोर करना होगा ताकि आप बाद में चेक कर सकें। और आप यह जानने के बिना लक्षित चर का उपयोग नहीं कर सकते कि रूपांतरण सफल था या नहीं।

ज्यादातर मामलों तुम सिर्फ जानना आवश्यक है कि रूपांतरण सफल है या नहीं (और निश्चित मूल्य अगर यह सफल रहा था की) था चाहते हैं, तो एक नल लक्ष्य चर रहता है जो सभी जानकारी वांछनीय और भी बहुत कुछ होगा अधिक सुरुचिपूर्ण - क्योंकि पूरी जानकारी सिर्फ एक ही स्थान पर संग्रहीत है: यह लगातार और उपयोग करने में आसान है, और बहुत कम त्रुटि-प्रवण है।

मैंने जो विस्तार विधि लिखा है वह ठीक है (यह आपको यह भी दिखाता है कि यदि आप इसका उपयोग नहीं करेंगे तो आपको हर बार किस प्रकार का कोड लिखना होगा)।

मेरा मानना ​​है कि .toDate(strDateFormat) का लाभ यह है कि यह आसान और साफ दिखता है - के रूप में सरल रूप में मूल DateTime.Parse होना चाहिए था - लेकिन अगर रूपांतरण सफल रहा था की जाँच करने की क्षमता के साथ, और अपवाद फेंकने के बिना। जो आवश्यक है जब आप पार्स का उपयोग कर रहे हैं क्योंकि यह एक अपवाद है, तो अवैध स्ट्रिंग पार्स किया गया है फेंक देंगे -


1) यहाँ क्या अर्थ होता है कि अपवाद हैंडलिंग (यानी एक try { ... } catch(Exception ex) { ...} ब्लॉक) है - इस मामले में केवल अनावश्यक नहीं है बल्कि यह भी परेशान है, और आपके कोड को जटिल बना रहा है। TryParse यह सब से बचाता है क्योंकि मैंने प्रदान किया गया कोड नमूना दिखा रहा है।


2) एरिक Lippert एक प्रसिद्ध StackOverflow fellow है और कुछ साल के लिए सी # संकलक टीम पर प्रिंसिपल डेवलपर के रूप में माइक्रोसॉफ्ट पर काम कर रहा था।

1

तुम भी XmlConvert.ToDateString

वर dateStr उपयोग कर सकते हैं = "2011-03-21 13:26"; var parsedDate = XmlConvert।ToDateTime (dateStr, "yyyy-MM-dd hh: mm");

यह तिथि तरह,

वर anotherParsedDate = DateTime.ParseExact की तरह निर्दिष्ट करने के लिए अच्छा है (dateStr "yyyy-MM-dd hh: mm",, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); विभिन्न पार्स विकल्पों http://amir-shenodua.blogspot.ie/2017/06/datetime-parsing-in-net.html

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