Konwertowanie ciągu na DateTime

590

Jak przekonwertować ciąg taki jak 2009-05-08 14:40:52,531na DateTime?

cramopy
źródło
2
@dban Dlaczego odpowiedź @CMSnie oznaczona jako odpowiedź? Może istnieć powód - jestem ciekawy.
nam
5
@nam Użytkownik usunął swoje konto lub został zbanowany, nie może na niego kliknąć ani zobaczyć reputacji / medali. Niestety wszystko, co możemy zrobić, to dać mu kciuki do góry.
YumeYume

Odpowiedzi:

753

Ponieważ masz do czynienia z czasem 24-godzinnym i masz przecinek oddzielający ułamek sekund, zalecamy określenie niestandardowego formatu:

DateTime myDate = DateTime.ParseExact("2009-05-08 14:40:52,531", "yyyy-MM-dd HH:mm:ss,fff",
                                       System.Globalization.CultureInfo.InvariantCulture);
CMS
źródło
4
Dobre oczy Nie widziałem przecinka w OP.
lc.
(Myślę, że chciałeś użyć przecinka w ciągach daty i formatu, prawda?)
lc.
1
Jest to tylko przecinek ze względu na ustawienie OPS European Locale, co jeśli przeniesiesz ten kod na inny serwer z US.Locale, wówczas ułamki sekcji będą przecinkiem, a nie przecinkiem na zapisanym ciągu, a twoje rozwiązanie złamać. Przed zastosowaniem prawidłowego analizatora składni należy dodać sprawdzanie typu przychodzącego ciągu datetime dla jego poprawnych ustawień regionalnych. Dziwię się, że Microsoft nie ma jeszcze tego kodu w innym miejscu w CLR lub C # .net
hamish
nie można przekonwertować tego na ciąg znaków daty MyString = "06/22/1916 3:20:14 PM";
Vinod Kumar
24-godzinny czas i przecinek jako separator dziesiętny nie są niestandardowymi ustawieniami narodowymi. Z tym nie trzeba się specjalnie obchodzić.
jpaugh
248

Masz w zasadzie dwie opcje. DateTime.Parse()a DateTime.ParseExact().

Pierwszy jest bardzo wybaczający pod względem składni i analizuje daty w wielu różnych formatach. Jest dobry do wprowadzania danych przez użytkownika, które mogą występować w różnych formatach.

ParseExact pozwoli ci określić dokładny format ciągu daty, który będzie używany podczas analizowania. Dobrze jest użyć tego, jeśli ciąg znaków ma zawsze ten sam format. W ten sposób można łatwo wykryć wszelkie odchylenia od oczekiwanych danych.

Możesz przeanalizować dane wejściowe użytkownika w następujący sposób:

DateTime enteredDate = DateTime.Parse(enteredString);

Jeśli masz określony format ciągu, powinieneś użyć innej metody:

DateTime loadedDate = DateTime.ParseExact(loadedString, "d", null);

"d"oznacza wzorzec krótkiej daty ( więcej informacji w MSDN) ) i nullokreśla, że ​​do parsowania łańcucha należy użyć bieżącej kultury.

Szlifierka
źródło
137

Spróbuj tego

DateTime myDate = DateTime.Parse(dateString);

lepszym sposobem byłoby:

DateTime myDate;
if (!DateTime.TryParse(dateString, out myDate))
{
    // handle parse failure
}
gehsekky
źródło
33

Użyj DateTime.Parse(string):

DateTime dateTime = DateTime.Parse(dateTimeStr);
Amir Touitou
źródło
26

Wydaje się, że nikt nie wdrożył metody rozszerzenia. Za pomocą odpowiedzi @ CMS :

Działający i ulepszony przykład pełnego źródła znajduje się tutaj: Gist Link

namespace ExtensionMethods {
    using System;
    using System.Globalization;

    public static class DateTimeExtensions {
        public static DateTime ToDateTime(this string s, 
                  string format = "ddMMyyyy", string cultureString = "tr-TR") {
            try {
                var r = DateTime.ParseExact(
                    s: s,
                    format: format,
                    provider: CultureInfo.GetCultureInfo(cultureString));
                return r;
            } catch (FormatException) {
                throw;
            } catch (CultureNotFoundException) {
                throw; // Given Culture is not supported culture
            }
        }

        public static DateTime ToDateTime(this string s, 
                    string format, CultureInfo culture) {
            try {
                var r = DateTime.ParseExact(s: s, format: format, 
                                        provider: culture);
                return r;
            } catch (FormatException) {
                throw;
            } catch (CultureNotFoundException) {
                throw; // Given Culture is not supported culture
            }

        }

    }
}

namespace SO {
    using ExtensionMethods;
    using System;
    using System.Globalization;

    class Program {
        static void Main(string[] args) {
            var mydate = "29021996";
            var date = mydate.ToDateTime(format: "ddMMyyyy"); // {29.02.1996 00:00:00}

            mydate = "2016 3";
            date = mydate.ToDateTime("yyyy M"); // {01.03.2016 00:00:00}

            mydate = "2016 12";
            date = mydate.ToDateTime("yyyy d"); // {12.01.2016 00:00:00}

            mydate = "2016/31/05 13:33";
            date = mydate.ToDateTime("yyyy/d/M HH:mm"); // {31.05.2016 13:33:00}

            mydate = "2016/31 Ocak";
            date = mydate.ToDateTime("yyyy/d MMMM"); // {31.01.2016 00:00:00}

            mydate = "2016/31 January";
            date = mydate.ToDateTime("yyyy/d MMMM", cultureString: "en-US"); 
            // {31.01.2016 00:00:00}

            mydate = "11/شعبان/1437";
            date = mydate.ToDateTime(
                culture: CultureInfo.GetCultureInfo("ar-SA"),
                format: "dd/MMMM/yyyy"); 
         // Weird :) I supposed dd/yyyy/MMMM but that did not work !?$^&*

            System.Diagnostics.Debug.Assert(
               date.Equals(new DateTime(year: 2016, month: 5, day: 18)));
        }
    }
}
guneysus
źródło
Nobody seems to implemented an extension methodmoże dlatego, że nie potrzebne ...
Yousha Aleayoub,
Czasami standardowa biblioteka nie odpowiada naszym potrzebom. I właśnie dlatego potrzebujesz / korzystaj z bibliotek pomocniczych. Używając metody rozszerzenia lub płynnego interfejsu API, preferujesz FP zamiast OOP lub odwrotnie. Ani poprawne, ani złe. To jest wybór. @YoushaAleayoub
guneysus
23

Próbowałem różnych sposobów. Dla mnie zadziałało to:

Convert.ToDateTime(data, CultureInfo.InvariantCulture);

data dla mnie były takie czasy 9/24/2017 9:31:34 AM

zeilja
źródło
Wygląda lepiej, czy można przypisać jego wartość do zmiennej DateTime?
Birhan Nega
20

Wypróbuj poniżej, gdzie strDate to Twoja data w formacie „MM / dd / rrrr”

var date = DateTime.Parse(strDate,new CultureInfo("en-US", true))
Kryszna
źródło
1
Nikt nie wspominał, że działa tylko z tym konkretnym formatem.
T.Todua,
Szkoda ... od Koderzy zawsze myślą, że inni koderzy się dowiedzą ... Właściwie to dobrze ... Spraw, abyśmy myśleli więcej ...
Krishna
15
string input;
DateTime db;
Console.WriteLine("Enter Date in this Format(YYYY-MM-DD): ");
input = Console.ReadLine();
db = Convert.ToDateTime(input);

//////// this methods convert string value to datetime
///////// in order to print date

Console.WriteLine("{0}-{1}-{2}",db.Year,db.Month,db.Day);
Umair Baig
źródło
1
Przegapiłeś część czasu? Potrzebuję zarówno daty, jak i godziny. Jak mogę to zrobić?
Badhon Jain
15

DateTime.Parse

Składnia:

DateTime.Parse(String value)
DateTime.Parse(String value, IFormatProvider provider)
DateTime.Parse(String value, IFormatProvider provider, DateTypeStyles styles)

Przykład:

string value = "1 January 2019";
CultureInfo provider = new CultureInfo("en-GB");
DateTime.Parse(value, provider, DateTimeStyles.NoCurrentDateDefault););
  • Wartość: ciąg znaków reprezentujący datę i godzinę.
  • Dostawca: obiekt, który udostępnia informacje specyficzne dla kultury.
  • Style: opcje formatowania, które dostosowują parsowanie ciągów dla niektórych metod parsowania daty i godziny. Na przykład AllowWhiteSpaces to wartość, która pomaga zignorować wszystkie spacje występujące w ciągu podczas analizowania.

Warto również pamiętać, że DateTime jest obiektem przechowywanym wewnętrznie jako liczba w frameworku, Format stosuje się do niego tylko po przekonwertowaniu go z powrotem na ciąg.

  • Analiza składniowa przekształcająca ciąg znaków na typ liczby wewnętrznej.

  • Formatowanie przekształcające wewnętrzną wartość liczbową na czytelny ciąg.

Ostatnio miałem problem polegający na tym, że próbowałem przekonwertować DateTime, aby przekazać go do Linq, czego nie zdawałem sobie wtedy sprawy, że format nie ma znaczenia przy przekazywaniu DateTime do zapytania Linq.

DateTime SearchDate = DateTime.Parse(searchDate);
applicationsUsages = applicationsUsages.Where(x => DbFunctions.TruncateTime(x.dateApplicationSelected) == SearchDate.Date);

Pełna dokumentacja DateTime

Mr.B
źródło
14

Możesz także użyć DateTime.TryParseExact () jak poniżej, jeśli nie jesteś pewien wartości wejściowej.

DateTime outputDateTimeValue;
if (DateTime.TryParseExact("2009-05-08 14:40:52,531", "yyyy-MM-dd HH:mm:ss,fff", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out outputDateTimeValue))
{
    return outputDateTimeValue;
}
else
{
    // Handle the fact that parse did not succeed
}
dev.bv
źródło
2

Umieść ten kod w klasie statycznej> public static class ClassName{ }

public static DateTime ToDateTime(this string datetime, char dateSpliter = '-', char timeSpliter = ':', char millisecondSpliter = ',')
{
   try
   {
      datetime = datetime.Trim();
      datetime = datetime.Replace("  ", " ");
      string[] body = datetime.Split(' ');
      string[] date = body[0].Split(dateSpliter);
      int year = date[0].ToInt();
      int month = date[1].ToInt();
      int day = date[2].ToInt();
      int hour = 0, minute = 0, second = 0, millisecond = 0;
      if (body.Length == 2)
      {
         string[] tpart = body[1].Split(millisecondSpliter);
         string[] time = tpart[0].Split(timeSpliter);
         hour = time[0].ToInt();
         minute = time[1].ToInt();
         if (time.Length == 3) second = time[2].ToInt();
         if (tpart.Length == 2) millisecond = tpart[1].ToInt();
      }
      return new DateTime(year, month, day, hour, minute, second, millisecond);
   }
   catch
   {
      return new DateTime();
   }
}

W ten sposób możesz użyć

string datetime = "2009-05-08 14:40:52,531";
DateTime dt0 = datetime.TToDateTime();

DateTime dt1 = "2009-05-08 14:40:52,531".ToDateTime();
DateTime dt5 = "2009-05-08".ToDateTime();
DateTime dt2 = "2009/05/08 14:40:52".ToDateTime('/');
DateTime dt3 = "2009/05/08 14.40".ToDateTime('/', '.');
DateTime dt4 = "2009-05-08 14:40-531".ToDateTime('-', ':', '-');
MRT2017
źródło
2

Właśnie znalazłem elegancki sposób:

Convert.ChangeType("2020-12-31", typeof(DateTime));

Convert.ChangeType("2020/12/31", typeof(DateTime));

Convert.ChangeType("2020-01-01 16:00:30", typeof(DateTime));

Convert.ChangeType("2020/12/31 16:00:30", typeof(DateTime), System.Globalization.CultureInfo.GetCultureInfo("en-GB"));

Convert.ChangeType("11/شعبان/1437", typeof(DateTime), System.Globalization.CultureInfo.GetCultureInfo("ar-SA"));

Convert.ChangeType("2020-02-11T16:54:51.466+03:00", typeof(DateTime)); // format: "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzz"
guneysus
źródło
1

Różne kultury na świecie zapisują ciągi dat na różne sposoby. Na przykład w Stanach Zjednoczonych 01/20/2008 jest 20 stycznia 2008 r. We Francji spowoduje to zgłoszenie wyjątku InvalidFormatException. Wynika to z faktu, że Francja odczytuje daty-godziny jako Dzień / Miesiąc / Rok, aw Stanach Zjednoczonych jest to Miesiąc / Dzień / Rok.

W rezultacie ciąg taki jak 20/01/2008 zostanie przeanalizowany do 20 stycznia 2008 r. We Francji, a następnie zgłosi wyjątek InvalidFormatException w USA.

Aby określić bieżące ustawienia kultury, możesz użyć System.Globalization.CultureInfo.CurrentCulture.

string dateTime = "01/08/2008 14:50:50.42";  
        DateTime dt = Convert.ToDateTime(dateTime);  
        Console.WriteLine("Year: {0}, Month: {1}, Day: {2}, Hour: {3}, Minute: {4}, Second: {5}, Millisecond: {6}",  
                          dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond);  
Saeed Dini
źródło
1
String now = DateTime.Now.ToString("YYYY-MM-DD HH:MI:SS");//make it datetime
DateTime.Parse(now);

ten ci daje

2019-08-17 11:14:49.000
Abdulhakim Zeinu
źródło
-1

Czy chcesz to szybko?

Powiedzmy, że masz datę w formacie yyMMdd.

Najszybszym sposobem na konwersję, który znalazłem, jest:

var d = new DateTime(
(s[0] - '0') * 10 + s[1] - '0' + 2000, 
(s[2] - '0') * 10 + s[3] - '0', 
(s[4] - '0') * 10 + s[5] - '0')

Po prostu wybierz indeksy zgodnie z wybranym formatem daty. Jeśli potrzebujesz prędkości, prawdopodobnie nie masz nic przeciwko „nieogólnemu” sposobowi działania tej funkcji.

Ta metoda zajmuje około 10% czasu wymaganego przez:

var d = DateTime.ParseExact(s, "yyMMdd", System.Globalization.CultureInfo.InvariantCulture);
David
źródło