Ошибка строка не распознана как действительное значение datetime

При конвертации строки в дату возникает ошибка:
System.FormatException: «Строка не распознана как действительное значение DateTime.»

string date_string = check_array[i].ToString().Split(',')[1]; // приходит "01.03.2021"

DateTime dt = DateTime.ParseExact(date_string, "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);

В отладчике смотрел — действительно, приходит string «01.03.2021».

Если же в коде указать конкретную дату «01.03.2021», то работает без ошибок:

DateTime dt = DateTime.ParseExact("01.03.2021", "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
            

Помогите решить проблему. Спасибо.

Специально, для тех, кто не верит — принтскрин отладчика:
введите сюда описание изображения

I have created an extension method that I use everytime

    public static DateTime? ToDateTime(this string dateTime)
    {
        if (string.IsNullOrEmpty(dateTime))
        {
            return null;
        }

        return DateTimeOffset.ParseExact(dateTime, new string[] { "MMM dd, yyyy", "dd/MM/yyyy", "d/M/yyyy", "dd-MM-yyyy", "d-M-yyyy", "yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-dd" }, CultureInfo.InvariantCulture).DateTime;
    }

I have added multiple formats that I encounter in an array and I reuse this method every time, the above method works for the following examples of date:

  • May 23, 2022
  • 5-08-2023
  • 05-08-2023
  • 5/08/2023
  • 05/08/2023
  • 2023-02-01
  • 2023-02-01T12:23:99Z

additionally in c# the answer of @Manjay can also be tried as follows :

    char formatChar = '-';
    if (dateTime.Contains('-'))
    {
        formatChar = '-';
    }

    if (dateTime.Contains('/'))
    {
        formatChar = '/';
    }

    string[] parts = dateTime.Split(formatChar);
    var month = parts[0].PadLeft(2, '0');
    var day = parts[1].PadLeft(2, '0');
    var year = parts[2];
    string properFormattedDate = $"{month}{formatChar}{day}{formatChar}{year}";

    return DateTimeOffset.ParseExact(properFormattedDate, new string[] { "MMM dd, yyyy", "dd/MM/yyyy", "dd-MM-yyyy", "yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-dd" }, CultureInfo.InvariantCulture).DateTime;

1nsan1ty

0 / 0 / 0

Регистрация: 18.08.2018

Сообщений: 34

1

13.09.2018, 02:04. Показов 14799. Ответов 5

Метки datetime (Все метки)


Студворк — интернет-сервис помощи студентам

снова не могу понять DataTime, я еще новичок, была у меня просто форма с date. Но в этот раз сказали сделать через DataTime. Я не могу понять что и как писать сначала перевел значение DataTime в строковое представление. После как я понял нужно из строкового представления вывести обратно в DataTime. Написал (наверное бурду) в интернете порылся не особо понял, может кто помочь написать правильно и объяснить что не так и как сделать так?? буду очень признателен.

C#
1
2
3
4
5
6
 public DateTime d1; 
DateTime d1 = DateTime.Now;
            string str_dt = d1.ToString(); //работает
 
            string inp_dt = Convert.ToDateTime(d1).ToString("mm.dd.yyyy");
            DateTime d2 = DateTime.Parse(inp_dt);//Строка не распознана как действительное значение DateTime."

что не так? вобще не дается мне DataTime. загвоздка в том что нужно обязательно сделать через нее
и главное понять что и к чему, может кто помочь?



0



kolorotur

Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

13.09.2018, 03:13

2

Цитата
Сообщение от 1nsan1ty
Посмотреть сообщение

DataTime

Перво-наперво, тип называется DateTime: ДатаВремя, а не ДанныеВремя.

Цитата
Сообщение от 1nsan1ty
Посмотреть сообщение

что не так?

Вы дату переводите в строку в произвольном формате, а назад в дату пытаетесь перевести используя формат, установленный в текущий момент в системе. Если эти форматы не совпадают, то будет ошибка, что вы и наблюдаете.

Если у вас имеется строка, представляющая дату каком-нибудь экзотическом формате, то надо использовать метод ParseExact, который позволяет задать формат, в котором эта дата представлена:

C#
1
DateTime d2 = DateTime.ParseExact(inp_dt, "mm.dd.yyyy", null);



1



0 / 0 / 0

Регистрация: 18.08.2018

Сообщений: 34

13.09.2018, 14:07

 [ТС]

3

прощу прощение за ошибку в DateTim, ближе к ночи уже перестаешь нормально соображать. Невнимательность



0



1nsan1ty

0 / 0 / 0

Регистрация: 18.08.2018

Сообщений: 34

13.09.2018, 14:49

 [ТС]

4

написал как вы и сказали, но тут такой вопрос. на который я никак не могу найти ответ не хватает знания и понимания. У меня есть страница там я ввожу данные и дату рождения. Все отлично кроме даты. Выводит число 01.01.0001. 00 00 00. Почему? как это исправить как выводить выбранную дату и без времени?????
вот так код выглядит сейчас, где косячу? где не понимаю??? почему так происходит вот никак не дается мне эта дата

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 List<Person> lst = new List<Person>();
        public class Person
        {
            public string Famil;
            public string Imja;
            public string Otch;
            public string Pol;
            public DateTime d1;
          
        }
 protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["l"] == null)
                Session["l"] = lst;
            lst = (List<Person>)Session["l"];
        }
 protected void Button1_Click(object sender, EventArgs e)
        {
            DateTime d1 = DateTime.Now;
            string str_dt = d1.ToString(); //работает
            string inp_dt = Convert.ToDateTime(d1).ToString("mm.dd.yyyy");
            DateTime d2 = DateTime.ParseExact(inp_dt, "mm.dd.yyyy", null);
 string Tex1 = TextBox1.Text;
            Person p = new Person();
            p.Famil = Tex1;
            //lst.Add(p);
            string Tex2 = TextBox2.Text;
            //Person z = new Person();
            p.Imja = Tex2;
            // lst.Add(z);
            string Tex3 = TextBox3.Text;
            // Person o = new Person();
            p.Otch = Tex3;
p.Pol = "-";
            if (RadioButton1.Checked)
            {
                p.Pol = RadioButton1.Text;
            }
            if (RadioButton2.Checked)
            {
                p.Pol = RadioButton2.Text;
            }
 lst.Add(p);
            RadioButton1.Checked = false;
            RadioButton2.Checked = false;
            Show();
        }
 protected void Button2_Click(object sender, EventArgs e)
        {
            Show();
        }
 
        private void Show()
        {
 if (lst.Count() == 0)
            {
               
                label2.Text = "0 элементов";
            }
 HtmlTableRow tr = new HtmlTableRow();
            HtmlTableCell number = new HtmlTableCell();
            number.InnerHtml = "#";
            tr.Cells.Add(number);
            HtmlTableCell surname = new HtmlTableCell();
            surname.InnerHtml = "Фамилия";
            tr.Cells.Add(surname);
            HtmlTableCell name = new HtmlTableCell();
            name.InnerHtml = "Имя";
            tr.Cells.Add(name);
            HtmlTableCell patronymic = new HtmlTableCell();
            patronymic.InnerHtml = "Отчество";
            tr.Cells.Add(patronymic);
HtmlTableCell dtr = new HtmlTableCell();
            dtr.InnerHtml = "Дата рождения";
            tr.Cells.Add(dtr);
            HtmlTableCell pol = new HtmlTableCell();
            pol.InnerHtml = "Пол";
            tr.Cells.Add(pol);
            tbl1.Rows.Add(tr);
            int count = 0;
foreach (Person p in lst) 
 {
                HtmlTableRow tr2 = new HtmlTableRow();
                HtmlTableCell number2 = new HtmlTableCell();
                count = count + 1;
                number2.InnerHtml = count.ToString();
                tr2.Cells.Add(number2);
                HtmlTableCell surname2 = new HtmlTableCell();
                surname2.InnerHtml = p.Famil.ToString();
                tr2.Cells.Add(surname2);
                HtmlTableCell name2 = new HtmlTableCell();
                name2.InnerHtml = p.Imja.ToString();
                tr2.Cells.Add(name2);
                HtmlTableCell patronymic2 = new HtmlTableCell();
                patronymic2.InnerHtml = p.Otch.ToString();
                tr2.Cells.Add(patronymic2);
 HtmlTableCell dtr2 = new HtmlTableCell();
                dtr2.InnerHtml = p.d1.ToString(); //format
                tr2.Cells.Add(dtr2);
                HtmlTableCell pol2 = new HtmlTableCell();
                pol2.InnerHtml = p.Pol.ToString();
                tr2.Cells.Add(pol2);
 
                tbl1.Rows.Add(tr2);
                DropDownList1.Items.Add(p.Famil + " " + p.Imja + " " + p.Otch);
            }

Миниатюры

Строка не распознана как действительное значение DateTime
 

Строка не распознана как действительное значение DateTime
 



0



kolorotur

Эксперт .NET

17346 / 12757 / 3338

Регистрация: 17.09.2011

Сообщений: 21,036

13.09.2018, 15:32

5

Цитата
Сообщение от 1nsan1ty
Посмотреть сообщение

C#
1
2
3
4
DateTime d1 = DateTime.Now;
string str_dt = d1.ToString(); //работает
string inp_dt = Convert.ToDateTime(d1).ToString("mm.dd.yyyy");
DateTime d2 = DateTime.ParseExact(inp_dt, "mm.dd.yyyy", null);

Здесь какие-то странные манипуляции.
Какого результата вы хотите ими добиться?
Зачем конвертировать дату в строку только для того, чтобы тут же обратно конвертировать эту строку в дату?

Цитата
Сообщение от 1nsan1ty
Посмотреть сообщение

Все отлично кроме даты. Выводит число 01.01.0001. 00 00 00. Почему?

Потому что в обработчике клика кнопки вы нигде не присваиваете значение полю d1 вашего экземпляра, вот оно и остается значением для DateTime по умолчанию.



1



0 / 0 / 0

Регистрация: 18.08.2018

Сообщений: 34

13.09.2018, 16:00

 [ТС]

6

спасибо, все уже разобрался, вы очень мне помогли!



0



Ah…error messages.

Sometimes very useful, other times not so much, but always present in a developer?s life. And that?s what today?s post is about.

Not ?error messages? in general, but one message in particular: ?String was not recognized as a valid DateTime.?

Datetime mistake: string not recognized as valid datetime.

As a developer, you?re pretty much guaranteed to have to write code that handles date and time. Which means you?re also bound to have some problems while parsing strings to DateTime values, and that?s what this post will cover.

We?ll start out by talking about the causes of the issue. You’ll learn about globalization and how big a role it plays in the consistency and correction of your application. Then, we?ll close with practical advice on what you can do to prevent such problems from happening in the first place.

Let?s get started!

“String Was Not Recognized as a Valid DateTime.” Why Does That Happen?

I’ll concede?it: As far as error messages go, “String was not recognized as a valid DateTime” isn’t bad at all. It states that you’re trying to get a DateTime value out of a string that is not a valid?DateTime.

Pretty easy, right?

Well, things would be a walk in the park if you got this message only when trying to parse, say, “potato” as a DateTime. The problem is, more often than not, the offending string is something that, at least to you, looks like a perfectly normal date and time.

C# Datetime Stamps

The really important piece in the last sentence was “at least to you,” as you’ll see in a second.

For instance, consider the following line of C# code:

DateTime d = DateTime.Parse("15/12/2019");

Go ahead, create a console app and place that line of code in it. Run the application. Did it run successfully? Or, did you get the “String was not recognized as a valid DateTime value” message?

As it turns out, whether the code works like a charm or crashes is mostly a matter of geography.

Date Formats Are Tricky

We humans have a messy relationship with time. One of the ways this messiness manifests itself is through the countless date formats used around the world.

For instance, think about the date June 14th, 2019. (There’s nothing special about that date; I got it from this Random Calendar Date Generator.)

Now consider this list, which shows just some of the possible ways that date can be represented, in actual date/time formats used by real people every day across the globe:

  • 14/06/2019
  • 14.06.2019
  • 14-06-2019
  • 14/06/19
  • 06/14/2019
  • 2019-06-14

It doesn’t take long to reach the conclusion that some strings that are perfectly valid dates in one format are not in others. For example, if you pass the “06/14/2019” string when the “dd/MM/yyyy” format is expected, the parsing will evidently fail, since there’s no month 14.

So, who gets to decide which format is acceptable when parsing dates? Read on to find out.

“String Not Recognized…” No More: Making the Error Go Away

Let’s revisit the code example from the previous section:

DateTime d = DateTime.Parse("15/12/2019");

We’ll now make a small edit to this line of code that will ensure it always works. (We’ll edit first and explain later.) Here’s the new version of the code:

DateTime d = DateTime.Parse(
    "15/12/2019",
     new System.Globalization.CultureInfo("pt-BR"));

Go ahead. Edit your code and run the app again. If it worked for you the first time, then it’ll just continue working with no alterations whatsoever. But if the first version crashed for you, it’ll work this time.

Why is that? What is this CultureInfo thing? And what does that “pt-BR” thing mean?

It’s All a Matter of Culture

There are many methods in the .NET BCL (Base Class Library) that are sensitive to culture. But what does culture mean in this context?

Some people will say it refers only to the language. And sure, language is involved in culture, but it’s far from being the only factor.

Here goes my definition: Culture is a set of conventions and expectations about the way information is presented. I know that sounds broad, so let’s get more specific. A given culture will contain, among other things, information about

  • the calendar used in the country;
  • number formats (e.g., do the people in the country use commas or periods as decimal separators); and
  • a plethora of date and time formats.

In the example from the previous section, you saw the “pt-BR” string. That identifies the “Portuguese – Brazilian” culture. Since in Brazil the standard short date format is “dd/MM/yyyy”, by explicitly passing the pt-BR culture as a parameter, we enabled the parsing to work as expected.

Taking CultureInfo for Granted: Yay or Nay?

So now you know that the CultureInfo class represents a culture in the .NET BCL. But how does the concept of culture fit in the “String Not Recognized” feature?

As I said earlier, there are a lot of methods in .NET that take an instance of CultureInfo as one of its parameters. What also usually happens is that those methods have overloads that don’t take a CultureInfo as a parameter but assume the culture of the current thread instead.

Too much commented out code in your codebase will have you pulling your hair out, like this poor guy.

Which means that the answer to the question above?to assume a default culture or not?is the dreaded “It depends.”

Consider an example. Let’s say a Brazilian developer is writing an application and needs to display the current date in the standard Brazilian short date format. To format the date, they write something like this:

var formattedDate = DateTimeOffset.Now.ToString("dd/MM/yyyy");

The code seems to work and it passes code review, so they call it a day. Not long after that, the company for which the developer works starts getting clients in the US. That’s exciting news…but Americans use a different date format. How to handle that?

If the developer in our story is unlucky enough, it won’t take long until someone suggests something like this:

var format = country == "br" ? "dd/MM/yyyy" : "MM/dd/yyyy";
var formattedDate = DateTimeOffset.Now.ToString(format);

The code above is definitely not OK, and I’m not even talking about the fact that it doesn’t handle the possibility of a third (or fourth, or fifth) format. No, the proper solution would be this:

var formattedDate = DateTimeOffset.Now.ToString("d");

The “d” format code refers to the short date format. There’s an overload for that method that takes a CultureInfo object as a parameter, but we’re not using it. Instead, we’re using the overload that assumes the current culture. That way, it will use the correct format for whatever the current culture is in the system.

Culture, Date Formats, and All That Jazz: How to Get Rid of “String Not Recognized as a Valid DateTime” for Good

As we’ve just seen, there are situations in which it makes sense for us to take the culture for granted.

However, there are scenarios in which the opposite is true. Parsing is one of those situations: More often than not, you want to explicitly declare the culture.

In C#/.NET, you have the following options for parsing DateTime values:

  • DateTime.Parse
  • DateTime.ParseExact
  • DateTime.TryParse
  • DateTime.TryParseExact

The “Try” versions of the methods return a Boolean value to indicate whether the parsing was successful or not, while their “non-try” counterparts throw when the parsing fails. The “Exact” variations allow you to explicitly pass one or more formats for the parsing.

The advice here is this: Always explicitly pass the culture, unless you’ve got a pretty decent reason not to. If you’re sure of the format the date is supposed to be in, then provide that format using the “Exact” variations of the method you’ve picked.

Tools at Your Disposal

SubMain has an offering called CodeIt.Right, which is an automated code review tool. It will check your source code against a variety of rules and give you instant feedback about its quality. As it turns out, CodeIt.Right actually has a rule that will gently nag you to always specify a CultureInfo instance whenever there’s a method overload that requires it.

Neat, right?

I suggest you download CodeIt.Right today and give it a try. It can definitely help you avoid not only “String Not Recognized…” but a lot of other nasty errors as well. Thanks for reading, and until next time!

Learn more how CodeIt.Right can help you automate code reviews, improve your code quality, and ensure your code is globalization ready.

About the author

Carlos Schults Headshot

Carlos Schults

Contributing Author


Carlos Schults is a .NET software developer with experience in both desktop and web development, and he?s now trying his hand at mobile. He has a passion for writing clean and concise code, and he?s interested in practices that help you improve app health, such as code review, automated testing, and continuous build. You can read more from Carlos at carlosschults.net.

Related

The error shown in question might have been thrown by Convert.ToDateTime method as shown below:

string dateString = @"20/05/2012";


DateTime date = Convert.ToDateTime(dateString);

In the above code the dateString represents Date in the Day/Month/Year format.
By default the en-US culture is used by .NET according to which the Date is in Month/Day/Year format. So, when ToDateTime method is used it throws error as 20 is out of Month range.

To avoid this error the appropriate culture can be used as follows

string dateString = @"20/05/2012";
DateTime date2 = Convert.ToDateTime(dateString,
	System.Globalization.CultureInfo.GetCultureInfo("hi-IN").DateTimeFormat);

Or the ParseExact method can be used with the required custom format as shown below:

string dateString = @"20/05/2012";
DateTime date3 = DateTime.ParseExact(dateString, @"d/M/yyyy", 
	System.Globalization.CultureInfo.InvariantCulture);

Here d/M/yyyy matches both single and double digit months, days like 20/05/2012, 20/5/2012. The custom format is used in conjunction with InvariantCulture.

When TryParse method is used as shown below

DateTime date4;
string dateString = @"20/05/2012";
bool result = DateTime.TryParse(dateString,out date4);

the parsing fails, but it will not throw error, rather it returns false indicating that the parsing failed.

Понравилась статья? Поделить с друзьями:
  • Ошибка стояночного тормоза w221
  • Ошибка строка 5 пустой тег summary
  • Ошибка субару b0321
  • Ошибка стояночного тормоза volkswagen touareg после замены колодок
  • Ошибка соединения 0x3102 kyocera при сканировании на почту