我在谷歌上搜索了很多,找到了很多解决方案,但没有一个能告诉我2012-12-31的正确周数。即使是MSDN上的例子(链接)也失败了。

2012-12-31是星期一,所以应该是第一周,但是我尝试的每一种方法都给了我53。以下是我尝试过的一些方法:

从MDSN库:

DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);

解决方案2:

return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

解决方案3:

CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

更新

当date为2012-12-31时,下面的方法实际返回1。换句话说,我的问题是我的方法没有遵循ISO-8601标准。

// This presumes that weeks start with Monday.
// Week 1 is the 1st week of the year with a Thursday in it.
public static int GetIso8601WeekOfYear(DateTime time)
{
    // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll 
    // be the same week# as whatever Thursday, Friday or Saturday are,
    // and we always get those right
    DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
    if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
    {
        time = time.AddDays(3);
    }

    // Return the week of our adjusted day
    return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

当前回答

public int GetWeekNumber()
{
   CultureInfo ciCurr = CultureInfo.CurrentCulture;
   int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTime.Now, 
   CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
   return weekNum;
}

其他回答

是这样的:

public int GetWeekNumber()
{
    CultureInfo ciCurr = CultureInfo.CurrentCulture;
    int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    return weekNum;
}

最重要的是CalendarWeekRule参数。

在这里看到的: https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=IT-IT&k=k (System.Globalization.CalendarWeekRule)、k (TargetFrameworkMoniker -.NETFramework

如果您需要日历周和年的组合(例如。“1/22”表示2022年日历周1)请注意,年份部分并不总是等于输入日期的年份。这是因为如果一年中至少有4天属于去年,那么每年的第一天属于前一年的最后一个日历周。因此,如果一周中至少有4天属于下一年,那么一年的最后几天属于下一年的第一个日历周。

下面是一个基于@Jogge在回答中提供的扩展

public static class DateTimeExtensions
{
    public static int GetIso8601WeekOfYear(this DateTime time)
    {
        var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }

        return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek,
            DayOfWeek.Monday);
    }

    public static int? GetIso8601WeekOfYear(this DateTime? time)
    {
        return time?.GetIso8601WeekOfYear();
    }

    public static string GetIso8601WeekAndYearString(this DateTime time)
    {
        var week = time.GetIso8601WeekOfYear();

        var year = time.Month == 1 && week >= 52
            ? time.Year - 1
            : time.Month == 12 && week == 1
                ? time.Year + 1
                : time.Year;

        return $"{week}/{new DateTime(year, 1, 1):yy}";
    }

    public static string GetIso8601WeekAndYearString(this DateTime? time)
    {
        return time?.GetIso8601WeekAndYearString();
    }
}

根据il_guru的回答,我根据自己的需要创建了这个版本,它也返回year组件。

    /// <summary>
    /// This presumes that weeks start with Monday.
    /// Week 1 is the 1st week of the year with a Thursday in it.
    /// </summary>
    /// <param name="time">The date to calculate the weeknumber for.</param>
    /// <returns>The year and weeknumber</returns>
    /// <remarks>
    /// Based on Stack Overflow Answer: https://stackoverflow.com/a/11155102
    /// </remarks>
    public static (short year, byte week) GetIso8601WeekOfYear(DateTime time)
    {
        // Seriously cheat.  If its Monday, Tuesday or Wednesday, then it'll
        // be the same week# as whatever Thursday, Friday or Saturday are,
        // and we always get those right
        DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
        if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
        {
            time = time.AddDays(3);
        }
        // Return the week of our adjusted day
        var week = (byte)CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
        return ((short)(week >= 52 & time.Month == 1 ? time.Year - 1 : time.Year), week);
    }

在PowerShell 7.x.y中: 如果您需要匹配的WeekYear,您将需要以下两个代码行。

[System.Globalization.ISOWeek]::GetWeekOfYear((get-date))
[System.Globalization.ISOWeek]::GetYear((get-date))

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

该类型具有以下签名,应涵盖大多数ISO周需求:

namespace System.Globalization
{
    public static class ISOWeek
    {
        public static int GetWeekOfYear(DateTime date);
        public static int GetWeeksInYear(int year);
        public static int GetYear(DateTime date);
        public static DateTime GetYearEnd(int year);
        public static DateTime GetYearStart(int year);
        public static DateTime ToDateTime(int year, int week, DayOfWeek dayOfWeek);
    }
}

你可以在这里找到源代码。

更新:这些api也包含在。net标准的2.1版本中。