static void do_adjust_special_weekday(timelib_time* time) { timelib_sll current_dow, count; count = time->relative.special.amount; current_dow = timelib_day_of_week(time->y, time->m, time->d); if (count == 0) { /* skip over saturday and sunday */ if (current_dow == 6) { time->d += 2; } /* skip over sunday */ if (current_dow == 0) { time->d += 1; } } else if (count > 0) { /* skip over saturday and sunday */ if (current_dow == 5) { time->d += 2; } /* skip over sunday */ if (current_dow == 6) { time->d += 1; } /* add increments of 5 weekdays as a week */ time->d += (count / 5) * 7; /* if current DOW plus the remainder > 5, add two days */ current_dow = timelib_day_of_week(time->y, time->m, time->d); time->d += (count % 5); if ((count % 5) + current_dow > 5) { time->d += 2; } } else if (count < 0) { /* skip over sunday and saturday */ if (current_dow == 1) { time->d -= 2; } /* skip over satruday */ if (current_dow == 0 ) { time->d -= 1; } /* subtract increments of 5 weekdays as a week */ time->d += (count / 5) * 7; /* if current DOW minus the remainder < 0, subtract two days */ current_dow = timelib_day_of_week(time->y, time->m, time->d); time->d += (count % 5); if ((count % 5) + current_dow < 1) { time->d -= 2; } } }
static void do_adjust_for_weekday(timelib_time* time) { timelib_sll current_dow, difference; current_dow = timelib_day_of_week(time->y, time->m, time->d); if (time->relative.weekday_behavior == 2) { if (time->relative.weekday == 0) { time->relative.weekday = 7; } time->d -= current_dow; time->d += time->relative.weekday; return; } difference = time->relative.weekday - current_dow; if ((time->relative.d < 0 && difference < 0) || (time->relative.d >= 0 && difference <= -time->relative.weekday_behavior)) { difference += 7; } if (time->relative.weekday >= 0) { time->d += difference; } else { time->d -= (7 - (abs(time->relative.weekday) - current_dow)); } time->relative.have_weekday_relative = 0; }
static void do_adjust_for_weekday(timelib_time* time) { timelib_sll current_dow, difference; current_dow = timelib_day_of_week(time->y, time->m, time->d); if (time->relative.weekday_behavior == 2) { /* To make "this week" work, where the current DOW is a "sunday" */ if (current_dow == 0 && time->relative.weekday != 0) { time->relative.weekday = -6; } /* To make "sunday this week" work, where the current DOW is not a * "sunday" */ if (time->relative.weekday == 0 && current_dow != 0) { time->relative.weekday = 7; } time->d -= current_dow; time->d += time->relative.weekday; return; } difference = time->relative.weekday - current_dow; if ((time->relative.d < 0 && difference < 0) || (time->relative.d >= 0 && difference <= -time->relative.weekday_behavior)) { difference += 7; } if (time->relative.weekday >= 0) { time->d += difference; } else { time->d -= (7 - (abs(time->relative.weekday) - current_dow)); } time->relative.have_weekday_relative = 0; }
void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy) { int y_leap, prev_y_leap, doy, jan1weekday, weekday; y_leap = timelib_is_leap(y); prev_y_leap = timelib_is_leap(y-1); doy = timelib_day_of_year(y, m, d) + 1; if (y_leap && m > 2) { doy++; } jan1weekday = timelib_day_of_week(y, 1, 1); weekday = timelib_day_of_week(y, m, d); if (weekday == 0) weekday = 7; if (jan1weekday == 0) jan1weekday = 7; /* Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53 */ if (doy <= (8 - jan1weekday) && jan1weekday > 4) { *iy = y - 1; if (jan1weekday == 5 || (jan1weekday == 6 && prev_y_leap)) { *iw = 53; } else { *iw = 52; } } else { *iy = y; } /* 8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1 */ if (*iy == y) { int i; i = y_leap ? 366 : 365; if ((i - (doy - y_leap)) < (4 - weekday)) { *iy = y + 1; *iw = 1; return; } } /* 9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 */ if (*iy == y) { int j; j = doy + (7 - weekday) + (jan1weekday - 1); *iw = j / 7; if (jan1weekday > 4) { *iw -= 1; } } }
timelib_sll timelib_daynr_from_weeknr(timelib_sll y, timelib_sll w, timelib_sll d) { timelib_sll dow, day; /* Figure out the dayofweek for y-1-1 */ dow = timelib_day_of_week(y, 1, 1); /* then use that to figure out the offset for day 1 of week 1 */ day = 0 - (dow > 4 ? dow - 7 : dow); /* Add weeks and days */ return day + ((w - 1) * 7) + d; }
static void do_adjust_special_weekday(timelib_time* time) { timelib_sll count, dow, rem; count = time->relative.special.amount; dow = timelib_day_of_week(time->y, time->m, time->d); /* Add increments of 5 weekdays as a week, leaving the DOW unchanged. */ time->d += (count / 5) * 7; /* Deal with the remainder. */ rem = (count % 5); if (count > 0) { if (rem == 0) { /* Head back to Friday if we stop on the weekend. */ if (dow == 0) { time->d -= 2; } else if (dow == 6) { time->d -= 1; } } else if (dow == 6) { /* We ended up on Saturday, but there's still work to do, so move * to Sunday and continue from there. */ time->d += 1; } else if (dow + rem > 5) { /* We're on a weekday, but we're going past Friday, so skip right * over the weekend. */ time->d += 2; } } else { /* Completely mirror the forward direction. This also covers the 0 * case, since if we start on the weekend, we want to move forward as * if we stopped there while going backwards. */ if (rem == 0) { if (dow == 6) { time->d += 2; } else if (dow == 0) { time->d += 1; } } else if (dow == 0) { time->d -= 1; } else if (dow + rem < 1) { time->d -= 2; } } time->d += rem; }
int main(void) { printf("dow = %d\n", timelib_day_of_week(1978, 12, 22)); /* 5 */ printf("dow = %d\n", timelib_day_of_week(2005, 2, 19)); /* 6 */ }