summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmil Mikulic <emikulic@gmail.com>2013-01-14 00:18:38 +1100
committerMichael Stapelberg <michael@stapelberg.de>2013-02-10 17:18:32 +0100
commit2ebe1f37269e9bec23a3f0c2e6be956884c7ab92 (patch)
treef326c0affdec8f9d19167f26e8de4dd92380f187
parent895cbad7a23cfac3b191c711fab052a74c04c0b2 (diff)
Add tztime module to support multiple different timezones.
-rw-r--r--i3status.c26
-rw-r--r--i3status.conf4
-rw-r--r--include/i3status.h7
-rw-r--r--man/i3status.man33
-rw-r--r--src/print_ddate.c7
-rw-r--r--src/print_time.c37
6 files changed, 89 insertions, 25 deletions
diff --git a/i3status.c b/i3status.c
index af62a7c..c1f6039 100644
--- a/i3status.c
+++ b/i3status.c
@@ -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;
}
diff --git a/i3status.conf b/i3status.conf
index 49ea488..6b1d2d7 100644
--- a/i3status.conf
+++ b/i3status.conf
@@ -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"
}
diff --git a/include/i3status.h b/include/i3status.h
index 09394bd..01d83d1 100644
--- a/include/i3status.h
+++ b/include/i3status.h
@@ -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);
diff --git a/man/i3status.man b/man/i3status.man
index 3f7a924..d780363 100644
--- a/man/i3status.man
+++ b/man/i3status.man
@@ -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
diff --git a/src/print_ddate.c b/src/print_ddate.c
index 8213862..de9a7be 100644
--- a/src/print_ddate.c
+++ b/src/print_ddate.c
@@ -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)
diff --git a/src/print_time.c b/src/print_time.c
index 00a6196..ad1efdd 100644
--- a/src/print_time.c
+++ b/src/print_time.c
@@ -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);
}