根据周数计算日期

发布于 2024-07-14 21:16:58 字数 68 浏览 13 评论 0 原文

任何人都知道一种简单的方法来获取一周第一天的日期(欧洲的星期一)。 我知道年份和周数吗? 我将在 C# 中执行此操作。

Anyone know an easy way to get the date of the first day in the week (monday here in Europe). I know the year and the week number? I'm going to do this in C#.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(26

七色彩虹 2024-07-21 21:16:59

最简单的方法可能是找到一年中的第一个星期一,然后添加相关的周数。 这是一些示例代码。 顺便说一句,它假定周数从 1 开始:

using System;

class Test
{
    static void Main()
    {
        // Show the third Tuesday in 2009. Should be January 20th
        Console.WriteLine(YearWeekDayToDateTime(2009, DayOfWeek.Tuesday, 3));
    }

    static DateTime YearWeekDayToDateTime(int year, DayOfWeek day, int week)
    {
        DateTime startOfYear = new DateTime (year, 1, 1);

        // The +7 and %7 stuff is to avoid negative numbers etc.
        int daysToFirstCorrectDay = (((int)day - (int)startOfYear.DayOfWeek) + 7) % 7;

        return startOfYear.AddDays(7 * (week-1) + daysToFirstCorrectDay);
    }
}

The easiest way is probably to find the first Monday of the year, and then add the relevant number of weeks. Here's some sample code. It assumes a week number starting at 1, by the way:

using System;

class Test
{
    static void Main()
    {
        // Show the third Tuesday in 2009. Should be January 20th
        Console.WriteLine(YearWeekDayToDateTime(2009, DayOfWeek.Tuesday, 3));
    }

    static DateTime YearWeekDayToDateTime(int year, DayOfWeek day, int week)
    {
        DateTime startOfYear = new DateTime (year, 1, 1);

        // The +7 and %7 stuff is to avoid negative numbers etc.
        int daysToFirstCorrectDay = (((int)day - (int)startOfYear.DayOfWeek) + 7) % 7;

        return startOfYear.AddDays(7 * (week-1) + daysToFirstCorrectDay);
    }
}
顾挽 2024-07-21 21:16:59

就我个人而言,我会利用文化信息来获取一周中的某一天,并循环到文化的一周第一天。 我不确定我的解释是否正确,这是一个例子:

    public DateTime GetFirstDayOfWeek(int year, int weekNumber)
    {
        return GetFirstDayOfWeek(year, weekNumber, Application.CurrentCulture);
    }

    public DateTime GetFirstDayOfWeek(int year, int weekNumber,
        System.Globalization.CultureInfo culture)
    {
        System.Globalization.Calendar calendar = culture.Calendar;
        DateTime firstOfYear = new DateTime(year, 1, 1, calendar);
        DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber);
        DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;

        while (targetDay.DayOfWeek != firstDayOfWeek)
        {
            targetDay = targetDay.AddDays(-1);
        }

        return targetDay;
    }

Personally I'd take advantage of the culture info to get the day of the week and loop down to the culture's first day of the week. I'm not sure if I'm explaining it properly, here's an example:

    public DateTime GetFirstDayOfWeek(int year, int weekNumber)
    {
        return GetFirstDayOfWeek(year, weekNumber, Application.CurrentCulture);
    }

    public DateTime GetFirstDayOfWeek(int year, int weekNumber,
        System.Globalization.CultureInfo culture)
    {
        System.Globalization.Calendar calendar = culture.Calendar;
        DateTime firstOfYear = new DateTime(year, 1, 1, calendar);
        DateTime targetDay = calendar.AddWeeks(firstOfYear, weekNumber);
        DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;

        while (targetDay.DayOfWeek != firstDayOfWeek)
        {
            targetDay = targetDay.AddDays(-1);
        }

        return targetDay;
    }
挽清梦 2024-07-21 21:16:59

使用 Fluent DateTime http://fluentdatetime.codeplex.com/

        var year = 2009;
        var firstDayOfYear = new DateTime(year, 1, 1);
        var firstMonday = firstDayOfYear.Next(DayOfWeek.Monday);
        var weeksDateTime = 12.Weeks().Since(firstMonday);

using Fluent DateTime http://fluentdatetime.codeplex.com/

        var year = 2009;
        var firstDayOfYear = new DateTime(year, 1, 1);
        var firstMonday = firstDayOfYear.Next(DayOfWeek.Monday);
        var weeksDateTime = 12.Weeks().Since(firstMonday);
无尽的现实 2024-07-21 21:16:59

这是一种与 Google Analytics 的周数兼容的方法,也与我们在英特尔内部使用的相同编号方案兼容,我确信它也在许多其他环境中使用。

// Google Analytics does not follow ISO standards for date.
// It numbers week 1 starting on Jan. 1, regardless what day of week it starts on.
// It treats Sunday as the first day of the week.
// The first and last weeks of a year are usually not complete weeks.
public static DateTime GetStartDateTimeFromWeekNumberInYear(int year, uint weekOfYear)
{
  if (weekOfYear == 0 || weekOfYear > 54) throw new ArgumentException("Week number must be between 1 and 54! (Yes, 54... Year 2000 had Jan. 1 on a Saturday plus 53 Sundays.)");

  // January 1 -- first week.
  DateTime firstDayInWeek = new DateTime(year, 1, 1);
  if (weekOfYear == 1) return firstDayInWeek;

  // Get second week, starting on the following Sunday.      
  do
  {
    firstDayInWeek = firstDayInWeek.AddDays(1);
  } while (firstDayInWeek.DayOfWeek != DayOfWeek.Sunday);

  if (weekOfYear == 2) return firstDayInWeek;

  // Now get the Sunday of whichever week we're looking for.
  return firstDayInWeek.AddDays((weekOfYear - 2)*7);
}

Here is a method that is compatible with the week numbers that Google Analytics, and also the same numbering scheme we used internally at Intel, and which I'm sure is also used in a lot of other contexts.

// Google Analytics does not follow ISO standards for date.
// It numbers week 1 starting on Jan. 1, regardless what day of week it starts on.
// It treats Sunday as the first day of the week.
// The first and last weeks of a year are usually not complete weeks.
public static DateTime GetStartDateTimeFromWeekNumberInYear(int year, uint weekOfYear)
{
  if (weekOfYear == 0 || weekOfYear > 54) throw new ArgumentException("Week number must be between 1 and 54! (Yes, 54... Year 2000 had Jan. 1 on a Saturday plus 53 Sundays.)");

  // January 1 -- first week.
  DateTime firstDayInWeek = new DateTime(year, 1, 1);
  if (weekOfYear == 1) return firstDayInWeek;

  // Get second week, starting on the following Sunday.      
  do
  {
    firstDayInWeek = firstDayInWeek.AddDays(1);
  } while (firstDayInWeek.DayOfWeek != DayOfWeek.Sunday);

  if (weekOfYear == 2) return firstDayInWeek;

  // Now get the Sunday of whichever week we're looking for.
  return firstDayInWeek.AddDays((weekOfYear - 2)*7);
}
遗心遗梦遗幸福 2024-07-21 21:16:59

稍微修改了 Mikael Svenson 代码。 我找到了第一个星期一所在的周并适当更改了周数。

 DateTime GetFirstWeekDay(int year, int weekNum)
    {
        Calendar calendar = CultureInfo.CurrentCulture.Calendar;

        DateTime jan1 = new DateTime(year, 1, 1);

        int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek;
        DateTime firstMonday = jan1.AddDays(daysOffset);
        int firstMondayWeekNum = calendar.GetWeekOfYear(firstMonday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

        DateTime firstWeekDay = firstMonday.AddDays((weekNum-firstMondayWeekNum) * 7);

        return firstWeekDay;
    }

Lightly changed Mikael Svenson code. I found the week of the first monday and appropriate change the week number.

 DateTime GetFirstWeekDay(int year, int weekNum)
    {
        Calendar calendar = CultureInfo.CurrentCulture.Calendar;

        DateTime jan1 = new DateTime(year, 1, 1);

        int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek;
        DateTime firstMonday = jan1.AddDays(daysOffset);
        int firstMondayWeekNum = calendar.GetWeekOfYear(firstMonday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

        DateTime firstWeekDay = firstMonday.AddDays((weekNum-firstMondayWeekNum) * 7);

        return firstWeekDay;
    }
段念尘 2024-07-21 21:16:59

根据瑞典使用的 ISO 8601:1988 标准,一年中的第一周是新的一年中至少有四天的第一周。

因此,如果您的一周从星期一开始,则任何一年的第一个星期四都在第一周内。
您可以从中添加 DateAdd 或 DateDiff 。

According to ISO 8601:1988 that is used in Sweden the first week of the year is the first week that has at least four days within the new year.

So if your week starts on a Monday the first Thursday any year is within the first week.
You can DateAdd or DateDiff from that.

猫瑾少女 2024-07-21 21:16:59

假设周数从 1 开始,

DateTime dt =  new DateTime(YearNumber, 1, 1).AddDays((WeekNumber - 1) * 7 - (WeekNumber == 1 ? 0 : 1));
return dt.AddDays(-(int)dt.DayOfWeek);

这将为您提供任何给定周的第一天。 我没有对其进行大量测试,但看起来它确实有效。 它比我在网上找到的大多数其他解决方案都要小,所以想分享。

Assuming the week number starts at 1

DateTime dt =  new DateTime(YearNumber, 1, 1).AddDays((WeekNumber - 1) * 7 - (WeekNumber == 1 ? 0 : 1));
return dt.AddDays(-(int)dt.DayOfWeek);

This should give you the first day in any given week. I haven't done a lot of testing on it, but looks like it works. It's smaller solution than most other's I found on the web, so wanted to share.

孤独患者 2024-07-21 21:16:59

免费的.NET 时间段库包括ISO 8601 符合类 Week

// ----------------------------------------------------------------------
public static DateTime GetFirstDayOfWeek( int year, int weekOfYear )
{
  return new Week( year, weekOfYear ).FirstDayStart;
} // GetFirstDayOfWeek

The free Time Period Library for .NET includes the ISO 8601 conform class Week:

// ----------------------------------------------------------------------
public static DateTime GetFirstDayOfWeek( int year, int weekOfYear )
{
  return new Week( year, weekOfYear ).FirstDayStart;
} // GetFirstDayOfWeek
沩ん囻菔务 2024-07-21 21:16:59

这个对我有用,它还有一个优点是期望以文化信息作为参数来测试不同文化的公式。 如果为空,它将获取当前的文化信息...有效值如下:“it”,“en-us”,“fr”,...等等。
诀窍是减去一年中第一天的周数,这可能是 1,表示第一天在第一周之内。 希望这可以帮助。

Public Shared Function FirstDayOfWeek(ByVal year As Integer, ByVal weekNumber As Integer, ByVal culture As String) As Date
    Dim cInfo As System.Globalization.CultureInfo
    If culture = "" Then
        cInfo = System.Globalization.CultureInfo.CurrentCulture
    Else
        cInfo = System.Globalization.CultureInfo.CreateSpecificCulture(culture)
    End If
    Dim calendar As System.Globalization.Calendar = cInfo.Calendar
    Dim firstOfYear As DateTime = New DateTime(year, 1, 1, calendar)
    Dim firstDayWeek As Integer = calendar.GetWeekOfYear(firstOfYear, cInfo.DateTimeFormat.CalendarWeekRule, cInfo.DateTimeFormat.FirstDayOfWeek)
    weekNumber -= firstDayWeek
    Dim targetDay As DateTime = calendar.AddWeeks(firstOfYear, weekNumber)
    Dim fDayOfWeek As DayOfWeek = cInfo.DateTimeFormat.FirstDayOfWeek

    While (targetDay.DayOfWeek <> fDayOfWeek)
        targetDay = targetDay.AddDays(-1)
    End While
    Return targetDay
End Function

This one worked for me, it also have the advantage of expecting a cultureinfo as parameter to test the formula with different cultures. If empty, it gets the current culture info... valid values are like: "it", "en-us", "fr", ... ando so on.
The trick is to subtract the week number of the first day of the year, that may be 1 to indicate that the first day is within the first week. Hope this helps.

Public Shared Function FirstDayOfWeek(ByVal year As Integer, ByVal weekNumber As Integer, ByVal culture As String) As Date
    Dim cInfo As System.Globalization.CultureInfo
    If culture = "" Then
        cInfo = System.Globalization.CultureInfo.CurrentCulture
    Else
        cInfo = System.Globalization.CultureInfo.CreateSpecificCulture(culture)
    End If
    Dim calendar As System.Globalization.Calendar = cInfo.Calendar
    Dim firstOfYear As DateTime = New DateTime(year, 1, 1, calendar)
    Dim firstDayWeek As Integer = calendar.GetWeekOfYear(firstOfYear, cInfo.DateTimeFormat.CalendarWeekRule, cInfo.DateTimeFormat.FirstDayOfWeek)
    weekNumber -= firstDayWeek
    Dim targetDay As DateTime = calendar.AddWeeks(firstOfYear, weekNumber)
    Dim fDayOfWeek As DayOfWeek = cInfo.DateTimeFormat.FirstDayOfWeek

    While (targetDay.DayOfWeek <> fDayOfWeek)
        targetDay = targetDay.AddDays(-1)
    End While
    Return targetDay
End Function
聽兲甴掵 2024-07-21 21:16:59

我尝试了上面的一些代码,有些有小错误,当你尝试不同的年份和不同的一周开始日期时,你会看到它们,我采用了 Jon Skeet 的代码,修复它并且它可以工作,非常简单的代码。

Public Function YearWeekDayToDateTime(ByVal year As Integer, ByVal weekDay As Integer, ByVal week As Integer) As DateTime
   ' weekDay, day you want
    Dim startOfYear As New DateTime(year, 1, 1)
    Dim startOfYearFixDay As Integer

    If startOfYear.DayOfWeek <> DayOfWeek.Sunday Then
        startOfYearFixDay = startOfYear.DayOfWeek
    Else
        startOfYearFixDay = 7
    End If

    Return startOfYear.AddDays((7 * (week)) - startOfYearFixDay + weekDay)
End Function

I tried some codes above and some have small mistakes, when you try different years with different starting days of week you will see them, I took the code of Jon Skeet, fix it and it works, very simple code.

Public Function YearWeekDayToDateTime(ByVal year As Integer, ByVal weekDay As Integer, ByVal week As Integer) As DateTime
   ' weekDay, day you want
    Dim startOfYear As New DateTime(year, 1, 1)
    Dim startOfYearFixDay As Integer

    If startOfYear.DayOfWeek <> DayOfWeek.Sunday Then
        startOfYearFixDay = startOfYear.DayOfWeek
    Else
        startOfYearFixDay = 7
    End If

    Return startOfYear.AddDays((7 * (week)) - startOfYearFixDay + weekDay)
End Function
梦明 2024-07-21 21:16:59

我简化了 Mikael Svensson 提供的代码,该代码对于欧洲许多国家/地区都是正确的。

public static DateTime FirstDateOfWeekIso8601(int year, int week)
{
        var firstThursdayOfYear = new DateTime(year, 1, 1);
        while (firstThursdayOfYear.DayOfWeek != DayOfWeek.Thursday)
        {
            firstThursdayOfYear = firstThursdayOfYear.AddDays(1);
        }

        var startDateOfWeekOne = firstThursdayOfYear.AddDays(-(DayOfWeek.Thursday - DayOfWeek.Monday));

        return startDateOfWeekOne.AddDays(7 * (week - 1));        
}

I simplified the code Mikael Svensson provided which is correct for many countries in Europe.

public static DateTime FirstDateOfWeekIso8601(int year, int week)
{
        var firstThursdayOfYear = new DateTime(year, 1, 1);
        while (firstThursdayOfYear.DayOfWeek != DayOfWeek.Thursday)
        {
            firstThursdayOfYear = firstThursdayOfYear.AddDays(1);
        }

        var startDateOfWeekOne = firstThursdayOfYear.AddDays(-(DayOfWeek.Thursday - DayOfWeek.Monday));

        return startDateOfWeekOne.AddDays(7 * (week - 1));        
}
若沐 2024-07-21 21:16:59

正如 khellang 所建议的(抱歉,我无法添加评论),使用 .NET Core 非常简单。 这是我的一段代码:

var today = DateTime.Today;
CultureInfo myCI = new CultureInfo("it-IT");
Calendar myCal = myCI.Calendar;
var weekNumber = myCal.GetWeekOfYear(today, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
var firstWeekDay = ISOWeek.ToDateTime(today.Year, weekNumber, DayOfWeek.Monday);

As suggested by khellang (sorry but I cannot add comments), with .NET Core is quite simple. This is my piece of code:

var today = DateTime.Today;
CultureInfo myCI = new CultureInfo("it-IT");
Calendar myCal = myCI.Calendar;
var weekNumber = myCal.GetWeekOfYear(today, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday);
var firstWeekDay = ISOWeek.ToDateTime(today.Year, weekNumber, DayOfWeek.Monday);
风渺 2024-07-21 21:16:59

第 1 周定义为从星期一开始并包含一年中第一个星期四的一周。

Week 1 is defined as being the week that starts on a Monday and contains the first Thursday of the year.

伪装你 2024-07-21 21:16:59

要双向转换,请参阅此处:有关 ISO 周日期的维基百科文章

To convert in both directions, see here: Wikipedia article on ISO week dates

楠木可依 2024-07-21 21:16:59

我通过覆盖对托马斯的解决方案进行了一些改进:

   public static DateTime FirstDateOfWeek(int year, int weekOfYear)
    {
      return Timer.FirstDateOfWeekOfMonth(year, 1, weekOfYear);
    }

    public static DateTime FirstDateOfWeekOfMonth(int year, int month, 
    int weekOfYear)
    {
      DateTime dtFirstDayOfMonth = new DateTime(year, month, 1);

       //I also commented out this part:
      /*
      if (firstWeek <= 1)
      {
        weekOfYear -= 1;
      }
      */

否则日期提前一周。

谢谢托马斯,很有帮助。

I improved a little on Thomas' solution with an override:

   public static DateTime FirstDateOfWeek(int year, int weekOfYear)
    {
      return Timer.FirstDateOfWeekOfMonth(year, 1, weekOfYear);
    }

    public static DateTime FirstDateOfWeekOfMonth(int year, int month, 
    int weekOfYear)
    {
      DateTime dtFirstDayOfMonth = new DateTime(year, month, 1);

       //I also commented out this part:
      /*
      if (firstWeek <= 1)
      {
        weekOfYear -= 1;
      }
      */

Otherwise the date was preceding by one week..

Thank you Thomas, great help.

初见终念 2024-07-21 21:16:59

我使用了其中一个解决方案,但它给了我错误的结果,仅仅是因为它将星期日算作一周的第一天。

我将: 更改

var firstDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber - 1) * 7);
var lastDay = firstDay.AddDays(6);

为:

var lastDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber) * 7);
var firstDay = lastDay.AddDays(-6);

现在它正在发挥作用。

I used one of the solutions but it gave me wrong results, simply because it counts Sunday as a first day of the week.

I changed:

var firstDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber - 1) * 7);
var lastDay = firstDay.AddDays(6);

to:

var lastDay = new DateTime(DateTime.Now.Year, 1, 1).AddDays((weekNumber) * 7);
var firstDay = lastDay.AddDays(-6);

and now it is working as a charm.

水水月牙 2024-07-21 21:16:59

建议的解决方案并不完整 - 它仅适用于 CalendarWeekRule.FirstFullWeek。 其他类型的周规则不起作用。 使用这个测试用例可以看出这一点:

foreach (CalendarWeekRule rule in Enum.GetValues(typeof(CalendarWeekRule)))
{
    for (int year = 1900; year < 2000; year++)
    {
        DateTime date = FirstDateOfWeek(year, 1, rule);
        Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, rule, DayOfWeek.Monday) == 1);
        Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(-1), rule, DayOfWeek.Monday) != 1);
    }
}

The proposed solution is not complete - it only works for CalendarWeekRule.FirstFullWeek. Other types of week rules do not work. This can be seen using this test case:

foreach (CalendarWeekRule rule in Enum.GetValues(typeof(CalendarWeekRule)))
{
    for (int year = 1900; year < 2000; year++)
    {
        DateTime date = FirstDateOfWeek(year, 1, rule);
        Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, rule, DayOfWeek.Monday) == 1);
        Assert(CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date.AddDays(-1), rule, DayOfWeek.Monday) != 1);
    }
}
花桑 2024-07-21 21:16:59

我对所提出的解决方案做了一个改进版本,它更简单,并且参数化了firstDayOfWeek:

public static DateTime GetFirstDayOfWeek(int year, int week, DayOfWeek firstDayOfWeek)
{
    return GetWeek1Day1(year, firstDayOfWeek).AddDays(7 * (week - 1));
}

public static DateTime GetWeek1Day1(int year, DayOfWeek firstDayOfWeek)
{
    DateTime date = new DateTime(year, 1, 1);

    // Move towards firstDayOfWeek
    date = date.AddDays(firstDayOfWeek - date.DayOfWeek);

    // Either 1 or 52 or 53
    int weekOfYear = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFullWeek, firstDayOfWeek);

    // Move forwards 1 week if week is 52 or 53
    date = date.AddDays(7 * System.Math.Sign(weekOfYear - 1));

    return date;
}

I have made a refined version of the proposed solution that is a simpler and parametrises the firstDayOfWeek:

public static DateTime GetFirstDayOfWeek(int year, int week, DayOfWeek firstDayOfWeek)
{
    return GetWeek1Day1(year, firstDayOfWeek).AddDays(7 * (week - 1));
}

public static DateTime GetWeek1Day1(int year, DayOfWeek firstDayOfWeek)
{
    DateTime date = new DateTime(year, 1, 1);

    // Move towards firstDayOfWeek
    date = date.AddDays(firstDayOfWeek - date.DayOfWeek);

    // Either 1 or 52 or 53
    int weekOfYear = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFullWeek, firstDayOfWeek);

    // Move forwards 1 week if week is 52 or 53
    date = date.AddDays(7 * System.Math.Sign(weekOfYear - 1));

    return date;
}
乖乖公主 2024-07-21 21:16:59

当我们想要计算给定年份、周数和星期几的日期时,这是我的解决方案。

int Year = 2014;
int Week = 48;
int DayOfWeek = 4;

DateTime FecIni = new DateTime(Year, 1, 1);
FecIni = FecIni.AddDays(7 * (Week - 1));
if ((int)FecIni.DayOfWeek > DayOfWeek)
{
    while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(-1);
}
else
{
    while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(1);
}

this is my solution when we want to calculate a date given year, week number and day of the week.

int Year = 2014;
int Week = 48;
int DayOfWeek = 4;

DateTime FecIni = new DateTime(Year, 1, 1);
FecIni = FecIni.AddDays(7 * (Week - 1));
if ((int)FecIni.DayOfWeek > DayOfWeek)
{
    while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(-1);
}
else
{
    while ((int)FecIni.DayOfWeek != DayOfWeek) FecIni = FecIni.AddDays(1);
}
您的好友蓝忘机已上羡 2024-07-21 21:16:59

我已经编写并测试了以下代码,并且对我来说工作得很好。 如果有人遇到此问题,请告诉我,我也发布了一个问题,以便获得最佳答案。 有人可能会发现它很有用。

public static DateTime GetFirstDateOfWeekByWeekNumber(int year, int weekNumber)
        {
            var date = new DateTime(year, 01, 01);
            var firstDayOfYear = date.DayOfWeek;
            var result = date.AddDays(weekNumber * 7);

            if (firstDayOfYear == DayOfWeek.Monday)
                return result.Date;
            if (firstDayOfYear == DayOfWeek.Tuesday)
                return result.AddDays(-1).Date;
            if (firstDayOfYear == DayOfWeek.Wednesday)
                return result.AddDays(-2).Date;
            if (firstDayOfYear == DayOfWeek.Thursday)
                return result.AddDays(-3).Date;
            if (firstDayOfYear == DayOfWeek.Friday)
                return result.AddDays(-4).Date;
            if (firstDayOfYear == DayOfWeek.Saturday)
                return result.AddDays(-5).Date;
            return result.AddDays(-6).Date;
        }

I have written and tested the following code and is working perfectly fine for me. Please let me know if anyone face trouble with this, I have posted a question as well in order to get the best possible answer. Someone may find it useful.

public static DateTime GetFirstDateOfWeekByWeekNumber(int year, int weekNumber)
        {
            var date = new DateTime(year, 01, 01);
            var firstDayOfYear = date.DayOfWeek;
            var result = date.AddDays(weekNumber * 7);

            if (firstDayOfYear == DayOfWeek.Monday)
                return result.Date;
            if (firstDayOfYear == DayOfWeek.Tuesday)
                return result.AddDays(-1).Date;
            if (firstDayOfYear == DayOfWeek.Wednesday)
                return result.AddDays(-2).Date;
            if (firstDayOfYear == DayOfWeek.Thursday)
                return result.AddDays(-3).Date;
            if (firstDayOfYear == DayOfWeek.Friday)
                return result.AddDays(-4).Date;
            if (firstDayOfYear == DayOfWeek.Saturday)
                return result.AddDays(-5).Date;
            return result.AddDays(-6).Date;
        }
不喜欢何必死缠烂打 2024-07-21 21:16:59

目前,没有 C# 类可以正确处理 ISO 8601week 数字。 尽管您可以实例化一种文化,寻找最接近的事物并纠正它,但我认为最好自己进行完整的计算:

    /// <summary>
    /// Converts a date to a week number.
    /// ISO 8601 week 1 is the week that contains the first Thursday that year.
    /// </summary>
    public static int ToIso8601Weeknumber(this DateTime date)
    {
        var thursday = date.AddDays(3 - date.DayOfWeek.DayOffset());
        return (thursday.DayOfYear - 1) / 7 + 1;
    }

    /// <summary>
    /// Converts a week number to a date.
    /// Note: Week 1 of a year may start in the previous year.
    /// ISO 8601 week 1 is the week that contains the first Thursday that year, so
    /// if December 28 is a Monday, December 31 is a Thursday,
    /// and week 1 starts January 4.
    /// If December 28 is a later day in the week, week 1 starts earlier.
    /// If December 28 is a Sunday, it is in the same week as Thursday January 1.
    /// </summary>
    public static DateTime FromIso8601Weeknumber(int weekNumber, int? year = null, DayOfWeek day = DayOfWeek.Monday)
    {
        var dec28 = new DateTime((year ?? DateTime.Today.Year) - 1, 12, 28);
        var monday = dec28.AddDays(7 * weekNumber - dec28.DayOfWeek.DayOffset());
        return monday.AddDays(day.DayOffset());
    }

    /// <summary>
    /// Iso8601 weeks start on Monday. This returns 0 for Monday.
    /// </summary>
    private static int DayOffset(this DayOfWeek weekDay)
    {
        return ((int)weekDay + 6) % 7;
    }

Currently, there is no C# class that correctly handles ISO 8601week numbers. Even though you can instantiate a culture, look for the closest thing and correct that, I think it is better to do the complete calculation yourself:

    /// <summary>
    /// Converts a date to a week number.
    /// ISO 8601 week 1 is the week that contains the first Thursday that year.
    /// </summary>
    public static int ToIso8601Weeknumber(this DateTime date)
    {
        var thursday = date.AddDays(3 - date.DayOfWeek.DayOffset());
        return (thursday.DayOfYear - 1) / 7 + 1;
    }

    /// <summary>
    /// Converts a week number to a date.
    /// Note: Week 1 of a year may start in the previous year.
    /// ISO 8601 week 1 is the week that contains the first Thursday that year, so
    /// if December 28 is a Monday, December 31 is a Thursday,
    /// and week 1 starts January 4.
    /// If December 28 is a later day in the week, week 1 starts earlier.
    /// If December 28 is a Sunday, it is in the same week as Thursday January 1.
    /// </summary>
    public static DateTime FromIso8601Weeknumber(int weekNumber, int? year = null, DayOfWeek day = DayOfWeek.Monday)
    {
        var dec28 = new DateTime((year ?? DateTime.Today.Year) - 1, 12, 28);
        var monday = dec28.AddDays(7 * weekNumber - dec28.DayOfWeek.DayOffset());
        return monday.AddDays(day.DayOffset());
    }

    /// <summary>
    /// Iso8601 weeks start on Monday. This returns 0 for Monday.
    /// </summary>
    private static int DayOffset(this DayOfWeek weekDay)
    {
        return ((int)weekDay + 6) % 7;
    }
≈。彩虹 2024-07-21 21:16:59

我发现的最大问题之一是将周转换为日期,然后从日期转换为周。

主要问题是当尝试从属于上一年一周的日期获取正确的星期年份时。 幸运的是 System.Globalization.ISOWeek.GetYear 可以处理这个问题。

这是我的解决方案:

public class WeekOfYear
{
    public static (int Year, int Week) DateToWeekOfYear(DateTime date) =>
        (ISOWeek.GetYear(date), ISOWeek.GetWeekOfYear(date));

    public static bool ValidYearAndWeek(int year, int week) =>
           year >= 1 && year <= 9999 && week >= 1 && week <= 53 // bounds of year/week
        && !(year <= 1 && week <= 1) && !(year >= 9999 && week >= 53); // bounds of DateTime

    public int Year { get; }
    public int Week { get; }
    public virtual DateTime StartOfWeek { get; protected set; }
    public virtual DateTime EndOfWeek { get; protected set; }

    public virtual IEnumerable<DateTime> DaysInWeek =>
        Enumerable.Range(1, 10).Select(i => StartOfWeek.AddDays(i));

    public WeekOfYear(int year, int week)
    {
        if (!ValidYearAndWeek(year, week))
            throw new ArgumentException($"DateTime can't represent {week} of year {year}.");

        Year = year;
        Week = week;
        StartOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Monday);
        EndOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Sunday).AddDays(1).AddTicks(-1);
    }

    public WeekOfYear((int Year, int Week) week) : this(week.Year, week.Week) { }
    public WeekOfYear(DateTime date) : this(DateToWeekOfYear(date)) { }
}

第二大问题是美国偏好从周日开始的几周。

我从上面提出了子类 WeekOfYear 的解决方案,并管理构造函数中的偏移量(将周转换为日期)和 DateToWeekOfYear (将日期转换为周) )。

public class UsWeekOfYear : WeekOfYear
{
    public static new (int Year, int Week) DateToWeekOfYear(DateTime date)
    {
        // if date is a sunday, return the next week
        if (date.DayOfWeek == DayOfWeek.Sunday) date = date.AddDays(1);
        return WeekOfYear.DateToWeekOfYear(date);
    }

    public UsWeekOfYear(int year, int week) : base(year, week)
    {
        StartOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Monday).AddDays(-1);
        EndOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Sunday).AddTicks(-1);
    }

    public UsWeekOfYear((int Year, int Week) week) : this(week.Year, week.Week) { }
    public UsWeekOfYear(DateTime date) : this(DateToWeekOfYear(date)) { }
}

这是一些测试代码:

public static void Main(string[] args)
{
    Console.WriteLine("== Last Week / First Week");
    Log(new WeekOfYear(2020, 53));
    Log(new UsWeekOfYear(2020, 53));

    Log(new WeekOfYear(2021, 1));
    Log(new UsWeekOfYear(2021, 1));

    Console.WriteLine("\n== Year Crossover (iso)");
    var start = new DateTime(2020, 12, 26);
    var i = 0;
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-26 - Sat
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-27 - Sun
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-28 - Mon
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-29 - Tue
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-30 - Wed
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-30 - Thu
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-01 - Fri
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-02 - Sat
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-03 - Sun
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-04 - Mon
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-05 - Tue
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-06 - Wed

    Console.WriteLine("\n== Year Crossover (us)");
    i = 0;
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-26 - Sat
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-27 - Sun
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-28 - Mon
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-29 - Tue
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-30 - Wed
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-30 - Thu
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-01 - Fri
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-02 - Sat
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-03 - Sun
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-04 - Mon
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-05 - Tue
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-06 - Wed

    var x = new UsWeekOfYear(2020, 53) as WeekOfYear;
}

public static void Log(WeekOfYear week)
{
    Console.WriteLine($"{week} - {week.StartOfWeek:yyyy-MM-dd} ({week.StartOfWeek:ddd}) - {week.EndOfWeek:yyyy-MM-dd} ({week.EndOfWeek:ddd})");
}

public static void Log(DateTime date, WeekOfYear week)
{
    Console.WriteLine($"{date:yyyy-MM-dd (ddd)} - {week} - {week.StartOfWeek:yyyy-MM-dd (ddd)} - {week.EndOfWeek:yyyy-MM-dd (ddd)}");
}

One of the biggest problems I found was to convert from weeks to dates, and then from dates to weeks.

The main problem is when trying to get the correct week year from a date that belongs to a week of the previous year. Luckily System.Globalization.ISOWeek.GetYear handles this.

Here is my solution:

public class WeekOfYear
{
    public static (int Year, int Week) DateToWeekOfYear(DateTime date) =>
        (ISOWeek.GetYear(date), ISOWeek.GetWeekOfYear(date));

    public static bool ValidYearAndWeek(int year, int week) =>
           year >= 1 && year <= 9999 && week >= 1 && week <= 53 // bounds of year/week
        && !(year <= 1 && week <= 1) && !(year >= 9999 && week >= 53); // bounds of DateTime

    public int Year { get; }
    public int Week { get; }
    public virtual DateTime StartOfWeek { get; protected set; }
    public virtual DateTime EndOfWeek { get; protected set; }

    public virtual IEnumerable<DateTime> DaysInWeek =>
        Enumerable.Range(1, 10).Select(i => StartOfWeek.AddDays(i));

    public WeekOfYear(int year, int week)
    {
        if (!ValidYearAndWeek(year, week))
            throw new ArgumentException(
quot;DateTime can't represent {week} of year {year}.");

        Year = year;
        Week = week;
        StartOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Monday);
        EndOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Sunday).AddDays(1).AddTicks(-1);
    }

    public WeekOfYear((int Year, int Week) week) : this(week.Year, week.Week) { }
    public WeekOfYear(DateTime date) : this(DateToWeekOfYear(date)) { }
}

The second biggest problem was the preference for weeks starting on Sundays in the US.

The solution I cam up with subclasses WeekOfYear from above, and manages the offset of the in the constructor (which converts week to dates) and DateToWeekOfYear (which converts from date to week).

public class UsWeekOfYear : WeekOfYear
{
    public static new (int Year, int Week) DateToWeekOfYear(DateTime date)
    {
        // if date is a sunday, return the next week
        if (date.DayOfWeek == DayOfWeek.Sunday) date = date.AddDays(1);
        return WeekOfYear.DateToWeekOfYear(date);
    }

    public UsWeekOfYear(int year, int week) : base(year, week)
    {
        StartOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Monday).AddDays(-1);
        EndOfWeek = ISOWeek.ToDateTime(year, week, DayOfWeek.Sunday).AddTicks(-1);
    }

    public UsWeekOfYear((int Year, int Week) week) : this(week.Year, week.Week) { }
    public UsWeekOfYear(DateTime date) : this(DateToWeekOfYear(date)) { }
}

Here is some test code:

public static void Main(string[] args)
{
    Console.WriteLine("== Last Week / First Week");
    Log(new WeekOfYear(2020, 53));
    Log(new UsWeekOfYear(2020, 53));

    Log(new WeekOfYear(2021, 1));
    Log(new UsWeekOfYear(2021, 1));

    Console.WriteLine("\n== Year Crossover (iso)");
    var start = new DateTime(2020, 12, 26);
    var i = 0;
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-26 - Sat
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-27 - Sun
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-28 - Mon
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-29 - Tue
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-30 - Wed
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2020-12-30 - Thu
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-01 - Fri
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-02 - Sat
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-03 - Sun
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-04 - Mon
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-05 - Tue
    Log(start.AddDays(i), new WeekOfYear(start.AddDays(i++))); // 2021-01-06 - Wed

    Console.WriteLine("\n== Year Crossover (us)");
    i = 0;
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-26 - Sat
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-27 - Sun
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-28 - Mon
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-29 - Tue
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-30 - Wed
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2020-12-30 - Thu
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-01 - Fri
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-02 - Sat
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-03 - Sun
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-04 - Mon
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-05 - Tue
    Log(start.AddDays(i), new UsWeekOfYear(start.AddDays(i++))); // 2021-01-06 - Wed

    var x = new UsWeekOfYear(2020, 53) as WeekOfYear;
}

public static void Log(WeekOfYear week)
{
    Console.WriteLine(
quot;{week} - {week.StartOfWeek:yyyy-MM-dd} ({week.StartOfWeek:ddd}) - {week.EndOfWeek:yyyy-MM-dd} ({week.EndOfWeek:ddd})");
}

public static void Log(DateTime date, WeekOfYear week)
{
    Console.WriteLine(
quot;{date:yyyy-MM-dd (ddd)} - {week} - {week.StartOfWeek:yyyy-MM-dd (ddd)} - {week.EndOfWeek:yyyy-MM-dd (ddd)}");
}
相对绾红妆 2024-07-21 21:16:58

即使 @RobinAndersson 进行了修复,我也对 @HenkHolterman 的解决方案有疑问。

阅读 ISO 8601 标准可以很好地解决这个问题。 使用第一个星期四作为目标,而不是星期一。 下面的代码也适用于 2009 年第 53 周。

public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
{
    DateTime jan1 = new DateTime(year, 1, 1);
    int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;

    // Use first Thursday in January to get first week of the year as
    // it will never be in Week 52/53
    DateTime firstThursday = jan1.AddDays(daysOffset);
    var cal = CultureInfo.CurrentCulture.Calendar;
    int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

    var weekNum = weekOfYear;
    // As we're adding days to a date in Week 1,
    // we need to subtract 1 in order to get the right date for week #1
    if (firstWeek == 1)
    {
        weekNum -= 1;
    }

    // Using the first Thursday as starting week ensures that we are starting in the right year
    // then we add number of weeks multiplied with days
    var result = firstThursday.AddDays(weekNum * 7);

    // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601
    return result.AddDays(-3);
}       

I had issues with the solution by @HenkHolterman even with the fix by @RobinAndersson.

Reading up on the ISO 8601 standard resolves the issue nicely. Use the first Thursday as the target and not Monday. The code below will work for Week 53 of 2009 as well.

public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
{
    DateTime jan1 = new DateTime(year, 1, 1);
    int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;

    // Use first Thursday in January to get first week of the year as
    // it will never be in Week 52/53
    DateTime firstThursday = jan1.AddDays(daysOffset);
    var cal = CultureInfo.CurrentCulture.Calendar;
    int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

    var weekNum = weekOfYear;
    // As we're adding days to a date in Week 1,
    // we need to subtract 1 in order to get the right date for week #1
    if (firstWeek == 1)
    {
        weekNum -= 1;
    }

    // Using the first Thursday as starting week ensures that we are starting in the right year
    // then we add number of weeks multiplied with days
    var result = firstThursday.AddDays(weekNum * 7);

    // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601
    return result.AddDays(-3);
}       
冷夜 2024-07-21 21:16:58

注意

以下答案使用 .NET 日历规则。 它不承诺符合 ISO8601。 当您需要时,请参阅此处的一些其他答案。 周编号是一团糟,总是先尝试找出需要遵循的规则。


下面的代码正确地将 2009 年第 1 周的开始时间定为 2008 年 12 月 29 日。 CalendarWeekRule 可能应该是一个参数。

请注意,weekNum 应该 >= 1

static DateTime FirstDateOfWeek(int year, int weekNum, CalendarWeekRule rule)
{
    Debug.Assert(weekNum >= 1);

    DateTime jan1 = new DateTime(year, 1, 1);

    int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek;
    DateTime firstMonday = jan1.AddDays(daysOffset);
    Debug.Assert(firstMonday.DayOfWeek == DayOfWeek.Monday);

    var cal = CultureInfo.CurrentCulture.Calendar;
    int firstWeek = cal.GetWeekOfYear(firstMonday, rule, DayOfWeek.Monday);

    if (firstWeek <= 1)
    {
        weekNum -= 1;
    }

    DateTime result = firstMonday.AddDays(weekNum * 7);

    return result;
}

Note

The below answer uses the .NET Calendar rules. It does not promise ISO8601 conformance. See some of the other answers here when you need that. Week numbering is a mess, always try to find out what rules you need to follow first.


The code below correctly puts the start of week 1, 2009 at 29-12-2008. The CalendarWeekRule probably should be a parameter.

Note that the weekNum should be >= 1

static DateTime FirstDateOfWeek(int year, int weekNum, CalendarWeekRule rule)
{
    Debug.Assert(weekNum >= 1);

    DateTime jan1 = new DateTime(year, 1, 1);

    int daysOffset = DayOfWeek.Monday - jan1.DayOfWeek;
    DateTime firstMonday = jan1.AddDays(daysOffset);
    Debug.Assert(firstMonday.DayOfWeek == DayOfWeek.Monday);

    var cal = CultureInfo.CurrentCulture.Calendar;
    int firstWeek = cal.GetWeekOfYear(firstMonday, rule, DayOfWeek.Monday);

    if (firstWeek <= 1)
    {
        weekNum -= 1;
    }

    DateTime result = firstMonday.AddDays(weekNum * 7);

    return result;
}
咋地 2024-07-21 21:16:58

更新:.NET Core 3.0 和 .NET Standard 2.1 已随此类型一起提供。

好消息! 将 System.Globalization.ISOWeek 添加到 .NET 的拉取请求 Core 刚刚合并,目前计划发布 3.0 版本。 希望它能在不久的将来传播到其他 .NET 平台。

您应该能够使用 ISOWeek.ToDateTime(intyear, int week, DayOfWeek dayOfWeek) 方法来计算此值。

您可以找到源代码 此处

UPDATE: .NET Core 3.0 and .NET Standard 2.1 has shipped with this type.

Good news! A pull request adding System.Globalization.ISOWeek to .NET Core was just merged and is currently slated for the 3.0 release. Hopefully it will propagate to the other .NET platforms in a not-too-distant future.

You should be able to use the ISOWeek.ToDateTime(int year, int week, DayOfWeek dayOfWeek) method to calculate this.

You can find the source code here.

醉酒的小男人 2024-07-21 21:16:58

我喜欢 Henk Holterman 提供的解决方案。 但为了更加独立于文化,您必须获得当前文化的一周的第一天(并不总是星期一):

using System.Globalization;

static DateTime FirstDateOfWeek(int year, int weekOfYear)
{
  DateTime jan1 = new DateTime(year, 1, 1);

  int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;

  DateTime firstMonday = jan1.AddDays(daysOffset);

  int firstWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);

  if (firstWeek <= 1)
  {
    weekOfYear -= 1;
  }

  return firstMonday.AddDays(weekOfYear * 7);
}

I like the solution provided by Henk Holterman. But to be a little more culture independent, you have to get the first day of the week for the current culture ( it's not always monday ):

using System.Globalization;

static DateTime FirstDateOfWeek(int year, int weekOfYear)
{
  DateTime jan1 = new DateTime(year, 1, 1);

  int daysOffset = (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - (int)jan1.DayOfWeek;

  DateTime firstMonday = jan1.AddDays(daysOffset);

  int firstWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(jan1, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);

  if (firstWeek <= 1)
  {
    weekOfYear -= 1;
  }

  return firstMonday.AddDays(weekOfYear * 7);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文