Локализация диапазонов дат
Кто-нибудь знает, как локализовать диапазоны дат с помощью С#?
В частности, я хочу генерировать "умные" диапазоны дат, чтобы исключить избыточную информацию.
Вот несколько примеров в английском английском
- Август - сентябрь 2009 г.
- Август 2009
- 1 августа - 9, 2009
- 1 января - 3 марта 2009 г.
- 6 декабря 2009 г. - 8 января 2010 г.
Форма, которую я могу сказать, поддерживает .NET Framework для локализации дат, но не диапазонов дат.
Используя информацию в System.Globalization.DateTimeFormatInfo
для локалей Windows, поддерживаемых CultureInfo
, я смог выяснить (большую часть времени), как делать элементы # 1 и # 2. Пункт № 2 просто DateTime.ToString(DateTimeFormatInfo.YearMonthFormat)
. Используя YearMonthFormat
, я также смог вывести форматы для # 1 для большинства языков. Для немногих, что я не мог, я просто дублировал год.
К сожалению, я не могу понять, как делать элементы # 3- # 5 с использованием .NET Framework. Форматы форматов Outlook используются с использованием этих форматов, поэтому я надеялся, что могут быть некоторые API Win32, которые это сделают, но поиск Google для "локализации диапазона дат Win32" ничего полезного не принес.
Мне нравится расширенное удобство использования, предоставляемое "интеллектуальным диапазоном формирования", и я хотел бы, чтобы мои клиенты, не использующие английские версии Windows, получали одинаковые преимущества.
Кто-нибудь знает, как это сделать в зависимости от культуры?
Ответы
Ответ 1
В итоге я определил свои собственные форматы диапазона.
По большей части я получил их из LongDatePattern. Там, где это возможно, я проверил форматы в отношении Календаря Google и/или носителей языка.
Я также создал 2 формата для диапазонов времени (в один и тот же день), один в течение одного и того же 12-часового периода и другой для периодов вне того же 12-часового периода (для культур, которые используют 24-часовое время, эти 2 формата одинаковы). Они в основном основаны на FullDateTimePattern.
Во всех случаях я удалял "имена дней" (понедельник, вторник и т.д.) из всех возможных форматов.
Мне бы хотелось опубликовать их здесь, но кажется, что люди имеют иррациональный страх перед html-таблицами, потому что они не позволяют использовать теги таблицы. Данные по существу представляют собой гигантскую таблицу. Мне неинтересно пытаться имитировать таблицы с помощью CSS, поэтому я просто помещаю таблицу на свой сайт. Вы можете получить к нему доступ, если вы заинтересованы:
http://www.transactor.com/misc/ranges.html
У меня есть некоторые подробные заметки о том, как я получил множество форматов, включая то, что было проверено, а что нет, если вы действительно заинтересованы. Если вы хотите эти заметки, просто отправьте электронное письмо по адресу:
[email protected]
и я был бы рад отправить их вам.
Ответ 2
Хороший вопрос, и это похоже на то, что среда .NET и другие языки, похоже, тоже отсутствуют. Я бы предположил, что представление результатов зависит от вашего приложения.
Outlook имеет очень хорошее понимание даты как вход (как и каландры Google), но я лично не видел эту форму выражения как результат (например, отображаемый пользователю).
Некоторые рекомендации:
- Stick с отображением даты начала и окончания и не беспокоиться о резервировании
- Сверните свой собственный.....: - (
Я бы предположил, что из вашего термина "локализовать" вы планируете интернационализировать вывод, если это так, вы будете иметь тяжелую работу, занимающуюся всеми случаями, это, похоже, не является информацией, хранящейся в большинстве типичных наборов данных интернационализации.
Сосредоточив внимание на английском на вашем примере, у вас, похоже, есть ряд правил, уже определенных в коде:
- Всегда отображается год.
- Также всегда отображается месяц (по крайней мере один из них).
- Дни не отображаются в случае 3, это означало бы, что дата начала - первая, а конец - 31 (например, каждый день месяца).
- День и месяц отображаются, если начало/конец - разные месяцы.
- Год дополнительно указывается с датой начала, если две даты отличаются по году.
Я знаю, что вышеизложенное относится только к английскому, но, на мой взгляд, не слишком сложно катиться, слишком много, чтобы писать в этом редакторе!
РЕДАКТИРОВАТЬ - я знаю, что это не отвечает оригиналу, но если кто-либо, использующий поисковую систему, найдет этот вопрос и хочет получить английскую версию...
class Program
{
static void Main(string[] args)
{
Console.WriteLine(DateRange.Generate(2009, 08, 01, 2009, 09, 31));
Console.WriteLine(DateRange.Generate(2009, 08, 01, 2009, 08, 31));
Console.WriteLine(DateRange.Generate(2009, 08, 01, 2009, 08, 09));
Console.WriteLine(DateRange.Generate(2009, 01, 01, 2009, 03, 03));
Console.WriteLine(DateRange.Generate(2009, 12, 06, 2010, 01, 08));
// Same dates
Console.WriteLine(DateRange.Generate(2009, 08, 01, 2009, 08, 01));
}
}
static class DateRange
{
private static string[] Months = {
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
public static string Generate(
int startYear, int startMonth, int startDay,
int endYear, int endMonth, int endDay)
{
bool yearsSame = startYear == endYear;
bool monthsSame = startMonth == endMonth;
bool wholeMonths = (startDay == 1 && IsLastDay(endDay, endMonth));
if ( monthsSame && yearsSame && startDay == endDay)
{
return string.Format("{0} {1}, {2}", startDay, Month(startMonth), startYear);
}
if (monthsSame)
{
if (yearsSame)
{
return wholeMonths
? string.Format("{0} {1}", Month(startMonth), endYear)
: string.Format("{0} {1} - {2}, {3}", Month(endMonth), startDay, endDay, endYear);
}
return wholeMonths
? string.Format("{0}, {1} - {2}, {3}",
Month(startMonth), startYear,
Month(endMonth), endYear)
: string.Format("{0} {1}, {2} - {3} {4}, {5}",
Month(startMonth), startDay, startYear,
Month(endMonth), endDay, endYear);
}
if (yearsSame)
{
return wholeMonths
? string.Format("{0} - {1}, {2}", Month(startMonth), Month(endMonth), endYear)
: string.Format("{0} {1} - {2} {3}, {4}",
Month(startMonth), startDay,
Month(endMonth), endDay,
endYear);
}
return wholeMonths
? string.Format("{0}, {1} - {2}, {3}",
Month(startMonth), startYear,
Month(endMonth), endYear)
: string.Format("{0} {1}, {2} - {3} {4}, {5}",
Month(startMonth), startDay, startYear,
Month(endMonth), endDay, endYear);
}
private static string Month(int month)
{
return Months[month - 1];
}
public static bool IsLastDay(int day, int month)
{
switch (month+1)
{
case 2:
// Not leap-year aware
return (day == 28 || day == 29);
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
return (day == 31);
case 4: case 6: case 9: case 11:
return (day == 30);
default:
return false;
}
}
}
Это дает тот же результат (почти, сентябрь становится сентября в моей) в качестве исходного вопроса:
August - September, 2009
August 1 - 31, 2009
August 1 - 9, 2009
January 1 - March 3, 2009
December 6, 2009 - January 8, 2010
Ответ 3
Ниже код обрабатывает 4 и 5, если я правильно поняла ваш код.
public string GetDateRangeString(DateTime dt1, DateTime dt2)
{
DateTimeFormatInfo info = new DateTimeFormatInfo();
string format1;
string format2;
format2 = info.YearMonthPattern;
format1 = dt1.Year == dt2.Year ? format1 = info.MonthDayPattern :
format2;
return string.Format("{0} - {1}", dt1.ToString(format1), dt2.ToString(format2));
}