Yyyy-gg-MM biçimindeki tarihlerle DateTime. TryParse sorunu


84

"2011-29-01 12:00 am" dize biçiminde aşağıdaki tarihe sahibim. Şimdi bunu aşağıdaki kodla datetime biçimine dönüştürmeye çalışıyorum:

DateTime.TryParse(dateTime, out dt); 

Ama her zaman {1/1/0001 12:00:00 AM} olarak dt alıyorum, lütfen bana nedenini söyler misiniz? ve bu dizeyi tarihe nasıl dönüştürebilirim.

DÜZENLEME: Az önce herkesin format argümanını kullanmaktan bahsettiğini gördüm. Şimdi, format parametresini, kullanıcının istediği özel tarih formatını seçmek için bazı ayarlara sahip olduğumdan ve bu kullanıcıya dayalı olarak, jQuery datepicker aracılığıyla bu formatta metin kutusundaki tarihi otomatik olarak alabildiğinden, kullanamayacağımı belirteceğim.


4
Bu arada, dönüş değerini kontrol ederek dönüşümün başarısız olup olmadığını belirleyebilirsiniz TryParse. Yani bool success = DateTime.TryParse(...);.
Jim Mischel

Yanıtlar:


188

Bu, "2011-29-01 00:00" örneğinize göre çalışmalıdır

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);

8
Beni yen. Girdi dizenizin biçimini biliyorsanız, neredeyse her zaman TryParseExact / ParseExact yöntemlerini kullanmalısınız.
Euro Micelli

tamam, öyleyse benim tarih formatım örnektekine benzer, ancak gün veya ay değeri tek basamaklıysa, DateTime ayrıştırıcısı bir hata atar çünkü yalnızca bir tane olduğunda iki basamak aradı. Bu senaryoda ne önerirsiniz?
Ciaran Gallagher

11
Kendi sorumu cevaplamak için, bu durumda, formatta tek bir karakter kullanırsanız, hem tek hem de çift karakterli tarihler için çalışır. örneğin d / a / yyyy, 13/11/2012 için çalışır
Ciaran Gallagher

@BrokenGlass bu benim için çalışmıyor Lütfen bana yardım eder misin
Meena

2
@CiaranGallagher Sadece küçük bir açıklama, Yorumunuzdaki tarih büyük M (d / M / yyyy) kullanmalıdır
Yusril Maulidan Raji

14

ParseExactYöntemi kullanmanız gerekir . Bu, tarih saatinin içinde bulunduğu biçimi belirten ikinci bağımsız değişkeni olarak bir dizeyi alır, örneğin:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
try
{
   result = DateTime.ParseExact(dateString, format, provider);
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Kullanıcı kullanıcı arayüzünde bir format belirleyebiliyorsa, bunu bu yönteme geçirebileceğiniz bir dizeye çevirmeniz gerekir. Doğrudan biçim dizesi girmesini sağlayan ya bunu yapabilirim - gerçi bu araçları dönüşüm olasılıkları da o kadar başarısız olduğunu olacak geçersiz biçim dizesi girin - ya da açılan kutu sahip olması mümkün seçimler ve sizinle hediyeler onları bu seçenekler için biçim dizelerini ayarlayın.

Girişin yanlış olma ihtimali varsa (örneğin, kullanıcı girişi) TryParseExact, hata durumunu ele almak için istisnalar kullanmak yerine kullanmak daha iyi olacaktır :

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Daha iyi bir alternatif etmek olabilir değil tarih biçimleri seçeneği kullanıcıya sunmak, ama kullanmak formatları bir dizi alır aşırı :

// A list of possible American date formats - swap M and d for European formats
string[] formats= {"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",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

Bir yapılandırma dosyası veya veritabanından olası biçimleri okursanız, insanların tarihleri ​​girmek için istediği tüm farklı yollarla karşılaştığınızda bunlara ekleyebilirsiniz.


5

Güvenli TryParseExact yöntemini kullanmayı deneyin

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);

4

Gönderen DateTime msdn üzerinde:

Tür: System.DateTime% Bu yöntem döndürüldüğünde, dönüştürme başarılı olursa s içinde bulunan tarih ve saate eşdeğer DateTime değerini veya dönüştürme başarısız olursa MinValue değerini içerir . S parametresi null ise, boş bir dizeyse ("") veya tarih ve saatin geçerli bir dize gösterimini içermiyorsa dönüştürme başarısız olur. Bu parametre başlatılmadan geçirilir.

"yyyy-dd-MM hh:mm tt"Bunun yerine biçim dizesiyle parseexact kullanın.


3

Bu çalışır:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);

1
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);

0

Kullanıcıya tarih / saat biçimini değiştirme fırsatı verirseniz, ayrıştırma için kullanmak üzere karşılık gelen bir biçim dizesi oluşturmanız gerekir. Olası tarih formatlarını biliyorsanız (yani kullanıcının bir listeden seçim yapması gerekiyorsa), bu çok daha kolaydır çünkü bu format dizilerini derleme zamanında oluşturabilirsiniz.

Kullanıcının tarih / saat biçiminin serbest biçimli tasarımını yapmasına izin verirseniz DateTime, çalışma zamanında ilgili biçim dizelerini oluşturmanız gerekir .


Doğru, Kullanıcının tarih / saat biçiminin serbest biçimli tasarımını yapmasına izin verirseniz, çalışma zamanında karşılık gelen DateTime biçim dizelerini oluşturmanız gerekir.
Pinal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.