好问题,它似乎确实是 .NET 框架和其他语言似乎也缺少的东西。我猜结果的呈现取决于您的应用程序。
Outlook 作为输入具有非常好的日期理解能力(就像谷歌日历一样),但我个人还没有看到这种形式的表达作为输出(例如显示给用户)。
一些建议:
- 坚持显示开始日期和结束日期,不用担心冗余
- 自己动手...... :-(
我猜想,从您的术语“本地化”中,您计划将输出国际化,如果是这种情况,您将很难捕捉所有案例,它似乎不是存储在大多数典型案例中的信息国际化数据集。
从您的示例中专注于英语,您似乎已经在代码中定义了许多规则:
- 年份始终显示。
- 也总是显示月份(至少其中一个)。
- 在情况 3 中不显示天数,我的条件是表示开始日期是 1 日,结束日期是 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