簡體   English   中英

從C#中的年,周號,日期名稱中檢索日期

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM