Amb*_*mps 198 .net c# asp.net date
我搜索了很多并找到了很多解决方案,但没有一个能给我2012-12-31的正确周数.甚至MSDN(链接)上的示例都失败了.
2012-12-31是星期一,因此它应该是第1周,但我尝试的每种方法都给了我53.以下是我尝试过的一些方法:
来自MDSN图书馆:
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
Calendar cal = dfi.Calendar;
return cal.GetWeekOfYear(date, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
Run Code Online (Sandbox Code Playgroud)
解决方案2:
return new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
Run Code Online (Sandbox Code Playgroud)
解决方案3:
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
Run Code Online (Sandbox Code Playgroud)
更新
当日期为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);
}
Run Code Online (Sandbox Code Playgroud)
il_*_*uru 286
如本MSDN页面所述,ISO8601周和.Net周编号之间存在细微差别.
您可以参考MSDN博客中的这篇文章以获得更好的解释:" Microsoft .Net中的ISO 8601年份周格式 "
简而言之,.Net允许数周分开,而ISO标准则没有.在文章中还有一个简单的功能,可以获得一年中最后一周的正确ISO 8601周数.
更新以下方法实际上返回1,2012-12-31
其在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);
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*ers 28
一年可能超过52周.每年有52个完整周+ 1或+2(闰年)额外.他们弥补了第53周.
因此,每年至少有一天额外的一天.两个闰年.这些额外的日子是否被视为自己的独立周?
这几周真的取决于你一周的开始日.让我们考虑一下2012年.
检查您当前的文化设置,以查看它在一周的第一天使用的内容.
如你所见,结果是53是正常的.
甚至可能有第54周.每隔28年发生1月1日和12月31日作为单独的星期.它也必须是闰年.
例如,2000年有54周.1月1日(sat)是第一个星期的一天,12月31日(太阳)是第二个星期的一天.
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);
Run Code Online (Sandbox Code Playgroud)
打印出:年份:2012年周:54
将上面例子中的CalendarWeekRule更改为FirstFullWeek或FirstFourDayWeek,然后你将返回53.让我们在星期一保持开始日,因为我们正在与德国打交道.
所以第53周开始于2012-12-31星期一,持续一天然后停止.
53是正确的答案.如果想尝试,请将文化改为德国.
CultureInfo cul = CultureInfo.GetCultureInfo("de-DE");
Run Code Online (Sandbox Code Playgroud)
dan*_*004 17
这是方式:
public int GetWeekNumber()
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(DateTime.Now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
return weekNum;
}
Run Code Online (Sandbox Code Playgroud)
最重要的是CalendarWeekRule
参数.
请参阅:https: //msdn.microsoft.com/query/dev14.query?appId = Dev14IDEF1&l = IT -IT&k = k(System.Globalization.CalendarWeekRule); k(TargetFrameworkMoniker-.NETFramework
rea*_*art 11
我要在这里玩死灵法师:-)
由于似乎没有.Net文化产生正确的ISO-8601周数,我宁愿完全绕过内置周确定,并手动进行计算,而不是试图纠正部分正确结果.
我最终得到的是以下扩展方法:
/// <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;
}
Run Code Online (Sandbox Code Playgroud)
首先,((int)date.DayOfWeek + 6) % 7)
确定工作日数字,0 =星期一,6 =星期日.
date.AddDays(-((int)date.DayOfWeek + 6) % 7)
确定所请求的周数之前的星期一的日期.
三天后是星期四的目标,它决定了一周的哪一年.
如果您将年内的(从零开始)日数除以7(向下舍入),您将获得该年中的(从零开始)周数.
在c#中,整数计算结果是隐式舍入的.
khe*_*ang 10
好消息!一个拉请求加入System.Globalization.ISOWeek
到.NET的核心刚刚合并,目前内定为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);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处找到源代码。
更新:这些API也已包含在2.1版本的.NET Standard中。
小智 6
在 .NET 3.0 及更高版本中,您可以使用ISOWeek.GetWeekOfDate
-Method。
请注意,年份 + 周数字格式中的年份可能与年份不同,DateTime
因为周数跨越了年份边界。