summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shared/time-dst.c5
-rw-r--r--src/shared/time-dst.h7
-rw-r--r--src/timedate/timedatectl.c34
3 files changed, 35 insertions, 11 deletions
diff --git a/src/shared/time-dst.c b/src/shared/time-dst.c
index df5f15151d..afc893cccc 100644
--- a/src/shared/time-dst.c
+++ b/src/shared/time-dst.c
@@ -83,7 +83,7 @@ static inline int64_t decode64(const void *ptr) {
int time_get_dst(time_t date, const char *tzfile,
time_t *switch_cur, char **zone_cur, bool *dst_cur,
- time_t *switch_next, char **zone_next, bool *dst_next) {
+ time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next) {
time_t *transitions = NULL;
size_t num_transitions = 0;
unsigned char *type_idxs = 0;
@@ -321,8 +321,11 @@ found:
*zone_cur = strdup(&zone_names[types[type_idxs[i - 1]].idx]);
if (dst_cur)
*dst_cur = types[type_idxs[i-1]].isdst;
+
if (switch_next)
*switch_next = transitions[i];
+ if (delta_next)
+ *delta_next = (types[type_idxs[i]].offset - types[type_idxs[i-1]].offset) / 60;
if (zone_next)
*zone_next = strdup(&zone_names[types[type_idxs[i]].idx]);
if (dst_next)
diff --git a/src/shared/time-dst.h b/src/shared/time-dst.h
index 3fa6c4423c..536b6bbdfb 100644
--- a/src/shared/time-dst.h
+++ b/src/shared/time-dst.h
@@ -1,7 +1,6 @@
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-#ifndef footimedst
-#define footimedst
+#pragma once
/***
This file is part of systemd.
@@ -24,6 +23,4 @@
int time_get_dst(time_t date, const char *tzfile,
time_t *switch_cur, char **zone_cur, bool *dst_cur,
- time_t *switch_next, char **zone_next, bool *dst_next);
-
-#endif
+ time_t *switch_next, int *delta_next, char **zone_next, bool *dst_next);
diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c
index 564f9e5f74..06b98b1061 100644
--- a/src/timedate/timedatectl.c
+++ b/src/timedate/timedatectl.c
@@ -82,19 +82,43 @@ static bool ntp_synced(void) {
return true;
}
+static const char *jump_str(int delta_minutes, char *s, size_t size) {
+ if (delta_minutes == 60)
+ return "one hour forward";
+ if (delta_minutes == -60)
+ return "one hour backwards";
+ if (delta_minutes < 0) {
+ snprintf(s, size, "%i minutes backwards", -delta_minutes);
+ return s;
+ }
+ if (delta_minutes > 0) {
+ snprintf(s, size, "%i minutes forward", delta_minutes);
+ return s;
+ }
+ return "";
+}
+
static void print_status_info(StatusInfo *i) {
usec_t n;
char a[FORMAT_TIMESTAMP_MAX];
char b[FORMAT_TIMESTAMP_MAX];
+ char s[32];
struct tm tm;
time_t sec;
char *zc, *zn;
time_t t, tc, tn;
+ int dn;
bool is_dstc, is_dstn;
int r;
assert(i);
+ /* enforce the values of /etc/localtime */
+ if (getenv("TZ")) {
+ fprintf(stderr, "Warning: ignoring the TZ variable, reading the system's timezone setting only.\n\n");
+ unsetenv("TZ");
+ }
+
n = now(CLOCK_REALTIME);
sec = (time_t) (n / USEC_PER_SEC);
@@ -135,7 +159,7 @@ static void print_status_info(StatusInfo *i) {
r = time_get_dst(sec, "/etc/localtime",
&tc, &zc, &is_dstc,
- &tn, &zn, &is_dstn);
+ &tn, &dn, &zn, &is_dstn);
if (r < 0)
printf(" DST active: n/a\n");
else {
@@ -149,10 +173,10 @@ static void print_status_info(StatusInfo *i) {
zero(tm);
assert_se(strftime(b, sizeof(b), "%a, %Y-%m-%d %H:%M:%S %Z", localtime_r(&tc, &tm)) > 0);
char_array_0(b);
- printf(" Last DST change: %s → %s, one hour %s\n"
+ printf(" Last DST change: %s → %s, DST became %s\n"
" %s\n"
" %s\n",
- strna(zn), strna(zc), is_dstc ? "forward" : "backwards", a, b);
+ strna(zn), strna(zc), is_dstc ? "active" : "inactive", a, b);
t = tn - 1;
zero(tm);
@@ -162,10 +186,10 @@ static void print_status_info(StatusInfo *i) {
zero(tm);
assert_se(strftime(b, sizeof(b), "%a, %Y-%m-%d %H:%M:%S %Z", localtime_r(&tn, &tm)) > 0);
char_array_0(b);
- printf(" Next DST change: %s → %s, one hour %s\n"
+ printf(" Next DST change: %s → %s, DST will become %s, the clock will jump %s\n"
" %s\n"
" %s\n",
- strna(zc), strna(zn), is_dstn ? "forward" : "backwards", a, b);
+ strna(zc), strna(zn), is_dstn ? "active" : "inactive", jump_str(dn, s, sizeof(s)), a, b);
free(zc);
free(zn);