英文:
Check if week, quarter, day and month fall between dates
问题
以下是已翻译的代码部分:
我有多个选项要检查:
- 如果给定**年份**的**周**在**startDate**和**endDate**之间。
- 如果给定**年份**的**季度**在**startDate**和**endDate**之间。
- 如果给定**年份**的**月份**在**startDate**和**endDate**之间。
- 如果**日期**在**startDate**和**endDate**之间。
我的现有代码适用于**startDate**和**endDate**的**年份**相同的情况,但如果**startDate**或**endDate**在不同的**年份**中,它显然无法工作:
void ForWeek(int year, int week)
{
// 如果周数小于1或大于53,则抛出异常
if (startYear == year && endYear == year
&& (ISOWeek.GetWeekOfYear(x.StartDate) == week && ISOWeek.GetWeekOfYear(x.EndDate) == week))
{
// 在这里执行你的操作
}
}
我还需要一个能够处理**日期**、**月份**和**季度**的函数。
我的现有季度方法:
void ForQuarter(int year, int quarter)
{
// 如果季度小于0或大于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)
{
// 如果月份小于1或大于12,则抛出异常
if (...)
{
// 在这里执行你的操作
}
}
希望这些翻译对你有所帮助。
英文:
I have multiple options which I want to check:
- If a week of a given year is between startDate and
endDate. - If a quarter of a given year is between startDate and
endDate. - If a month of a given year is between startDate and
endDate. - If a day is between startDate and
endDate.
My existing code, which works fine for when the startDate year equals the endDate year, however if the startDate or endDate is in a different year it does not work obviously:
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))
{
}
}
I also need a function which does the same for day, month and quarter.
My existing quarter method:
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)))
{
}
}
My existing day method:
void ForDay(DateTime day)
{
if (x.StartDate.Date == day.Date && x.EndDate.Date == day.Date)
{
}
}
I do not have a month function yet:
void ForMonth(int year, int month)
{
// throw if month < 1 or month > 12
if (...)
{
}
}
答案1
得分: 1
由于@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
英文:
Due to @JeanotZubler's answer, I was able to modify their code in order to fit the other scenarios.
In case anyone would like to achieve the things I wanted, here are my methods:
Year:
(year > startDate.Year || year == startDate.Year) && (year < endDate.Year || year == endDate.Year)
Quarter:
(year > startDate.Year || (year == startDate.Year && ((startDate.Month + 2) / 3) == quarter)) && (year < endDate.Year || (year == endDate.Year && ((endDate.Month + 2) / 3) == quarter))
Month:
(year > startDate.Year || (year == startDate.Year && startDate.Month == month)) && (year < endDate.Year || (year == endDate.Year && endDate.Month == month))
Week:
(year > startDate.Year || (year == startDate.Year && week >= ISOWeek.GetWeekOfYear(startDate))) && (year < endDate.Year || (year == endDate.Year && week <= ISOWeek.GetWeekOfYear(endDate)))
Day:
day >= startDate && day <= endDate
Date range:
startDate >= start && endDate <= end
答案2
得分: 0
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("无效的日期");
//将number-1天添加到1月1日
pstart = new DateTime(year, 1, 1).AddDays(number - 1); // 给定日期
pend = pstart.AddDays(1); //下一天
break;
case 1: //周
if (number < 1 || number > 53) throw new ArgumentException("无效的周");
//遵循ISO周定义,即一周的开始是星期一,一年的第一周是那年的第一个星期四
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;
}
//将number - 1周添加到第1周的开始
pstart = pstart.AddDays(7 * (number -1));
pend = pstart.AddDays(7);
break;
case 2: //月
if (number < 1 || number > 12) throw new ArgumentException("无效的月份");
pstart = new DateTime(year, number, 1); //给定月份的第一天
pend = pstart.AddMonths(1); //下个月的第一天
break;
case 3: //季度
if (number < 1 || number > 4) throw new ArgumentException("无效的季度");
pstart = new DateTime(year, 1 + (number -1) * 3, 1); //季度的第一天
pend = pstart.AddMonths(3); //下个季度的第一天
break;
default:
throw new ArgumentException("无效的类型");
}
return startDate >= pstart && endDate < pend;
}
英文:
I'd do it as follows:
The methods takes 5 parameters
type
period type to look at (0 = day, 1 = week, 2 = month, 3= quarter)number
the number of the period within the yearyear
the year to look atstartDate
endDate
How does it work:
- First it determines the
pstart
(ie the beginning) of the period in question. This is quite easy for day, month and quarter. For the beginning of a week, you need a bit more code (or a respective library which calculates that for you) - Then add a whole period to that
pstart
(ie 1 day, 7 days, 1 month, 3 months). This gives you the beginning of the next period (ie the first instant in time that is not contained in the period in question)
With these two dates, you can now easily check
if (startDate <= pstart && endDate >= pend)
ie, if you whole period from [pstart, pend)
is contained between startDate
and endDate
. This makes an explicit check for the year obsolete.
Calculating pend
as the beginning of the next period instead of the end of the current period makes this comparison easier, because you don't have to deal with the time of the day. For instance if you are checking the 3rd month of 2023 and your endDate = 2023-03-31T14:00:00
. Should that count as contained or not. Technically it's not, because march ends at 2023-03-31-23:59:59.999999
So to handle this situation correctly, you would need to set the enddate to 2023-03-31T23:59:59.999999
but depending on the timeresolution of your system, this still leaves an (admittedly tiny) space for errors, which is eliminated by setting pend
to 2023-04-01T00:00:00
. Furthermore, this also makes finding the end of a month or and of a quarter easier, because those periods don't have a fixed number of days. So getting the 31st of March from the 1st of march is different from getting the 30th of April from the 1st of April. But adding a number of months will always bring you to the 1st of the desired month ...
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论