Обычно "специализированная структура" на самом деле ЯВЛЯЕТСЯ разумным текущим состоянием объекта с его собственными методами.
class Some3SpaceThing(object):
def __init__(self,x):
self.g(x)
def g(self,x):
self.y0 = x + 1
self.y1 = x * 3
self.y2 = y0 ** y3
r = Some3SpaceThing( x )
r.y0
r.y1
r.y2
мне нравится находить названия анонимных структур, если это возможно. Понятные имена делают вещи более ясными.
I ended up defining my own range formats for this.
For the most part I derived them from the LongDatePattern. Where possible I verified the formats against Google Calendar, and / or native speakers.
I also generated 2 formats for time ranges (within the same day), one for within the same 12 hour period and another for times outside the same 12 hour period (for cultures that use 24 hour time these 2 formats are the same). Those are mostly based on the FullDateTimePattern.
In all cases I removed "day names" (monday, tuesday, etc) from all the formats where ever possible.
I would love to post them here, but it seems that the Stack Overflow folks have an irrational fear of html tables, because they don't allow table tags. The data is essentially a giant table. I have no interest in trying to simulate tables using CSS, so I just put the table up on my own site. You can access it here if you are interested:
http://www.transactor.com/misc/ranges.html
I do have some detailed notes on how I derived a lot of the formats, including what's been validated and what hasn't, if you are really interested. If you want those notes, just send an email to:
contact@transactor.com
и я буду рад их вам отправить.
Хороший вопрос, и похоже, что .NET framework и другие языки тоже этого не делают. Я предполагаю, что представление результатов зависит от вашего приложения.
Outlook имеет очень хорошее понимание даты в качестве входных данных (как и календари Google), но я лично не видел эту форму выражения в качестве выходных данных (например, отображаемых в пользователя).
Некоторые рекомендации:
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
Приведенный ниже код обрабатывает 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));
}