[英]Retrieve date from year, week number, day name in C#
通过提供年,周编号和日期名称,我从C#中检索日期时遇到了一个大问题。
假设我有
Year = 2016
Week number = 1
Day Name ='FRI'
First day of week='SUN'
预期结果:
01-01-2016
我怎样才能做到这一点?
有许多星期编号方案。 例如,ISO-8601计算整周,因此2016-01-01
是2015年的第53周。但是,您的预期结果显示您希望从1/1开始计数,而不是从第一个整周开始计数。
您可以使用NodaTime之类的库来避免麻烦,该库已经支持根据年,周和日来计算日期:
LocalDate date = LocalDate.FromWeekYearWeekAndDay(year, week, IsoDayOfWeek.Monday);
如果您不想使用外部库,则“技巧”是找到第一周的开始日期,在其中添加指定的周数,然后添加与指定的工作日相对应的天数:
var year=2016;
var weekNumber=1;
var dayOfWeek=(int)DayOfWeek.Friday;
//Doesn't really matter when the week starts
var firstDayOfWeek=(int)DayOfWeek.Sunday;
var yearStart=new DateTime(year,1,1);
var firstWeekDate=yearStart.AddDays( firstDayOfWeek -(int)yearStart.DayOfWeek);
//Use Calendar to add the number of weeks
Calendar myCal = CultureInfo.InvariantCulture.Calendar;
var targetDate=myCal.AddWeeks(firstWeekDate,weekNumber-1)
.AddDays(dayOfWeek - firstDayOfWeek);
结果是2016-1-1
。 对于第11周,结果将是2016-3-11
。
简化firstWeekDate
的代码变为:
var targetDate=myCal.AddWeeks(yearStart,weekNumber-1)
.AddDays(dayOfWeek - (int)yearStart.DayOfWeek);
作为一个函数,看起来像:
DateTime FromWeekYearWeekAndDay(int year, int weekNumber, DayOfWeek dayOfWeek,
CultureInfo cultureInfo=null)
{
cultureInfo=cultureInfo??CultureInfo.InvariantCulture;
Calendar myCal = cultureInfo.Calendar;
var yearStart=new DateTime(year,1,1);
var targetDate=myCal.AddWeeks(yearStart,weekNumber-1)
.AddDays((int)dayOfWeek - (int)yearStart.DayOfWeek);
return targetDate;
}
最后一部分是解析日期名称。 如果您使用全英文日期名称,则可以使用Enum.Parse :
var dayOfWeek=(int)Enum.Parse(typeof(DayOfWeek),"Friday");
对于缩写,您可以从CultureInfo的DateTimeFormat.AbbreviatedDayNames属性检索日期缩写的列表。 缩写词的索引位置与其DayOfWeek值相对应。
为了使查找更容易,您可以将此列表转换为字典:
var abbreviations=CultureInfo.InvariantCulture.DateTimeFormat.AbbreviatedDayNames;
var dayDict=abbreviations.Select((name,idx)=>new{name,idx})
.ToDictionary(l=>l.name,
l=>(DayOfWeek)l.idx,
StringComparer.InvariantCultureIgnoreCase);
var dayOfWeek= dayDict["FRI"];
最后,可以使用以下代码找到目标日期:
var dayOfWeek=dayDict["FRI"];
var targetDate=FromWeekYearWeekAndDay(2016,1,dayOfWeek);
//2016-01-01
要么
var targetDate=FromWeekYearWeekAndDay(2016,11,dayOfWeek);
//2016-3-11
好的,假设您要在Y年的第X个工作日,在W周的。
public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
{
DateTime jan1 = new DateTime(year, 1, 1);
int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
DateTime firstThursday = jan1.AddDays(daysOffset);
var cal = CultureInfo.CurrentCulture.Calendar;
int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
var weekNum = weekOfYear;
if (firstWeek <= 1)
{
weekNum -= 1;
}
var result = firstThursday.AddDays(weekNum * 7);
return result.AddDays(-3);
}
现在您有W周的第一天。现在您使用
DateTime input = FirstDateOfWeekISO8601(y, w);
input.DayOfWeek
这样就可以在第0天获得星期几。现在,您可以使用input.AddDays(1)进行循环,直到找到要搜索的日期为止。
说
for(int i = 0; i < 7; ++i)
{
if(input.AddDays(i).DayOfWeek == "here you need to the number from X which you passs as a string")
}
或者,您可以减去两个dayofweek值,但是在这种情况下,您将需要正确处理负值,因为w的第一天不必是星期一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.