Рядок не було визнано дійсним DateTime "формат dd / MM / yyyy"


172

Я намагаюся перетворити моє значення в рядковому форматі у тип дати у формат dd/MM/yyyy.

this.Text="22/11/2009";

DateTime date = DateTime.Parse(this.Text);

В чому проблема ? У нього є друга переоцінка, яка вимагає IFormatProvider. Що це? Чи потрібно мені це також пройти? Якщо так, як це використовувати для цього випадку?

Редагувати

Які відмінності між Parseі ParseExact?

Редагувати 2

Обидві відповіді Slaks і Сем працюють для мене, наразі користувач дає вхід, але це буде впевнене мною, що вони дійсні за допомогою maskTextbox.

Яка відповідь краще врахувати всі аспекти, такі як тип saftey, продуктивність чи щось, що вам здається


7
@Edit: Ось для чого складається документація. msdn.microsoft.com/en-us/library/w2sa9yss.aspx
SLaks

2
ParseExact призначений для того, коли ви знаєте точний формат рядка дати, Parse - це те, коли вам потрібно щось, що може обробити щось більш динамічне.
пряник

Відповіді:


255

Використовуйте DateTime.ParseExact.

this.Text="22/11/2009";

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", null);

8
Чому ми мусимо тут пропустити нуль?
Шантану Гупта

3
Вхід може бути "22/11/2009 12:00:00 AM" або "22/11/2009". Також культура машини розвитку може відрізнятися від культури виробництва. Тож чи буде описаний вище код безпроблемно?
Рахатур

8
@Rahat, точний аналіз не буде працювати, якщо формат не збігається. Наведений вище формат є dd/MM/yyyyтаким чином, що текстовий рядок з часом у ньому буде неправильно проаналізований. Вам потрібно буде або зняти час, або включити його у шаблон формату. Існує перевантаження, ParseExactяка приймає масив форматів шаблонів і аналізує текст, якщо він відповідає будь-якому з них.
Самуель Нефф

7
@SamuelNeff Чому б ви не використовували CultureInfo.InvariantCultureзамість поточного, якщо ви все одно визначаєте формат?
Елвін Вонг

3
@Toolkit Причина полягає в тому, що косої риски в рядку формату не є буквальними косою рисою. Вони заміщені рядком роздільника дат у поточній культурі. Отже, це залежить від культури, як написано вище. Семюел Нефф, спробуйте Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");, це порушить ваше рішення. Щоб виправити це, використовуйте "dd'/'MM'/'yyyy"(захист @"dd\/MM\/yyyy"косої риски за допомогою одинарних лапок) або ("уникнення" косої риски за допомогою косої риски).
Jeppe Stig Nielsen

44

Вам потрібно зателефонувати ParseExact, який аналізує дату, яка точно відповідає формату, який ви надаєте.

Наприклад:

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);

IFormatProviderПараметр визначає культуру використовувати для розбору дати.
Якщо ваша строка не надходить від користувача, вам слід пройти CultureInfo.InvariantCulture.
Якщо рядок дійсно надходить від користувача, вам слід пройти CultureInfo.CurrentCulture, який буде використовувати налаштування, які користувач вказав у регіональних параметрах на панелі керування.


2
@Slaks: CultureInfo.InvariantCulture не доступна в коді. Чи потрібно мені використовувати простір імен
Shantanu Gupta

3
using System.Globalization;
Слакс

2
Ви також можете клацнути правою кнопкою миші на помилку і натиснути вирішити, це помістить у відсутню для вас область імен.
Inkey

ви також можете двічі клацнути помилку та побачити стрілку вниз, де відображаються пов’язані простори імен, якими ви можете скористатися
Usman Younas

Пробіли також враховуються, тому, наприклад, якщо ваш рядок є "MM / dd / yyyy HH: mm: ss" (примітка - 2 пробіли) - тоді ваш формат для ParseExact також повинен містити пробіли
Chris Halcrow

20

Розбиття рядкового подання DateTime є складним, оскільки різні культури мають різні формати дати. .Net знає про ці формати дати та витягує їх із вашої поточної культури ( System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat) під час дзвінка DateTime.Parse(this.Text);

Наприклад, рядок "22/11/2009" не відповідає ShortDatePattern для Сполучених Штатів (en-US), але він відповідає Франції (fr-FR).

Тепер ви можете або зателефонувати DateTime.ParseExactта передати потрібний рядок формату, який ви очікуєте, або передати відповідну культуру, DateTime.Parseщоб проаналізувати дату.

Наприклад, це правильно розбере вашу дату:

DateTime.Parse( "22/11/2009", CultureInfo.CreateSpecificCulture("fr-FR") );

Звичайно, не слід вибирати Францію лише випадковим чином, а щось відповідне вашим потребам.

Що потрібно з’ясувати, це те, що System.Threading.Thread.CurrentThread.CurrentCultureвстановлено, і якщо / чому воно відрізняється від того, що ви очікуєте.


ваше рішення не працює для мене, воно дає помилку типу "Рядок не був визнаний дійсним DateTime". і я передаю наступну дату введення: "13/06/17" до вашого рішення, але це дає помилку.
Ghanshyam Lakhani

16

Хоча вищезазначені рішення ефективні, ви також можете змінити файл webconfig за допомогою наступного ...

<configuration>
   <system.web>
     <globalization culture="en-GB"/>
   </system.web>
</configuration>

Посилання: Формат дати відрізняється на локальній машині порівняно з виробничою машиною


1
Аміт Філіпс, ти врятував мені день .. Я спробував усі можливі речі. І ця невелика зміна працює. Дякую.
RNH

1
Змитуйся, ти справді син Божий.
Розлючений ведмідь


4

Затративши багато часу, я вирішив проблему

 string strDate = PreocessDate(data);
 string[] dateString = strDate.Split('/');
 DateTime enter_date = Convert.ToDateTime(dateString[1]+"/"+dateString[0]+"/"+dateString[2]);

3

використовуйте це для перетворення рядка в дату:

Datetime DT = DateTime.ParseExact(STRDATE,"dd/MM/yyyy",System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat)

3

Виходячи з цього посилання , для мене працював наступний підхід:

// e.g. format = "dd/MM/yyyy", dateString = "10/07/2017" 
var formatInfo = new DateTimeFormatInfo()
{
     ShortDatePattern = format
};
date = Convert.ToDateTime(dateString, formatInfo);

2
private DateTime ConvertToDateTime(string strDateTime)
{
DateTime dtFinaldate; string sDateTime;
try { dtFinaldate = Convert.ToDateTime(strDateTime); }
catch (Exception e)
{
string[] sDate = strDateTime.Split('/');
sDateTime = sDate[1] + '/' + sDate[0] + '/' + sDate[2];
dtFinaldate = Convert.ToDateTime(sDateTime);
}
return dtFinaldate;
}

1

Так само, як хтось вище сказав, що ви можете надіслати його як параметр рядка, але він повинен мати такий формат: наприклад, "20130121", і ви можете перетворити його у той формат, взявши його безпосередньо з керування. Таким чином, ви отримаєте його, наприклад, із текстового поля типу:

date = datetextbox.text; // date is going to be something like: "2013-01-21 12:00:00am"

щоб перетворити його на: '20130121', ви використовуєте:

date = date.Substring(6, 4) + date.Substring(3, 2) + date.Substring(0, 2);

щоб SQL міг перетворити його і помістити у вашу базу даних.


0

Ви також можете використовувати

this.Text = "22112009";
DateTime newDateTime = new DateTime(Convert.ToInt32(this.Text.Substring(4, 4)), // Year
                                    Convert.ToInt32(this.Text.Substring(2,2)), // Month
                                    Convert.ToInt32(this.Text.Substring(0,2)));// Day

0

Для мене працював нижче код:

DateTime date = DateTime.Parse(this.Text, CultureInfo.CreateSpecificCulture("fr-FR"));

Простір імен

using System.Globalization;

-6

Змінити вручну:

string s = date.Substring(3, 2) +"/" + date.Substring(0, 2) + "/" + date.Substring(6, 4);

З 22.11.2015 він буде перетворений на 22.11.2015

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.