【问题标题】:How could I get months week number based on year week number (i.e week 33)如何根据年周数(即第 33 周)获得月周数
【发布时间】:2025-12-18 15:45:02
【问题描述】:

我想知道如何根据一年中一周的序数计算一个月的星期几。例如,我正在处理第 33 周,我应该知道那是 8 月的第 2 周。 我已经计算了几个月,但现在我要处理几周。

我已经有了解决方案,但对我来说似乎很脏..

代码如下:

var data = query.GroupBy(x => CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(x.CreatedDate ?? DateTime.UtcNow, CalendarWeekRule.FirstDay, DayOfWeek.Monday))
.Select(article => new ArticleSimpleObject
{
    Week = GetWeekNumberOfMonth(article.FirstOrDefault().CreatedDate.Value),
    Amount = article.Sum(x => x.Amount),
    Month = article.FirstOrDefault().CreatedDate.Value.Month
});

这是我用来获取周数的方法:

 private static int GetWeekNumberOfMonth(DateTime date)
 {
      date = date.Date;
      DateTime firstMonthDay = new DateTime(date.Year, date.Month, 1);
      DateTime firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
      if (firstMonthMonday > date)
      {
          firstMonthDay = firstMonthDay.AddMonths(-1);
          firstMonthMonday = firstMonthDay.AddDays((DayOfWeek.Monday + 7 - firstMonthDay.DayOfWeek) % 7);
       }
      return (date - firstMonthMonday).Days / 7 + 1;
  }

正如我写的,这个解决方案有效,

但我个人不喜欢它,我想有更优雅的解决方案,这就是为什么我发布这个问题来帮助自己和未来的读者,如果有经验的人帮助我们解决这个问题:)

也许这可以基于日历类https://docs.microsoft.com/en-us/dotnet/api/system.globalization.calendar?view=netframework-4.8来解决

我尝试了一些变体,但我什至没有接近解决它..

谢谢大家

干杯

【问题讨论】:

  • 当您已经有一个接受日期的GetWeekNumberOfMonth 方法时,为什么还需要根据序数计算月份中的星期几?
  • @mm8 是的,有一个 GetWeekNumberOfMonth 方法,但我想知道是否有更优雅的日历类或类似的解决方案。
  • 您的描述说根据一年中的一周计算一个月中的一周,但您的代码似乎与此无关。你真正想要完成的是什么?一周中的哪一天为您开启一周?

标签: c# linq datetime asp.net-core-webapi datetime-format


【解决方案1】:

一种方法是从日期所在年份的周数中减去该日期所在月份的第 1 天所在的年份周数。像这样:

void Main()
{
    Console.WriteLine(DateTime.Now.GetWeekOfMonth());       
}

public static class MyDateTimeExtensions
{
    private static GregorianCalendar _calendar = new GregorianCalendar();

    public static int GetWeekOfMonth(this DateTime date)
    {
        return 
            date.GetWeekOfYear()
            - new DateTime(date.Year, date.Month, 1).GetWeekOfYear()
            + 1;
    }

    private static int GetWeekOfYear(this DateTime date)
    {
        return _calendar.GetWeekOfYear(
            date, 
            CalendarWeekRule.FirstDay, 
            DayOfWeek.Sunday);
    }
}

当前日期为 4:2019 年 9 月 23 日。

【讨论】:

  • @khillang 你是对的,答案具有相同的方法。我应该检查现有的答案。
  • @NetMage 我发布的解决方案(被指出使用与先前答案相同的方法)不返回 0,而是在您提到的两个日期返回 1。然而,全周的问题很有趣,但在原始问题中没有提到。如果需要整周,您确实需要知道一周中的哪一天被认为是一周的第一天(传统上是星期日)。
  • @CarloBos 都在方法GetWeekNumberOfMonth的代码中。一周从星期一开始,第一周从每月的第一个星期一开始。
  • @CarloBos 你说得对,我想我错过了return末尾的+1
【解决方案2】:

您可以编写几个通用扩展来更简单地计算它。

首先,您需要从一周中的特定日期开始的一周中的第一个日期作为日期:

public static DateTime FirstDateOfWeekStarting(this DateTime aDate, DayOfWeek dow) => aDate.Date.AddDays((int)dow - (int)aDate.DayOfWeek);

然后,您可以轻松地将第一个日期的月份日期转换为该月的周数:

public static int WeekStartingDOWNumOfMonth(this DateTime aDate, DayOfWeek dow) => (aDate.FirstDateOfWeekStarting(dow).Day-1) / 7 + 1;

而且,对于从星期一开始的几周的具体情况,

public static int WeekStartingMonNumOfMonth(this DateTime aDate) => aDate.WeekStartingDOWNumOfMonth(DayOfWeek.Monday);

【讨论】: