【问题标题】:In .net, knowing the week number how can I get the weekdays date?在 .net 中,知道周数如何获取工作日日期?
【发布时间】:2011-04-20 17:53:16
【问题描述】:

我想在 C# 中创建一个函数,它会在一周内返回我的天数。

例如第 40 周,我怎样才能得到天数: 4/10、5/10、6/10、7/10、8/10、9/10、10/10。

提前谢谢你!

【问题讨论】:

标签: .net datetime week-number dayofweek


【解决方案1】:

我认为这应该做你想做的:

    public static DateTime[] WeekDays(int Year, int WeekNumber)
    {
        DateTime start = new DateTime(Year, 1, 1).AddDays(7 * WeekNumber);
        start = start.AddDays(-((int)start.DayOfWeek));
        return Enumerable.Range(0, 7).Select(num => start.AddDays(num)).ToArray();
    }

虽然我将星期日视为一周的第一天,但​​如果您想将星期一作为第一天,则更改范围从 (0,7) 到 (1,7)。

如果您想符合 ISO 标准,我认为这应该可行:

    public static DateTime[] WeekDays(int Year, int WeekNumber)
    {
        DateTime start = new DateTime(Year, 1, 4);
        start = start.AddDays(-((int)start.DayOfWeek));
        start = start.AddDays(7 * (WeekNumber - 1));
        return Enumerable.Range(0, 7).Select(num => start.AddDays(num)).ToArray();
    }

【讨论】:

  • 这基本上取决于你在世界的哪个地方,因为在欧洲第 1 周是第一周有 4 天,而在美国是第 1 周有 1/1 (en.wikipedia.org/wiki/Seven-day_week#Week_numbering) - 所以代码是正确的,除了“基础”可能需要调整。
  • 据我记得一个较老的项目,上面的代码在使用 ISO-Weeks(欧洲经常使用的 8601)计算时也不起作用,如果基数会被调整(见我的回答)。但也许 .net4 改变了这种情况。
  • 是的,你是对的,它不符合 ISO 标准。可以很容易地调整以符合标准。将投入和更正。
  • 谢谢,我用了另一个函数,但主要思想是一样的。
  • 我在自己的答案中提供了计算 ISO 周日期的正确方法。我发现大多数人都弄错了,并认为保留此代码是个好主意。它不会做任何奇怪的事情,而是尽可能使用 .NET API 来获得正确的结果。
【解决方案2】:

注意

我似乎错过了错误。当前代码已于 2012 年 1 月 30 日更新以说明这一事实,我们现在根据周二推导出 daysOffset,根据 Mikael Svenson 似乎可以解决问题。有关详细信息,请参阅此answer

大多数人往往会误解这一点,我所说的错误是指不符合 ISO8601 周日期(我们在瑞典经常使用这个)标准。这个计算有点奇怪,但归结为 .NET 中的这段代码:

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

int daysOffset = DayOfWeek.Tuesday - jan1.DayOfWeek;

DateTime firstMonday = jan1.AddDays(daysOffset);

var cal = CultureInfo.CurrentCulture.Calendar;

int firstWeek = cal.GetWeekOfYear(jan1, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

var weekNum = ww;

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

var result = firstMonday.AddDays(weekNum * 7 + d - 1);

return result;

它将计算一年中的日期 (yyyy)、星期数 (ww) 和星期几 (d)。它首先使用内置日历建立一月一日(因此可以自定义此代码)。这有点奇怪的原因是第 53 周有时发生在 1 月,有时第 1 周发生在 12 月。

如果您需要另辟蹊径,这并不完全是微不足道的,但此处显示了在 .NET 中执行此操作的正确方法。

var c = CultureInfo.CurrentCulture.Calendar;

// `FromDayOfWeek` fixes problem with the enumeration
// not based on Monday being the first day of the week
d = (byte)FromDayOfWeek(c.GetDayOfWeek(t));
switch (d)
{
    case 1:
    case 2:
    case 3:
        // see this for details
        // http://blogs.msdn.com/shawnste/archive/2006/01/24/iso-8601-week-of-year-format-in-microsoft-net.aspx
        t = t.AddDays(3);
        break;
}

ww = (byte)c.GetWeekOfYear(t, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

// Adjust year when week 53 occurs in January or week 1 occurs in December 
if (ww == 53 && t.Month == 1)
{
    yyyy = (short)(t.Year - 1);
}
else if (ww == 1 && t.Month == 12)
{
    yyyy = (short)(t.Year + 1);
}
else
{
    yyyy = (short)t.Year;
}

【讨论】:

    【解决方案3】:

    以下函数将帮助您从周数和年份获取开始日期

    public DateTime GetFirstDayFromWeekNumber(int weekNumber, int weekYear)
            {
                DateTime beginingYear = new DateTime(weekYear, 1, 1);
                DateTime finalDate = new DateTime();
                int maxDayOfWeek = (int)DayOfWeek.Saturday;
                int yearStartDay = (int)beginingYear.DayOfWeek;
                int dayDeference = maxDayOfWeek - yearStartDay;
    
                if (weekNumber == 1)
                {
                    finalDate = beginingYear.AddDays(-yearStartDay);
                }
                else if (weekNumber == 2)
                {
                    finalDate = beginingYear.AddDays((dayDeference + 1));
                }
                else if (weekNumber > 2 && weekNumber <= 53)
                {
                    finalDate = beginingYear.AddDays((dayDeference + 1) + ((weekNumber - 2)* 7));
                }
                return finalDate;
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2017-04-20
      • 1970-01-01
      • 2014-08-10
      • 2013-09-07
      • 2014-04-21
      相关资源
      最近更新 更多