पार्स स्ट्रिंग स्ट्रिंग टू डेटटाइम टू सी #


165

मेरे पास एक स्ट्रिंग की तरह तारीख और समय है:

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

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

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


19
तो आप DateTime.Parse का उपयोग क्यों नहीं करते?
ऑस्टिन सैलूनन

8
मैं पददलितों में से एक था। ऐसा इसलिए था क्योंकि आपके मूल प्रश्न ( stackoverflow.com/revisions/… ) में कहा गया था कि आप DateTime.Parse () का उपयोग करना चाहते थे, लेकिन आपने यह नहीं बताया कि आप इसका उपयोग क्यों नहीं कर सकते। इससे यह एक निरर्थक प्रश्न की तरह प्रतीत होता है, खासकर जब से एक साधारण जाँच ने यह स्पष्ट कर दिया है कि काको की बात सही थी: आपका स्ट्रिंग "2011-03-21 13:26" डेटटाइम के लिए कोई समस्या नहीं है। अंत में, आपने अपने मूल प्रश्न में ParseExact () का कोई उल्लेख नहीं किया। आपने मिच के उत्तर को एक संपादन में जोड़ने के बाद तक इंतजार किया ।
आनन

4
मैं सिर्फ उन लोगों से प्यार करता हूं, जिन्होंने बिना किसी कारण के टिप्पणी में वोटिंग पर सवाल उठाया है।
हूच

जवाबों:


271

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

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

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

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

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

C # प्रारूप स्ट्रिंग के लिए एक और उपयोगी संसाधन स्ट्रिंग # में स्वरूपण स्ट्रिंग है


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

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

1
@ करारा: ISO8601 प्रारूप में तारीखें (यानी yyyy-mm-dd 'की हमेशा सही तरीके से व्याख्या की जाती है। यही कारण है कि हम ISO8601 प्रारूप तिथियों का उपयोग करते हैं ...
मिच गेहूं

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

ParseExact बढ़िया है क्योंकि यह लचीली है, लेकिन इसका नकारात्मक पहलू है: ध्यान दें कि ParseExact और Parse मेथड्स अपवादों को फेंकते हैं यदि चर के दिनांक प्रारूप में एक सिंटैक्स त्रुटि हो s। इसलिए, TryParseExcact का उपयोग करना बेहतर है मैंने नीचे दिए अपने जवाब में बताया है कि क्यों।
मैट

47

जैसा कि मैं बाद में समझा रहा हूं, मैं हमेशा 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)।

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

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

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


समाधान:   .ToDate () विस्तार विधि

इसे .NetFiddle में आज़माएं

public static class Extensions
{
    // Extension method parsing a date string to a DateTime?
    // dateFmt is optional and allows to pass a parsing pattern array
    // or one or more patterns passed as string parameters
    public static DateTime? ToDate(this string dateTimeStr, params 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"});
      // or simpler: 
      // var dt = "2011-03-21 13:26".ToDate("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();
      }
      // Commented out below because it can be done shorter as shown below.
      // For older C# versions (older than C#7) you need it like that:
      // DateTime? result = null;
      // DateTime dt;
      // if (DateTime.TryParseExact(dateTimeStr, dateFmt,
      //    CultureInfo.InvariantCulture, style, out dt)) result = dt;
      // In C#7 and above, we can simply write:
      var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
                   style, out var dt) ? dt : null as DateTime?;
      return result;
    }
}

कोड के बारे में कुछ जानकारी

आप आश्चर्यचकित हो सकते हैं कि मैंने InvariantCultureकॉलिंग का उपयोग क्यों किया है TryParseExact: यह फ़ंक्शन को प्रारूप पैटर्न को हमेशा एक ही तरह से व्यवहार करने के लिए मजबूर करना है (अन्यथा उदाहरण के लिए "" अंग्रेजी में दशमलव विभाजक के रूप में व्याख्या की जा सकती है, जबकि यह एक समूह विभाजक या दिनांक विभाजक है। जर्मन)। याद है कि हमने पहले से ही कुछ पंक्तियों के कल्चर आधारित प्रारूप को पहले से ही उद्धृत कर दिया है ताकि यहाँ ठीक हो।

अद्यतन: .ToDate() (मापदंडों के बिना) अब थ्रेड की वर्तमान संस्कृति के सभी सामान्य तिथि / समय पैटर्न के लिए चूक।
ध्यान दें कि हमें resultऔर dtसाथ की आवश्यकता है , क्योंकि TryParseExactउपयोग करने की अनुमति नहीं है DateTime?, जिसे हम वापस करने का इरादा रखते हैं। में सी # संस्करण 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;

या, अगर आपको यह कम पसंद है:

 // in C#7 only: Declaration of result as a "one-liner" ;-)
 var result = DateTime.TryParseExact(dateTimeStr, dateFmt, CultureInfo.InvariantCulture,
              style, out var dt) ? dt : null as DateTime?;

जिस स्थिति में आपको दो घोषणाओं की आवश्यकता नहीं है DateTime? result = null;और DateTime dt;आप इसे कोड की एक पंक्ति में कर सकते हैं। ( यदि आप चाहें तो out DateTime dtइसके बजाय लिखने की अनुमति दी जाएगी out var dt)।

मैंने paramsकीवर्ड का उपयोग करके कोड को और सरल कर दिया है : अब आपको किसी भी तरह से 2 nd ओवरलोड विधि की आवश्यकता नहीं है ।


उपयोग का उदाहरण

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ताकि आप ठीक से जान सकें कि एक उचित तारीख / समय स्ट्रिंग पारित हो गया है या नहीं।


उपयोग के अधिक उदाहरण

अतिभारित फ़ंक्शन आपको पार्सिंग / परिवर्तित तिथियों के लिए उपयोग किए जाने वाले मान्य स्वरूपों की एक सरणी को पास करने की अनुमति देता है जैसा कि यहां दिखाया गया है ( 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);

यदि आपके पास कुछ टेम्पलेट पैटर्न हैं, तो आप यह भी लिख सकते हैं:

var dateStr = "2011-03-21 13:26";
var dt = dateStr.ToDate("yyyy-MM-dd HH:mm", "M/d/yyyy h:mm:ss tt");

उन्नत उदाहरण हैं

आप ??विफल-सुरक्षित प्रारूप में डिफ़ॉल्ट रूप से ऑपरेटर का उपयोग कर सकते हैं , जैसे

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

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

आप LINQ में एक्सटेंशन का उपयोग भी कर सकते हैं, इसे आज़माएं (यह .NetFiddle ऊपर है):

var patterns=new[] { "dd-MM-yyyy", "dd.MM.yyyy" };
(new[] { "15-01-2019", "15.01.2019" }).Select(s => s.ToDate(patterns)).Dump(); 

जो पैटर्न का उपयोग करके मक्खी पर सरणी में तिथियों को परिवर्तित करेगा और उन्हें कंसोल पर डंप करेगा।


TryParseExact के बारे में कुछ पृष्ठभूमि

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

मैं इस विस्तार विधि में TryParseExact पसंद कर रहा हूं , क्योंकि आप अपवाद से निपटने से बचते हैं - आप अपवादों के बारे में एरिक लिपर्ट के लेख में पढ़ सकते हैं कि आपको पार्स के बजाय ट्रायपार्स का उपयोग क्यों करना चाहिए, मैं उनसे उस विषय के बारे में उद्धरण करता हूं: 2)

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

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

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

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

मेरा मानना .ToDate(strDateFormat)है कि इसका लाभ यह है कि यह सरल और साफ दिखता है - मूल जितना सरल DateTime.Parseहोना चाहिए था - लेकिन यह जांचने की क्षमता के साथ कि रूपांतरण सफल था, और अपवादों को फेंक दिए बिना।


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


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


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

अन्य प्रारूप के तार के लिए इस लिंक को देखें!



4

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

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

2

सरल और सीधा जवाब ->

using System;

namespace DemoApp.App

{
public class TestClassDate
{
    public static DateTime GetDate(string string_date)
    {
        DateTime dateValue;
        if (DateTime.TryParse(string_date, out dateValue))
            Console.WriteLine("Converted '{0}' to {1}.", string_date, dateValue);
        else
            Console.WriteLine("Unable to convert '{0}' to a date.", string_date);
        return dateValue;
    }
    public static void Main()
    {
        string inString = "05/01/2009 06:32:00";
        GetDate(inString);
    }
}
}

/**
 * Output:
 * Converted '05/01/2009 06:32:00' to 5/1/2009 6:32:00 AM.
 * */

अच्छा @ शिवम भारद्वाज, मैंने इसे वैसे ही किया
मुहम्मद इरफान

2

आप XmlConvert.ToDateString का भी उपयोग कर सकते हैं

var dateStr = "2011-03-21 13:26";
var parsedDate = XmlConvert.ToDateTime(dateStr, "yyyy-MM-dd hh:mm");

दिनांक प्रकार निर्दिष्ट करना अच्छा है, कोड है:

var 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


0

निम्नलिखित कोड का प्रयास करें

Month = Date = DateTime.Now.Month.ToString();   
Year = DateTime.Now.Year.ToString(); 
ViewBag.Today = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(Int32.Parse(Month)) + Year;

नमस्ते, स्वागत है, कृपया किसी प्रश्न का उत्तर देते समय स्पष्टीकरण प्रदान करें। बस पोस्टिंग कोड अनुशंसित नहीं है
अली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.