Как отформатировать дату в C # на примере? - PullRequest
11 голосов
/ 06 июля 2011

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

Если вы хотите отобразить дату в форме «Пт, 24 июня», вы можете сделать это следующим образом:

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

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

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

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

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

Ответы [ 5 ]

14 голосов
/ 06 июля 2011

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

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

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

DateTime.Now.ToString(DateTimeFormats.DayOfWeekMonthDay)
6 голосов
/ 06 июля 2011

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

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

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

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

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

2 голосов
/ 06 июля 2011

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

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

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

Я разделяю мнение большинства респондентов о том, что усилия, необходимые для этого, совершенно несопоставимы с альтернативой простого запоминания уже предоставленных форматов 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()));
1 голос
/ 06 июля 2011

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

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

0 голосов
/ 08 июля 2011

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...