Цитата(SpiritDance @ Mar 31 2008, 12:36)

Вот алгоритм вычисление собственно последнего дня недели в месяце в текущем году и интересует.
Для учета летнего/зимнего времени можно определить следующие переменные:
char saving-starts[3] = {p1,p2,p3};
char saving-ends[3] = {p1,p2,p3};
char time-offset = p4;
char saving-starts-time = p5;
char saving-ends-time = p6;
Параметры: p1 – какой день: 1 – первый, -1 – последний день недели месяца; p2 – день недели: 0 – воскресенье; p3 – месяц; p4 – разница во времени в минутах при переходе; p5, p6 – число минут после полуночи, когда переводить стрелки.
Переход на летнее время - Последнее воскресенье марта 2 часа ночи.
Переход на зимнее время - Последнее воскресенье октября 3 часа ночи.
saving-starts[3] = {1,0,4}; // последнее воскресенье марта
saving-ends[3] = {-1,0,10}; //последнее воскресенье октября
time-offset = 60; //1 час
saving-starts-time = 120; //2 часа ночи
saving-ends-time = 180; //3 часа ночи
Алгоритм перевода стрелок осенью:
1. На основании системных переменных знаем время перехода (tm_sec, tm_min, tm_hour);
2. Найдем (mktime) номер дня недели (tm_wday) для даты <сего года>.10.31 00:00:00 (последний день месяца);
3. dD := <номер дня недели <сего года>.10.31> – <номер дня недели перехода (из системной переменной)>; (учесть переход через 0);
4. ЧИСЛО ПЕРЕХОДА (tm_mday) = 31- dD;
5.Зная число (см. п.4) месяц (tm_mon) и год (tm_year) перехода (из системной переменной) и время перехода (см. п.1) определяем (time_t mktime(struct tm* )) точное время этого события в time_t формате.
Затем сверяем его с текущим временем.
Время перехода определяем при включении питания и при коррекции времени.
Примечание: в п.2,3,4 жестко записано 31, но нужно учитывать 30/31, если, вдруг, будет не октябрь и не март.
!!! аппаратные часы _всегда_ должны считать время в UTC, а учет летнего времени можно учитывать для отображения, журналов, и т.д.