]> git.sur5r.net Git - i3/i3status/commitdiff
Add tztime module to support multiple different timezones.
authorEmil Mikulic <emikulic@gmail.com>
Sun, 13 Jan 2013 13:18:38 +0000 (00:18 +1100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 10 Feb 2013 16:18:32 +0000 (17:18 +0100)
i3status.c
i3status.conf
include/i3status.h
man/i3status.man
src/print_ddate.c
src/print_time.c

index af62a7ce74c46fbb1c80d76b0a83fa5c4591e88e..c1f6039b51c02c074cdd911a4f263ce345ceba77 100644 (file)
@@ -239,7 +239,13 @@ int main(int argc, char *argv[]) {
         };
 
         cfg_opt_t time_opts[] = {
-                CFG_STR("format", "%d.%m.%Y %H:%M:%S", CFGF_NONE),
+                CFG_STR("format", "%Y-%m-%d %H:%M:%S", CFGF_NONE),
+                CFG_END()
+        };
+
+        cfg_opt_t tztime_opts[] = {
+                CFG_STR("format", "%Y-%m-%d %H:%M:%S %Z", CFGF_NONE),
+                CFG_STR("timezone", "", CFGF_NONE),
                 CFG_END()
         };
 
@@ -292,6 +298,7 @@ int main(int argc, char *argv[]) {
                 CFG_SEC("volume", volume_opts, CFGF_TITLE | CFGF_MULTI),
                 CFG_SEC("ipv6", ipv6_opts, CFGF_NONE),
                 CFG_SEC("time", time_opts, CFGF_NONE),
+                CFG_SEC("tztime", tztime_opts, CFGF_TITLE | CFGF_MULTI),
                 CFG_SEC("ddate", ddate_opts, CFGF_NONE),
                 CFG_SEC("load", load_opts, CFGF_NONE),
                 CFG_SEC("cpu_usage", usage_opts, CFGF_NONE),
@@ -403,16 +410,9 @@ int main(int argc, char *argv[]) {
          * (!), not individual plugins, seem very unlikely. */
         char buffer[4096];
 
-        struct tm tm;
         while (1) {
                 struct timeval tv;
                 gettimeofday(&tv, NULL);
-                time_t current_time = tv.tv_sec;
-                struct tm *current_tm = NULL;
-                if (current_time != (time_t) -1) {
-                        localtime_r(&current_time, &tm);
-                        current_tm = &tm;
-                }
                 if (output_format == O_I3BAR)
                         yajl_gen_array_open(json_gen);
                 for (j = 0; j < cfg_size(cfg, "order"); j++) {
@@ -465,13 +465,19 @@ int main(int argc, char *argv[]) {
 
                         CASE_SEC("time") {
                                 SEC_OPEN_MAP("time");
-                                print_time(json_gen, buffer, cfg_getstr(sec, "format"), current_tm);
+                                print_time(json_gen, buffer, cfg_getstr(sec, "format"), NULL, tv.tv_sec);
+                                SEC_CLOSE_MAP;
+                        }
+
+                        CASE_SEC_TITLE("tztime") {
+                                SEC_OPEN_MAP("tztime");
+                                print_time(json_gen, buffer, cfg_getstr(sec, "format"), cfg_getstr(sec, "timezone"), tv.tv_sec);
                                 SEC_CLOSE_MAP;
                         }
 
                         CASE_SEC("ddate") {
                                 SEC_OPEN_MAP("ddate");
-                                print_ddate(json_gen, buffer, cfg_getstr(sec, "format"), current_tm);
+                                print_ddate(json_gen, buffer, cfg_getstr(sec, "format"), tv.tv_sec);
                                 SEC_CLOSE_MAP;
                         }
 
index 49ea488ae389c59393ebe75b9464168043ee8dcc..6b1d2d726e195a60eb0e2da2294fd6d75a52d838 100644 (file)
@@ -19,7 +19,7 @@ order += "wireless wlan0"
 order += "ethernet eth0"
 order += "battery 0"
 order += "load"
-order += "time"
+order += "tztime local"
 
 wireless wlan0 {
         format_up = "W: (%quality at %essid) %ip"
@@ -44,7 +44,7 @@ run_watch VPN {
         pidfile = "/var/run/vpnc/pid"
 }
 
-time {
+tztime local {
         format = "%Y-%m-%d %H:%M:%S"
 }
 
index 09394bd1bfade9396da1c87ffd1cd0224a7959eb..01d83d18e3b5de08a6903bbde17b4308fd24476d 100644 (file)
@@ -137,11 +137,14 @@ char *endcolor() __attribute__ ((pure));
 /* src/auto_detect_format.c */
 char *auto_detect_format();
 
+/* src/print_time.c */
+void set_timezone(const char *timezone);
+
 void print_ipv6_info(yajl_gen json_gen, char *buffer, const char *format_up, const char *format_down);
 void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format);
 void print_battery_info(yajl_gen json_gen, char *buffer, int number, const char *path, const char *format, int low_threshold, char *threshold_type, bool last_full_capacity);
-void print_time(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm);
-void print_ddate(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm);
+void print_time(yajl_gen json_gen, char *buffer, const char *format, const char *timezone, time_t t);
+void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t);
 const char *get_ip_addr();
 void print_wireless_info(yajl_gen json_gen, char *buffer, const char *interface, const char *format_up, const char *format_down);
 void print_run_watch(yajl_gen json_gen, char *buffer, const char *title, const char *pidfile, const char *format);
index 3f7a924ba64d0db6e576224485ffb222b6acb4a3..d7803638aac91aeaabc47b1e6dbaa0ed739c40d7 100644 (file)
@@ -56,7 +56,8 @@ order += "ethernet eth0"
 order += "battery 0"
 order += "cpu_temperature 0"
 order += "load"
-order += "time"
+order += "tztime local"
+order += "tztime berlin"
 
 wireless wlan0 {
         format_up = "W: (%quality at %essid, %bitrate) %ip"
@@ -83,8 +84,13 @@ run_watch VPN {
         pidfile = "/var/run/vpnc/pid"
 }
 
-time {
-       format = "%Y-%m-%d %H:%M:%S"
+tztime local {
+        format = "%Y-%m-%d %H:%M:%S"
+}
+
+tztime berlin {
+        format = "%Y-%m-%d %H:%M:%S %Z"
+        timezone = "Europe/Berlin"
 }
 
 load {
@@ -258,12 +264,31 @@ Gets the system load (number of processes waiting for CPU time in the last
 
 === Time
 
-Formats the current system time. See +strftime(3)+ for the format.
+Outputs the current time in the local timezone.
+To use a different timezone, you can set the TZ environment variable,
+or use the +tztime+ module.
+See +strftime(3)+ for details on the format string.
 
 *Example order*: +time+
 
 *Example format*: +%Y-%m-%d %H:%M:%S+
 
+=== TzTime
+
+Outputs the current time in the given timezone.
+If no timezone is given, local time will be used.
+See +strftime(3)+ for details on the format string.
+The system's timezone database is usually installed in +/usr/share/zoneinfo+.
+Files below that path make for valid timezone strings, e.g. for
++/usr/share/zoneinfo/Europe/Berlin+ you can set timezone to +Europe/Berlin+
+in the +tztime+ module.
+
+*Example order*: +tztime berlin+
+
+*Example format*: +%Y-%m-%d %H:%M:%S %Z+
+
+*Example timezone*: +Europe/Berlin+
+
 === DDate
 
 Outputs the current discordian date in user-specified format. See +ddate(1)+ for
index 82138620ddb4d7b4774d588b9ac1eb6413011cc4..de9a7be468e71d4232bc560963e19d438671784f 100644 (file)
@@ -204,11 +204,14 @@ struct disc_time *get_ddate(struct tm *current_tm) {
         return &dt;
 }
 
-void print_ddate(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm) {
+void print_ddate(yajl_gen json_gen, char *buffer, const char *format, time_t t) {
         char *outwalk = buffer;
         static char *form = NULL;
+        struct tm current_tm;
         struct disc_time *dt;
-        if ((dt = get_ddate(current_tm)) == NULL)
+        set_timezone(NULL);  /* Use local time. */
+        localtime_r(&t, &current_tm);
+        if ((dt = get_ddate(&current_tm)) == NULL)
                 return;
         if (form == NULL)
                 if ((form = malloc(strlen(format) + 1)) == NULL)
index 00a619636decd905bf9b9e40108c055df165bbb1..ad1efddc982bf0ff2fcaa6e6cdeef4e07eb3545a 100644 (file)
@@ -7,12 +7,39 @@
 
 #include "i3status.h"
 
-void print_time(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm) {
+static int local_timezone_init = 0;
+static const char *local_timezone = NULL;
+static const char *current_timezone = NULL;
+
+void set_timezone(const char *timezone) {
+        if (!local_timezone_init) {
+                /* First call, initialize. */
+                local_timezone = getenv("TZ");
+                local_timezone_init = 1;
+        }
+        if (timezone == NULL || timezone[0] == '\0') {
+                /* User wants localtime. */
+                timezone = local_timezone;
+        }
+        if (timezone != current_timezone) {
+                if (timezone) {
+                        setenv("TZ", timezone, 1);
+                } else {
+                        unsetenv("TZ");
+                }
+                tzset();
+                current_timezone = timezone;
+        }
+}
+
+void print_time(yajl_gen json_gen, char *buffer, const char *format, const char *timezone, time_t t) {
         char *outwalk = buffer;
-        if (current_tm == NULL)
-                return;
-        /* Get date & time */
-        outwalk += strftime(outwalk, 4095, format, current_tm);
+        struct tm tm;
+
+        /* Convert time and format output. */
+        set_timezone(timezone);
+        localtime_r(&t, &tm);
+        outwalk += strftime(outwalk, 4095, format, &tm);
         *outwalk = '\0';
         OUTPUT_FULL_TEXT(buffer);
 }