检查周、季度、天和月份是否在日期范围内。

huangapple go评论75阅读模式
英文:

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 &gt; startDate.Year || year == startDate.Year) &amp;&amp; (year &lt; endDate.Year || year == endDate.Year)

Quarter:

(year &gt; startDate.Year || (year == startDate.Year &amp;&amp; ((startDate.Month + 2) / 3) == quarter)) &amp;&amp; (year &lt; endDate.Year || (year == endDate.Year &amp;&amp; ((endDate.Month + 2) / 3) == quarter))

Month:

(year &gt; startDate.Year || (year == startDate.Year &amp;&amp; startDate.Month == month)) &amp;&amp; (year &lt; endDate.Year || (year == endDate.Year &amp;&amp; endDate.Month == month))

Week:

(year &gt; startDate.Year || (year == startDate.Year &amp;&amp; week &gt;= ISOWeek.GetWeekOfYear(startDate))) &amp;&amp; (year &lt; endDate.Year || (year == endDate.Year &amp;&amp; week &lt;= ISOWeek.GetWeekOfYear(endDate)))

Day:

day &gt;= startDate &amp;&amp; day &lt;= endDate

Date range:

startDate &gt;= start &amp;&amp; endDate &lt;= 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 year
  • year the year to look at
  • startDate
  • 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 &lt;= pstart &amp;&amp; endDate &gt;= 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 &lt; 1 || number &gt; (DateTime.IsLeapYear(year) ? 366 : 365)) throw new ArgumentException(&quot;invalid day&quot;);
//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 &lt; 1 || number &gt; 53) throw new ArgumentException(&quot;invalid week&quot;);
//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 &lt; 1 || number &gt; 12) throw new ArgumentException(&quot;invalid month&quot;);
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 &lt; 1 || number &gt; 4) throw new ArgumentException(&quot;invalid quarter&quot;);
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(&quot;invalid type&quot;);
}
return startDate &gt;= pstart &amp;&amp; endDate &lt; pend;
}

huangapple
  • 本文由 发表于 2023年3月31日 18:18:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75897386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定