首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >获取给定日期的正确周数

获取给定日期的正确周数
EN

Stack Overflow用户
提问于 2012-06-22 18:43:41
回答 18查看 290.5K关注 0票数 260

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

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

从MDSN库中:

代码语言:javascript
复制
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;

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

解决方案2:

代码语言:javascript
复制
return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);

解决方案3:

代码语言:javascript
复制
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;

更新

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

代码语言:javascript
复制
// 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);
}
EN

回答 18

Stack Overflow用户

回答已采纳

发布于 2012-06-22 19:13:02

正如本MSDN page中所指出的,ISO8601 week和.Net week的编号略有不同。

你可以参考MSDN Blog中的这篇文章来获得更好的解释:"ISO 8601 Week of Year format in Microsoft .Net

简而言之,.Net允许将几周时间分成几年,而国际标准化组织标准不允许。在这篇文章中,还有一个简单的函数可以获得一年中最后一周的正确ISO 8601周数字。

更新以下方法实际上为2012-12-31返回1,这在ISO8601(例如德国)中是正确的。

代码语言:javascript
复制
// 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);
} 
票数 357
EN

Stack Overflow用户

发布于 2018-06-19 18:24:33

好消息!刚刚合并了一个将System.Globalization.ISOWeek添加到.NET核心的pull request,目前计划在3.0版本中使用。希望它能在不久的将来推广到其他.NET平台。

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

代码语言:javascript
复制
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);
    }
}

你可以找到源代码here

更新:这些API也已经被included in the 2.1 version of .NET Standard

票数 47
EN

Stack Overflow用户

发布于 2012-06-22 19:00:33

一年中可能有超过52周。每一年有52个完整的星期+1或+2 (闰年)天。他们补足了53周的时间。

  • 52周*7天= 364天。

因此,每一年,你至少有一个额外的一天。两个表示闰年。这些额外的日子是否被算作他们自己的单独的星期?

有多少周取决于你一周的开始日期。让我们考虑一下2012年的情况。

  • US (周日->周六):52周+一周短2天,2012-12-30和2012-12-31。这将导致总共53周。今年的最后两天(周日+周一)组成了他们自己的短短一周。

检查当前“区域性”的设置,查看它用作每周的第一天的内容。

如你所见,结果是53是很正常的。

  • 欧洲(星期一和星期日):1月2dn (2012-1-2)是第一个星期一,所以这是第一周的第一天。询问1月1日的周编号,你会得到52,因为它被认为是2011年上周的一部分。

甚至有可能会有54周。每28年发生一次,将1月1日和12月31日视为不同的星期。今年肯定也是闰年。

例如,2000年有54周。1月1日(星期六)为第一周日,12月31日(星期日)为第二周日。

代码语言:javascript
复制
var d = new DateTime(2012, 12, 31);
CultureInfo cul = CultureInfo.CurrentCulture;

var firstDayWeek = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int weekNum = cul.Calendar.GetWeekOfYear(
    d,
    CalendarWeekRule.FirstDay,
    DayOfWeek.Monday);

int year = weekNum == 52 && d.Month == 1 ? d.Year - 1 : d.Year;
Console.WriteLine("Year: {0} Week: {1}", year, weekNum);

打印数量:年份: 2012周: 54

将上面示例中的CalendarWeekRule更改为FirstFullWeek或FirstFourDayWeek,您将返回53。让我们把起跑日保持在周一,因为我们是在和德国打交道。

因此,第53周从2012-12-31星期一开始,持续一天,然后停止。

53是正确答案。如果您想尝试一下,请将“文化”更改为“德国”。

代码语言:javascript
复制
CultureInfo cul = CultureInfo.GetCultureInfo("de-DE");
票数 35
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11154673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档