2010-10-30 5 views
2

У меня есть текущая неделя как целое число (43 на данный момент). Мне нужна дата в понедельник в формате «Mon Oct 25».получить первый день данной недели

Думал, что могу выполнить это с помощью функции, но я не знаю, как это сделать. Любые предложения?

EDIT: Я попробовал предложение от R., но это не дает ожидаемого результата. Я сделал это неправильно?

time_t monday; 
char date_format[32]; 
time_t now = time(NULL); 
struct tm *tm = localtime(&now); 

tm->tm_yday = 0; // reset to Jan 1st 
tm->tm_hour = 24 * 7 * WEEK + 24; // goto Sun and add 24h for Mon 

monday = mktime(tm); 

strftime(date_format, 31, "%a : %D", tm); 

printf("%s\n", date_format); 
+2

Удачи. ISO-8601 определяет, что означает «номер недели» (т. Е. Как определить, какая дата дня 1 неделя 1, в зависимости от того, какой день недели начинается в году). В частности, неделя 1 - какая бы неделя не была первой четверть года. Но не все используют это определение последовательно. Поэтому, прежде чем вы сможете написать какой-либо код, вы должны знать, что на самом деле означает вход. –

+0

Доступные решения зависят от вашей среды. –

+0

Помните, что этот ответ изменится в зависимости от того, в каком году он. –

ответ

2

Примечание: Не тестировался, но, учитывая текущий год, это должно сделать это:

const char *months[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep", 
         "Oct","Nov","dec","Jan"}; 
/* Start with January 1st of the current year */ 
struct tm curYear={ 
    0, // secs 
    0, // mins 
    0, // hours 
    1, // Day of month 
    0, // Month (Jan) 
    year, 
    0, // wday 
    0, // yday 
    0}; // isdst 

/* Offset the number of weeks specified */ 
time_t secsSinceEpoch=mktime(&curYear)+ 
         weekNum*86400*7; /* Shift by number of weeks */ 
struct tm *candidateDate=gmtime(&secsSinceEpoch); 

/* If the candidate date is not a Monday, shift it so that it is */ 
if (candidateDate->tm_wday!=1) 
{ 
    secsSinceEpoch+=(86400*(candidateDate->tm_wday-1)); 
    candidateDate=gmtime(&secsSinceEpoch); 
} 

printf("Mon %s %d",months[candidateDate->tm_mon],candidateDate->tm_mday\n"); 

Вы, возможно, придется скорректировать формулы в этом коде в зависимости от того, что именно вы имеете в виду неделю 43 в конкретном году или для соответствия ISO-8601, например. Тем не менее, это должно предоставить вам хороший код плиты котла, чтобы начать работу. Вы также можете параметризовать день недели, чтобы он не был жестко закодирован.

Кроме того, если вы хотите, вы можете избежать массива месяцев и вынуждены отформатировать время, обрезая результат функции ctime, который просто так отображает больше, чем вы просили. Вы передадите ему указатель на значение secsSinceEpoch и обрезаете его вывод, чтобы отобразить только день недели, день месяца и аббревиатуру названия месяцев.

+1

Вы делаете это слишком сложно. См. Мой ответ. –

+0

Что не так с использованием strftime() здесь? – Clifford

+0

вы действительно умеете писать код, не тестируя его :) Мне нужно было только изменить длину массива до 13 и уменьшить число недели на единицу. Затем я получаю «Mon Oct 25», что абсолютно правильно. – ClosedID

2

mktime функция может это сделать. Просто инициализируйте struct tm foo для представления первого дня года (или первого дня первой недели года по мере необходимости), затем установите tm_hour на номер 24*7*weeknum и позвоните по номеру mktime. Это нормализует дату для вас.

+0

Является ли это компилятор поведения конкретным или частью стандарта C? –

+0

@ Майкл: стандарт говорит, что начальные значения могут быть вне диапазона и что они «вынуждены» в диапазон. Он не говорит, как они вынуждены (по крайней мере, не в 7.23.2.3/2 от C99), поэтому, возможно, вы можете утверждать, что стандарт не требует этого, но я думаю, что намерение заключается в том, что расчеты переполнения времени выполняются , @Р. Вам нужно установить время (например,) в полдень в первый день, а не в полночь, чтобы избежать выхода на один день из-за летнего сбережения? –

+0

Это отличное решение, но я не могу заставить его работать так, как ожидалось. Я добавил предложенный код к своему оригинальному сообщению. Он печатает «Солнце: 08/28/11» для текущей недели 43. Кто-то видит ошибку? – ClosedID

Смежные вопросы