Как отформатировать дату на С# на примере?

С# обеспечивает большую гибкость при форматировании объекта DateTime для строкового представления, однако для использования этой гибкости нужно знать все строки формата.

Если вы хотите отобразить дату в форме "Fri, June 24", вы можете сделать это следующим образом:

DateTime someDate = DateTime.Now;
Console.Write(someDate.ToString("ddd, MMMM dd"));

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

Я хочу добиться тех же результатов, которые были возвращены из приведенного выше кода, но с этим:

DateTime someDate = DateTime.Now;
Console.WriteLine(someDate.ToString("Wed, June 12"));

Дата, указанная в виде строки, может быть произвольной. По сути, формат должен определяться путем первоначального синтаксического анализа даты. Я знаю, что этот подход имеет ограничения (локализация - одна), но для простых сценариев это гораздо более понятно. Есть ли способ сделать это отдельно от его реализации? Я готов использовать сторонние библиотеки.

Ответ 1

Обычно я просто выясняю, какая должна быть правильная строка формата (в вашем примере "ddd, MMMM dd"), а затем сохраните ее как константу где-нибудь в приложении...

public static class DateTimeFormats
{
    public string DayOfWeekMonthDay = "ddd, MMMM dd";
}

тогда вы можете просто обратиться к нему

DateTime.Now.ToString(DateTimeFormats.DayOfWeekMonthDay)

Ответ 2

Я вижу, как это может показаться более легким для более современного разработчика, но есть несколько проблем, с которыми приходится сталкиваться при построении функции "формат даты из даты". Я могу представить сценарии, в которых такая функция может потерпеть неудачу, говоря такие вещи, как:

  • Ты сказал "май"; это означает, что даты в июнь должны форматироваться как "июнь" или "июнь"?
  • Ты сказал "12 июня"; означает ли это 5 июня в формате "5 июня" или "05 июня"?

Теперь вы можете объяснить новым разработчикам, что им нужно быть осторожными, чтобы не использовать шаблоны формата даты, которые неоднозначны. Но это потребует от них уже понять, как это может быть неоднозначно. Им нужно будет уже думать, как думает функция форматирования.

Вот почему строки формата даты определены так, как они есть, - чтобы быть как можно более конкретными относительно желаемого формата вывода, который разработчик хочет/должен произвести. Они предотвращают такие двусмысленности в максимально возможной степени.

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

Ответ 3

Строгий ответ на этот вопрос:

Есть ли способ сделать это отдельно от сам это реализовать? Я готов к используйте сторонние библиотеки.

Нет, если третье лицо уже этого не делало, вам нужно будет реализовать собственный синтаксический анализатор строк.

Я разделяю мнение большинства респондентов о том, что усилия, необходимые для этого, совершенно несоразмерны альтернативе просто запоминания уже предоставленных форматов DateTime (или ссылки на их документацию). Но если вы предпримете такие усилия, вы захотите реализовать ICustomFormatter и IFormatProvider, который предоставит его по запросу.

См. документацию ICustomFormatter, приведенную выше для примера, но ваша задача будет включать метод Format(string format, object arg, IFormatProvider formatProvider), который берет строку в интересующем вас формате и использует ее для преобразования DateTime, переданного в arg в строку сопоставив этот рисунок.

Как только это будет сделано, и у вас есть IFormatProvider, метод GetFormat() возвращает ваш собственный форматировщик, ваш пример кода будет выглядеть так:

DateTime someDate = DateTime.Now;
Console.WriteLine(someDate.ToString("Wed, June 12", new CustomDateFormatter()));

Ответ 4

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

Вы когда-нибудь работали с VBA и датами?

Ответ 5

После поиска некоторое время мне удалось найти Ruby library, которая делает то же самое, что я искал. Поскольку я не смог найти .NET-решение, я реализовал свою собственную утилиту, вдохновленную Ruby.

Пик, поддерживающий 4 общих формата, можно увидеть на github - Stamp.Net. Я отправляю это как ответ, чтобы люди, заинтересованные в такой утилите, могли получить оттуда и использовать их непосредственно в своих проектах.

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

Некоторые примечания по реализации:

.NET framewok обеспечивает очень хороший способ для реализации пользовательских форматировщиков и поставщиков форматов для типов. @djacobson упомянул об этом в своем ответе на вопрос. К сожалению, класс DateTime реализован таким образом, что с ним нельзя использовать ICustomFormatter. Когда вы вызываете ToString() с поставщиком произвольного формата, поставщик этого формата должен возвращать объект DateTimeFormatInfo, а класс DateTime не вызывает настраиваемый форматтер, возвращаемый поставщиком данных.

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