Помогите с формулой, пожалуйста. Весь день головой об стол стучу, что-то никак.
Дано: дата (день,месяц,год).
Номер недели по ISO — это число 1..53
неделя начинается с понедельника
первая неделя должна включать в себя первый четверг года
нулевая неделя — это 52 или 53 (т.е. относится к прошлому году)
Здравствуйте, Кодт, Вы писали:
К>Помогите с формулой, пожалуйста. Весь день головой об стол стучу, что-то никак.
К>Дано: дата (день,месяц,год).
К>Номер недели по ISO — это число 1..53 К>неделя начинается с понедельника К>первая неделя должна включать в себя первый четверг года К>нулевая неделя — это 52 или 53 (т.е. относится к прошлому году)
К>Можно пользоваться WinAPI.
SYSTEMTIME SystemTime1;
SYSTEMTIME SystemTime2;
FILETIME FileTime1;
FILETIME FileTime2;
double dNanoSec;
int iDay;
// Получили текущее системное время
GetLocalTime(&SystemTime1);
SystemTime2 = SystemTime1;
//Задали "1января текущего года"
SystemTime2.wMonth=1; SystemTime2.wDay=1;
SystemTime2.wHour=0; SystemTime2.wMinute=0; SystemTime2.wSecond=0;
//Опред.число Тик с 1601 года
SystemTimeToFileTime(&SystemTime1, &FileTime1);
SystemTimeToFileTime(&SystemTime2, &FileTime2);
//Получаем разницу в тиках 2-х дат
dNanoSec = static_cast<double> ((FileTime1.dwHighDateTime - FileTime2.dwHighDateTime) *
0xFFFFFFFF + (FileTime1.dwLowDateTime - FileTime2.dwLowDateTime));
//Определяем текущий день года
iDay = (int) ((dNanoSec / ((double) 24 * 36000000000)) + 1);
Дальше считай сам...
Мой компьютер прогоняет бесконечный цикл за 9 секунд, но, мне кажется, он мог бы сделать это быстрее...
День года я умею получить. Даже без плавающей арифметики.
Как получить номер недели, с учётом всех вышеупомянутых правил? И с учётом того, что в локали может стоять первый день недели — воскресенье, среда, чёрт-знает-что? А ISO-шная неделя — строго с понедельника.
Здравствуйте, Кодт, Вы писали:
К>Как получить номер недели, с учётом всех вышеупомянутых правил? И с учётом того, что в локали может стоять первый день недели — воскресенье, среда, чёрт-знает-что? А ISO-шная неделя — строго с понедельника.
Блин, может я чего не понимаю.
1. Берем за отправную точку текущий год.
2. Расчитываем порядковый номер необходимого нам дня года.
3. Вычитаем из него количетво дней от 1 января до первого понедельника текущего года.
4. Делим полученное число на 7.
5. Если нужно сделать расчет на следующий год или на предыдущий, то вносишь соответствующие поправки в п.3, т.е. для следующего года +1, для предыдущего -2, т.к. этот год високосный.
Мой компьютер прогоняет бесконечный цикл за 9 секунд, но, мне кажется, он мог бы сделать это быстрее...
Здравствуйте, Кодт, Вы писали:
К>Помогите с формулой, пожалуйста. Весь день головой об стол стучу, что-то никак.
К>Дано: дата (день,месяц,год).
К>Номер недели по ISO — это число 1..53 К>неделя начинается с понедельника К>первая неделя должна включать в себя первый четверг года К>нулевая неделя — это 52 или 53 (т.е. относится к прошлому году)
К>Можно пользоваться WinAPI.
Прошу прощения может не в тему. По сути нужно найти дату первой недели
Здравствуйте, Кодт, Вы писали:
К>Помогите с формулой, пожалуйста. Весь день головой об стол стучу, что-то никак.
К>Дано: дата (день,месяц,год).
К>Номер недели по ISO — это число 1..53 К>неделя начинается с понедельника К>первая неделя должна включать в себя первый четверг года К>нулевая неделя — это 52 или 53 (т.е. относится к прошлому году)
К>Можно пользоваться WinAPI.
Предположим, что мы умеем получать день недели в виде 0,1,2..6 (0 — понедельник, 6 — воскресенье) и день года, тоже индексированный от нуля. Тогда вроде бы должно работать примерно следующее:
// дано d, m, y
// день недели на данную датуint curDOW = DayOfWeek( d, m, y );
// день недели 1 января данного годаint baseDOW = DayOfWeek( 1, 1, y );
// день в годуint curDOY = DayOfYear( d, m, y );
// если год начинается с пн, вт, ср, чт,
// то 1 января - первая неделя, иначе - нулеваяint baseWeek = baseDOW<4 ? 1 : 0;
// грубо: номер нашей недели - это
// номер недели 1 января + количество целых недельint isoWeek = baseWeek + curDOY / 7;
// коррекция: если данный день раньше в неделе, чем 1 января,
// то на самом деле неделя уже другая (следующая)if( curDOW < baseDOW )
++isoWeek;
... << RSDN@Home 1.1.3 stable >>
Все на свете должно происходить медленно и неправильно...
Да, забыл. Еще нужна коррекция нулевой недели, если она получается в ответе. Для этого тем же самым способом получаем номер недели 31.12 предыдущего года — это и будет ответ.
... << RSDN@Home 1.1.3 stable >>
Все на свете должно происходить медленно и неправильно...
Здравствуйте, Кодт, Вы писали:
К>Помогите с формулой, пожалуйста. Весь день головой об стол стучу, что-то никак.
К>Дано: дата (день,месяц,год).
К>Номер недели по ISO — это число 1..53 К>неделя начинается с понедельника К>первая неделя должна включать в себя первый четверг года К>нулевая неделя — это 52 или 53 (т.е. относится к прошлому году)
К>Можно пользоваться WinAPI.
МММ. Ну давай чуть-чуть порассуждаем. Переводим дату в номер дня в году. Все номера дней занимают отрезок 1-365 или 1-366 для високосного года. Теперь рассмотрим первые семь дней 1-7. Один из этих дней (и только один) -- четверг. Пусть это день номер k. От чего зависит это число? От года и больше ни от чего. Надо научиться его вычислять. Ну а дальше просто. Номер недели для дня k -- 1, потому что это первый четверг в году. Если теперь у нас день номер k+7*n, то его номер недели -- 1+n. Если k+1+7*n (пятница), k+2+7*n (суббота), k+3+7*n (воскресенье), то тоже 1+n. А вот для
k+4+7*n (понедельник) -- уже 2+n. Короче, n+1 я неделя -- это [k-3+7*n,k+3+7*n]. Значит, день номер l принадлежит (l+10-k)/7 й неделе.
Здравствуйте, conraddk, Вы писали:
C>Да, забыл. Еще нужна коррекция нулевой недели, если она получается в ответе. Для этого тем же самым способом получаем номер недели 31.12 предыдущего года — это и будет ответ.
А как насчет обратной задачи? имеется например 31.12. как узнать к какой неделе относится эта дата, к 52-й неделе этого года или к 1-й неделе следующего года? именно по календарю!!! а не по порядковому номеру недели в году.
т.к. по вышеизложенным алгоритмам 31.12 и 01.01 находящиеся в одной неделе выдадут разные номера нелеь если 01.01 — это 1-я неделя.
Здравствуйте, xWanderer, Вы писали:
W>А как насчет обратной задачи? имеется например 31.12. как узнать к какой неделе относится эта дата, к 52-й неделе этого года или к 1-й неделе следующего года? именно по календарю!!! а не по порядковому номеру недели в году.
Не понял выделенное. Кстати, почему задача обратная? Та же самая: по дате надо узнать неделю.
W>т.к. по вышеизложенным алгоритмам 31.12 и 01.01 находящиеся в одной неделе выдадут разные номера нелеь если 01.01 — это 1-я неделя.
Из определения ISO week number
так и получается. 31.12 в этом случае в последней неделе старого года, а 01.01 — в первой неделе нового года. Если нужно относить 31.12 в такой ситуации к первой неделе нового года (что об этом думает ISO? ), добавляем еще одну коррекцию. Такое может произойти в следующих случаях: