计算从 4 月开始的年份的周数
Calculate week numbers with year starting in April
我正在尝试根据特定规则计算周数。我正在寻找的规则示例是:
Week 1 = first week of the year which containers 1st April.
示例数据:
Week 1 March 27, 2017 April 2, 2017
...
Week 23 September 4, 2017 September 10, 2017
我发现了一个类似的问题 - Getting Week number of year starting from April - 并以此为指导,我提出了以下在未来特定日期有效的问题。然而,截止时间早于当前一周的日期时间会导致问题。
LocalDate firstOne = LocalDate.FromDateTime(dateTime);
int targetYear = firstOne.Month > 4 || firstOne.Month == 4 && firstOne.Day >= 1 ? firstOne.Year : firstOne.Year - 1;
LocalDate start = new LocalDate(targetYear, 4, 1);
int days = Period.Between(start, firstOne, PeriodUnits.Days).Days;
int targetWeek = (days / 7) + 1;
if (targetWeek >= 52)
{
// if we are greater than 52 then we are technically in week 1 of the following year; eg 31st March 2017.
// Remove the "year" from the week count and move the year counter back to the correct year.
targetWeek -= 52;
targetYear++;
}
return (targetYear, targetWeek);
当前的问题是,如果我在 2017 年 3 月 27 日通过,也就是 1 日之后的 7 天内,它仍然会给出前一年和第 52 周。我想我需要以某种方式考虑周开始日(?!).
我如何解决这个问题取决于您需要做什么。在 Noda Time 2.0(并向后移植到 1.4)中,有一个 IWeekYearRule
接口可以实现,如果你想彻底做到这一点。
如果你只是需要计算年和周数,而不需要相反的方向,我会这样做:
- 找到与给定日历年对应的周年的开始
- 检查传入的日期是否在当天或之后
- 如果是这样,请使用该周开始的年份进行计算
- 否则,计算前一周年的开始,并使用它
使用 DateAdjusters.PreviousOrSame
查找一周年的开始真的很容易,因为您可以说 "It's the Monday on or immediately before April 1st"(根据需要调整星期几)。
这是一个完整的示例,带有示例结果:
using System;
using NodaTime;
class Test
{
static void Main()
{
ShowDate(2017, 1, 1);
ShowDate(2017, 3, 27);
ShowDate(2017, 9, 7);
}
private static void ShowDate(int year, int month, int day)
{
var date = new LocalDate(year, month, day);
var result = GetWeekYearAndWeek(date);
Console.WriteLine($"{date:uuuu-MM-dd} => {result}");
}
private static (int weekYear, int week) GetWeekYearAndWeek(LocalDate date)
{
// Initial guess...
int weekYear = date.Year;
var startOfWeekYear = GetStartOfWeekYear(weekYear);
if (date < startOfWeekYear)
{
weekYear--;
startOfWeekYear = GetStartOfWeekYear(weekYear);
}
int days = Period.Between(startOfWeekYear, date, PeriodUnits.Days).Days;
int week = (days / 7) + 1;
return (weekYear, week);
}
private const IsoDayOfWeek StartOfWeek = IsoDayOfWeek.Monday;
private static LocalDate GetStartOfWeekYear(int weekYear) =>
new LocalDate(weekYear, 4, 1).With(DateAdjusters.PreviousOrSame(StartOfWeek));
}
输出:
2017-01-01 => (2016, 40)
2017-03-27 => (2017, 1)
2017-09-07 => (2017, 24)
我正在尝试根据特定规则计算周数。我正在寻找的规则示例是:
Week 1 = first week of the year which containers 1st April.
示例数据:
Week 1 March 27, 2017 April 2, 2017
...
Week 23 September 4, 2017 September 10, 2017
我发现了一个类似的问题 - Getting Week number of year starting from April - 并以此为指导,我提出了以下在未来特定日期有效的问题。然而,截止时间早于当前一周的日期时间会导致问题。
LocalDate firstOne = LocalDate.FromDateTime(dateTime);
int targetYear = firstOne.Month > 4 || firstOne.Month == 4 && firstOne.Day >= 1 ? firstOne.Year : firstOne.Year - 1;
LocalDate start = new LocalDate(targetYear, 4, 1);
int days = Period.Between(start, firstOne, PeriodUnits.Days).Days;
int targetWeek = (days / 7) + 1;
if (targetWeek >= 52)
{
// if we are greater than 52 then we are technically in week 1 of the following year; eg 31st March 2017.
// Remove the "year" from the week count and move the year counter back to the correct year.
targetWeek -= 52;
targetYear++;
}
return (targetYear, targetWeek);
当前的问题是,如果我在 2017 年 3 月 27 日通过,也就是 1 日之后的 7 天内,它仍然会给出前一年和第 52 周。我想我需要以某种方式考虑周开始日(?!).
我如何解决这个问题取决于您需要做什么。在 Noda Time 2.0(并向后移植到 1.4)中,有一个 IWeekYearRule
接口可以实现,如果你想彻底做到这一点。
如果你只是需要计算年和周数,而不需要相反的方向,我会这样做:
- 找到与给定日历年对应的周年的开始
- 检查传入的日期是否在当天或之后
- 如果是这样,请使用该周开始的年份进行计算
- 否则,计算前一周年的开始,并使用它
使用 DateAdjusters.PreviousOrSame
查找一周年的开始真的很容易,因为您可以说 "It's the Monday on or immediately before April 1st"(根据需要调整星期几)。
这是一个完整的示例,带有示例结果:
using System;
using NodaTime;
class Test
{
static void Main()
{
ShowDate(2017, 1, 1);
ShowDate(2017, 3, 27);
ShowDate(2017, 9, 7);
}
private static void ShowDate(int year, int month, int day)
{
var date = new LocalDate(year, month, day);
var result = GetWeekYearAndWeek(date);
Console.WriteLine($"{date:uuuu-MM-dd} => {result}");
}
private static (int weekYear, int week) GetWeekYearAndWeek(LocalDate date)
{
// Initial guess...
int weekYear = date.Year;
var startOfWeekYear = GetStartOfWeekYear(weekYear);
if (date < startOfWeekYear)
{
weekYear--;
startOfWeekYear = GetStartOfWeekYear(weekYear);
}
int days = Period.Between(startOfWeekYear, date, PeriodUnits.Days).Days;
int week = (days / 7) + 1;
return (weekYear, week);
}
private const IsoDayOfWeek StartOfWeek = IsoDayOfWeek.Monday;
private static LocalDate GetStartOfWeekYear(int weekYear) =>
new LocalDate(weekYear, 4, 1).With(DateAdjusters.PreviousOrSame(StartOfWeek));
}
输出:
2017-01-01 => (2016, 40)
2017-03-27 => (2017, 1)
2017-09-07 => (2017, 24)