我有多个选项,我想检查:
- 如果周年份startDate和endDate。
- 如果四分之一年份startDate和endDate。
- 如果月份年份startDate和endDate。
- 如果adaystartDate和endDate。
我现有的代码,当startDate<年/strong>=endDate<年/strong>,但是如果startDate或endDate在不同的年份它显然不起作用:
void ForWeek(int year, int week)
{
// throw if week < 1 or week > 53
if (startYear == year && endYear == year
&& (ISOWeek.GetWeekOfYear(x.StartDate) == week && ISOWeek.GetWeekOfYear(x.EndDate) == week))
{
}
}
我还需要一个函数为day做同样的事情月,和季度strong>.
我现有的四分之一方法:
void ForQuarter(int year, int quarter)
{
// throw if quarter < 0 or quarter > 4
if (startYear == year && endYear == year
&& (((x.StartDate.Month + 2) / 3) == quarter && ((x.EndDate.Month + 2) / 3 == quarter)))
{
}
}
我现有的日期方法:
void ForDay(DateTime day)
{
if (x.StartDate.Date == day.Date && x.EndDate.Date == day.Date)
{
}
}
我还没有月份功能:
void ForMonth(int year, int month)
{
// throw if month < 1 or month > 12
if (...)
{
}
}
由于@JeanotZubler的回答,我能够修改他们的代码以适应其他场景。
如果有人想实现我想要的东西,这里是我的方法:
:
(year > startDate.Year || year == startDate.Year) && (year < endDate.Year || year == endDate.Year)
季度:
(year > startDate.Year || (year == startDate.Year && ((startDate.Month + 2) / 3) == quarter)) && (year < endDate.Year || (year == endDate.Year && ((endDate.Month + 2) / 3) == quarter))
:
(year > startDate.Year || (year == startDate.Year && startDate.Month == month)) && (year < endDate.Year || (year == endDate.Year && endDate.Month == month))
:
(year > startDate.Year || (year == startDate.Year && week >= ISOWeek.GetWeekOfYear(startDate))) && (year < endDate.Year || (year == endDate.Year && week <= ISOWeek.GetWeekOfYear(endDate)))
:
day >= startDate && day <= endDate
日期范围:
startDate >= start && endDate <= end
我会这样做:
方法有5个参数
type
周期类型查看(0 =天,1 =周,2 =月,3=季度)number
年内期数year
年看startDate
endDate
它是如何工作的:
- 首先,它确定
pstart
(即开始)的问题期间。这对于日、月和季度来说都很容易。对于一周的开始,您需要更多的代码(或相应的库为您计算) - 然后将整个周期添加到
pstart
(即1天,7天,1个月,3个月)。这将给出下一个周期的开始(即不包含在该周期中的的第一个瞬间)
有了这两个日期,现在可以很容易地检查
if (startDate <= pstart && endDate >= pend)
即,如果从[pstart, pend)
开始的整个周期包含在startDate
和endDate
之间。这使得对年份的显式检查不再使用。
计算pend
作为下一个周期的开始而不是当前周期的结束使比较更容易,因为您不必处理一天中的时间。例如,如果你正在检查2023年的第3个月和你的endDate = 2023-03-31T14:00:00
。这算不算被控制住。从技术上讲,它不是,因为march在2023-03-31-23:59:59.999999
结束,所以要正确处理这种情况,您需要将结束日期设置为2023-03-31T23:59:59.999999
,但根据系统的时间分辨率,这仍然会为错误留下(诚然很小)空间,通过将pend
设置为2023-04-01T00:00:00
可以消除错误。此外,这也使得找到一个月或一个季度的结束更容易,因为这些时期没有固定的天数。所以从3月1日得到3月31日和从4月1日得到4月30日是不同的。但是加上月份的数字总是会把你带到你想要的月份的1号。
public static bool isInRange(int type, int number, int year, DateTime startDate, DateTime endDate) {
DateTime pstart, pend;
switch (type) {
case 0: //day
if (number < 1 || number > (DateTime.IsLeapYear(year) ? 366 : 365)) throw new ArgumentException("invalid day");
//add number -1 days to Jan 1st
pstart = new DateTime(year, 1, 1).AddDays(number - 1); // the given day
pend = pstart.AddDays(1); //the next day
break;
case 1: //week
if (number < 1 || number > 53) throw new ArgumentException("invalid week");
//following ISO Week definition here, IE start of week is Monday, and first week of the year is the one
//with the first thursday in the year
pstart = new DateTime(year, 1, 1);
switch(pstart.DayOfWeek) {
case DayOfWeek.Sunday:
pstart = pstart.AddDays(1);
break;
case DayOfWeek.Tuesday:
pstart = pstart.AddDays(-1);
break;
case DayOfWeek.Wednesday:
pstart = pstart.AddDays(-2);
break;
case DayOfWeek.Thursday:
pstart = pstart.AddDays(-3);
break;
case DayOfWeek.Friday:
pstart = pstart.AddDays(3);
break;
case DayOfWeek.Saturday:
pstart = pstart.AddDays(2);
break;
default:
break;
}
//add number - 1 weeks to start of week 1
pstart = pstart.AddDays(7 * (number -1));
pend = pstart.AddDays(7);
break;
case 2: //month
if (number < 1 || number > 12) throw new ArgumentException("invalid month");
pstart = new DateTime(year, number, 1); //first day of given month
pend = pstart.AddMonths(1); //first day of next month
break;
case 3: //quarter
if (number < 1 || number > 4) throw new ArgumentException("invalid quarter");
pstart = new DateTime(year, 1 + (number -1) * 3, 1); //first day of the quarter
pend = pstart.AddMonths(3); //first day of next quarter
break;
default:
throw new ArgumentException("invalid type");
}
return startDate >= pstart && endDate < pend;
}