TryParse / ParseExact для строки не удается преобразовать в формат ("dddd dd MMMM"), если добавляются месяцы после нового года - PullRequest
0 голосов
/ 16 октября 2019

Моя цель - преобразовать строковый параметр в формате ' dddd dd MMMM ' в объект DateTime. Сам строковый параметр формируется из выборки относительной даты с сегодняшнего дня, через несколько месяцев в будущем, например DateTime.Now.AddMonths(5).ToString("dddd dd MMMM");. При использовании метода TryParse / ParseExact для преобразования строки параметра обратно в DateTime после нового года (в данном случае после 1 января 2019 года) я получаю следующую ошибку:

System.FormatException:Строка не была распознана как допустимый DateTime, поскольку день недели был неверным. *

Когда я пытаюсь передать параметр требуемого формата до нового года, он принимается как действительный. Может быть, это связано с необходимостью расчета високосного года или есть еще одна причина для этого?

Спасибо,

Ответы [ 2 ]

2 голосов
/ 16 октября 2019

Это никак не связано с тем, что год является високосным: причина, по которой он подходит для дат этого года, но не подходит для дат следующего года, состоит в том, что в вашем формате нет года, поэтому .Net делаетпредположение, что год равен этому году, а день, месяц-день и месяц следующего года не будут анализироваться.

Например:

"Saturday 16 March" -> анализирует без ошибок, поскольку это действительно сейчас, в 2019 году.

"Monday 16 March" -> ошибка, как описано. Это допустимая комбинация дня, месяца-дня и месяца в 2020 году, но она не действительна для этого года, 2019.

0 голосов
/ 17 октября 2019

Ответ Яна правильный, поскольку день недели не совпадает. Это правильный ответ.

Однако - для потомков я также укажу, что в таком коде все еще есть ошибка високосного года. Рассмотрим следующее:

DateTime dt = new DateTime(2020, 2, 29); // a leap day
string format = "MM/dd"; //any format with month and day but without year
string s = dt.ToString(format, CultureInfo.InvariantCulture);
DateTime result = DateTime.ParseExact(s, format, CultureInfo.InvariantCulture);

Этот код выглядит так, как будто он всегда должен работать, так как формат одинаков как при создании строки, так и при ее разборе. Однако, поскольку год не является частью формата, он будет работать только в високосном году. При выполнении в течение общего года будет выдано FormatException с сообщением:

DateTime, представленный строкой, не поддерживается в календаре System.Globalization.GregorianCalendar

Это потому, что объект DateTime должен иметь год, поэтому, если он не был указан, он использует текущий год. Когда я запускаю это сегодня, в 2019 году, он пытается создать дату 2019-02-29, которой не существует.

Кстати, то же самое может случиться при синтаксическом анализе XML. Тип данных XSD gMonthDay предоставляет месяц и день без года, помещая дополнительный дефис в позицию года, например "--12-31", который можно преобразовать с помощью XmlConvert.ToDateTime. Обычно он работает со всеми днями года, но XmlConvert.ToDateTime("--02-29") работает, только если текущий год является високосным, хотя это явно разрешено спецификацией XSD.

...