2016-03-09 8 views
2

У меня возникла большая проблема, чтобы получить дату с C#, указав год, номер недели и день.Извлечь дату из года, номер недели, имя дня в C#

Пусть я

Year = 2016 
Week number = 1 
Day Name ='FRI' 
First day of week='SUN' 

Ожидаемый результат:

01-01-2016 

Как я могу это сделать?

+0

Что это такое? Все ли они? –

+6

На какой неделе вы используете систему нумерации? Есть * много * доступных ... –

+0

@ SonerGönül, hmm все строки – Shohel

ответ

2

OK, если вы хотите будний X в год Y, в неделю 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 значения, но в этом случае вам необходимо правильно обрабатывать отрицательные значения, так как в первый день недели вес не должен быть понедельником ,

+0

Вы предполагаете, что OP хочет нумерацию недель ISO-8601 - I см. никаких доказательств того, что до сих пор. –

+0

Вместо того, чтобы использовать календарь для определения первой недели, почему бы вам не использовать его для * добавления * количества недель? Также, почему * loop *, чтобы найти окончательную дату, когда 'DayOfWeek 'уже соответствует нескольким дням? –

1

Существует множество схем нумерации недель. Например, ISO-8601 рассчитан на полные недели, поэтому 2016-01-01 - это неделя 53 из 2015 года. Ваш ожидаемый результат показывает, что вы хотите начать отсчет с 1/1, а не с первой полной недели.

Вы можете избежать хлопот, используя библиотеку как NodaTime которая already supports вычислительное дату в год, номер недели и день:

LocalDate date = LocalDate.FromWeekYearWeekAndDay(year, week, IsoDayOfWeek.Monday); 

Если вы не хотите использовать внешнюю библиотеку, «Трюк "чтобы найти первую неделю дату начала, добавьте указанное количество недель к нему, а затем, добавьте количество дней, которое соответствует targed дня недели:

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"); 

Для сокращения, вы можете получить список дат сокращений от собственности DateTimeFormat.AbbreviatedDayNames CultureInfo в. Позиция индекса аббревиатуры соответствует значению DayOfWeek.

Для того, чтобы Lookups проще, вы можете преобразовать этот список в словарь:

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 
Смежные вопросы