mirror of
https://github.com/systemd/systemd.git
synced 2024-11-07 01:27:11 +03:00
basic: calendarspec UTC support
Just add " UTC" to the end of the event expression. Works for the special expressions.
This commit is contained in:
parent
d08a6b02b5
commit
51ffa239e8
@ -279,6 +279,9 @@ int calendar_spec_to_string(const CalendarSpec *c, char **p) {
|
|||||||
fputc(':', f);
|
fputc(':', f);
|
||||||
format_chain(f, 2, c->second);
|
format_chain(f, 2, c->second);
|
||||||
|
|
||||||
|
if (c->utc)
|
||||||
|
fputs(" UTC", f);
|
||||||
|
|
||||||
r = fflush_and_check(f);
|
r = fflush_and_check(f);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
free(buf);
|
free(buf);
|
||||||
@ -657,6 +660,10 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
|
|||||||
if (!c)
|
if (!c)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
c->utc = endswith_no_case(p, "UTC");
|
||||||
|
if (c->utc)
|
||||||
|
p = strndupa(p, strlen(p) - strlen(" UTC"));
|
||||||
|
|
||||||
if (strcaseeq(p, "minutely")) {
|
if (strcaseeq(p, "minutely")) {
|
||||||
r = const_chain(0, &c->second);
|
r = const_chain(0, &c->second);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -859,13 +866,13 @@ static int find_matching_component(const CalendarComponent *c, int *val) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tm_out_of_bounds(const struct tm *tm) {
|
static bool tm_out_of_bounds(const struct tm *tm, bool utc) {
|
||||||
struct tm t;
|
struct tm t;
|
||||||
assert(tm);
|
assert(tm);
|
||||||
|
|
||||||
t = *tm;
|
t = *tm;
|
||||||
|
|
||||||
if (mktime(&t) == (time_t) -1)
|
if (mktime_or_timegm(&t, utc) == (time_t) -1)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Did any normalization take place? If so, it was out of bounds before */
|
/* Did any normalization take place? If so, it was out of bounds before */
|
||||||
@ -878,7 +885,7 @@ static bool tm_out_of_bounds(const struct tm *tm) {
|
|||||||
t.tm_sec != tm->tm_sec;
|
t.tm_sec != tm->tm_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool matches_weekday(int weekdays_bits, const struct tm *tm) {
|
static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
|
||||||
struct tm t;
|
struct tm t;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
@ -886,7 +893,7 @@ static bool matches_weekday(int weekdays_bits, const struct tm *tm) {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
t = *tm;
|
t = *tm;
|
||||||
if (mktime(&t) == (time_t) -1)
|
if (mktime_or_timegm(&t, utc) == (time_t) -1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
k = t.tm_wday == 0 ? 6 : t.tm_wday - 1;
|
k = t.tm_wday == 0 ? 6 : t.tm_wday - 1;
|
||||||
@ -904,7 +911,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Normalize the current date */
|
/* Normalize the current date */
|
||||||
mktime(&c);
|
mktime_or_timegm(&c, spec->utc);
|
||||||
c.tm_isdst = -1;
|
c.tm_isdst = -1;
|
||||||
|
|
||||||
c.tm_year += 1900;
|
c.tm_year += 1900;
|
||||||
@ -916,7 +923,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
}
|
}
|
||||||
if (r < 0 || tm_out_of_bounds(&c))
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc))
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
c.tm_mon += 1;
|
c.tm_mon += 1;
|
||||||
@ -927,7 +934,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
}
|
}
|
||||||
if (r < 0 || tm_out_of_bounds(&c)) {
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||||
c.tm_year ++;
|
c.tm_year ++;
|
||||||
c.tm_mon = 0;
|
c.tm_mon = 0;
|
||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
@ -938,14 +945,14 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
r = find_matching_component(spec->day, &c.tm_mday);
|
r = find_matching_component(spec->day, &c.tm_mday);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
if (r < 0 || tm_out_of_bounds(&c)) {
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||||
c.tm_mon ++;
|
c.tm_mon ++;
|
||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matches_weekday(spec->weekdays_bits, &c)) {
|
if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
|
||||||
c.tm_mday++;
|
c.tm_mday++;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -954,7 +961,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
r = find_matching_component(spec->hour, &c.tm_hour);
|
r = find_matching_component(spec->hour, &c.tm_hour);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_min = c.tm_sec = 0;
|
c.tm_min = c.tm_sec = 0;
|
||||||
if (r < 0 || tm_out_of_bounds(&c)) {
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||||
c.tm_mday ++;
|
c.tm_mday ++;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -963,14 +970,14 @@ static int find_next(const CalendarSpec *spec, struct tm *tm) {
|
|||||||
r = find_matching_component(spec->minute, &c.tm_min);
|
r = find_matching_component(spec->minute, &c.tm_min);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_sec = 0;
|
c.tm_sec = 0;
|
||||||
if (r < 0 || tm_out_of_bounds(&c)) {
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||||
c.tm_hour ++;
|
c.tm_hour ++;
|
||||||
c.tm_min = c.tm_sec = 0;
|
c.tm_min = c.tm_sec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = find_matching_component(spec->second, &c.tm_sec);
|
r = find_matching_component(spec->second, &c.tm_sec);
|
||||||
if (r < 0 || tm_out_of_bounds(&c)) {
|
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||||
c.tm_min ++;
|
c.tm_min ++;
|
||||||
c.tm_sec = 0;
|
c.tm_sec = 0;
|
||||||
continue;
|
continue;
|
||||||
@ -991,13 +998,13 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *next)
|
|||||||
assert(next);
|
assert(next);
|
||||||
|
|
||||||
t = (time_t) (usec / USEC_PER_SEC) + 1;
|
t = (time_t) (usec / USEC_PER_SEC) + 1;
|
||||||
assert_se(localtime_r(&t, &tm));
|
assert_se(localtime_or_gmtime_r(&t, &tm, spec->utc));
|
||||||
|
|
||||||
r = find_next(spec, &tm);
|
r = find_next(spec, &tm);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
t = mktime(&tm);
|
t = mktime_or_timegm(&tm, spec->utc);
|
||||||
if (t == (time_t) -1)
|
if (t == (time_t) -1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ typedef struct CalendarComponent {
|
|||||||
|
|
||||||
typedef struct CalendarSpec {
|
typedef struct CalendarSpec {
|
||||||
int weekdays_bits;
|
int weekdays_bits;
|
||||||
|
bool utc;
|
||||||
|
|
||||||
CalendarComponent *year;
|
CalendarComponent *year;
|
||||||
CalendarComponent *month;
|
CalendarComponent *month;
|
||||||
|
Loading…
Reference in New Issue
Block a user