예제 #1
0
static int find_next(const CalendarSpec *spec, struct tm *tm) {
        struct tm c;
        int r;

        assert(spec);
        assert(tm);

        c = *tm;

        for (;;) {
                /* Normalize the current date */
                mktime(&c);
                c.tm_isdst = -1;

                c.tm_year += 1900;
                r = find_matching_component(spec->year, &c.tm_year);
                c.tm_year -= 1900;

                if (r > 0) {
                        c.tm_mon = 0;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                }
                if (r < 0 || tm_out_of_bounds(&c))
                        return r;

                c.tm_mon += 1;
                r = find_matching_component(spec->month, &c.tm_mon);
                c.tm_mon -= 1;

                if (r > 0) {
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                }
                if (r < 0 || tm_out_of_bounds(&c)) {
                        c.tm_year ++;
                        c.tm_mon = 0;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                        continue;
                }

                r = find_matching_component(spec->day, &c.tm_mday);
                if (r > 0)
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                if (r < 0 || tm_out_of_bounds(&c)) {
                        c.tm_mon ++;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                        continue;
                }

                if (!matches_weekday(spec->weekdays_bits, &c)) {
                        c.tm_mday++;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                        continue;
                }

                r = find_matching_component(spec->hour, &c.tm_hour);
                if (r > 0)
                        c.tm_min = c.tm_sec = 0;
                if (r < 0 || tm_out_of_bounds(&c)) {
                        c.tm_mday ++;
                        c.tm_hour = c.tm_min = c.tm_sec = 0;
                        continue;
                }

                r = find_matching_component(spec->minute, &c.tm_min);
                if (r > 0)
                        c.tm_sec = 0;
                if (r < 0 || tm_out_of_bounds(&c)) {
                        c.tm_hour ++;
                        c.tm_min = c.tm_sec = 0;
                        continue;
                }

                r = find_matching_component(spec->second, &c.tm_sec);
                if (r < 0 || tm_out_of_bounds(&c)) {
                        c.tm_min ++;
                        c.tm_sec = 0;
                        continue;
                }


                *tm = c;
                return 0;
        }
}
예제 #2
0
static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
        struct tm c;
        int tm_usec;
        int r;

        assert(spec);
        assert(tm);

        c = *tm;
        tm_usec = *usec;

        for (;;) {
                /* Normalize the current date */
                (void) mktime_or_timegm(&c, spec->utc);
                c.tm_isdst = spec->dst;

                c.tm_year += 1900;
                r = find_matching_component(spec, spec->year, &c, &c.tm_year);
                c.tm_year -= 1900;

                if (r > 0) {
                        c.tm_mon = 0;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                }
                if (r < 0)
                        return r;
                if (tm_out_of_bounds(&c, spec->utc))
                        return -ENOENT;

                c.tm_mon += 1;
                r = find_matching_component(spec, spec->month, &c, &c.tm_mon);
                c.tm_mon -= 1;

                if (r > 0) {
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                }
                if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
                        c.tm_year++;
                        c.tm_mon = 0;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                        continue;
                }

                r = find_matching_component(spec, spec->day, &c, &c.tm_mday);
                if (r > 0)
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
                        c.tm_mon++;
                        c.tm_mday = 1;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                        continue;
                }

                if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
                        c.tm_mday++;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                        continue;
                }

                r = find_matching_component(spec, spec->hour, &c, &c.tm_hour);
                if (r > 0)
                        c.tm_min = c.tm_sec = tm_usec = 0;
                if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
                        c.tm_mday++;
                        c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
                        continue;
                }

                r = find_matching_component(spec, spec->minute, &c, &c.tm_min);
                if (r > 0)
                        c.tm_sec = tm_usec = 0;
                if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
                        c.tm_hour++;
                        c.tm_min = c.tm_sec = tm_usec = 0;
                        continue;
                }

                c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
                r = find_matching_component(spec, spec->microsecond, &c, &c.tm_sec);
                tm_usec = c.tm_sec % USEC_PER_SEC;
                c.tm_sec /= USEC_PER_SEC;

                if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
                        c.tm_min++;
                        c.tm_sec = tm_usec = 0;
                        continue;
                }

                *tm = c;
                *usec = tm_usec;
                return 0;
        }
}