tree data BUGFIX account for DST in timezone offset
Fixes cesnet/netopeer2#1378
diff --git a/src/tree_data.h b/src/tree_data.h
index 017ab5a..8307db3 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -2611,7 +2611,7 @@
LIBYANG_API_DECL LY_ERR lyd_find_target(const struct ly_path *path, const struct lyd_node *tree, struct lyd_node **match);
/**
- * @brief Get current timezone UTC (GMT) time offset in seconds.
+ * @brief Get current timezone UTC (GMT) time offset in seconds. Changes based on the current DST setting.
*
* @return Timezone shift in seconds.
*/
diff --git a/src/tree_data_common.c b/src/tree_data_common.c
index 0275ad5..51d971e 100644
--- a/src/tree_data_common.c
+++ b/src/tree_data_common.c
@@ -1536,16 +1536,24 @@
LIBYANG_API_DEF int
ly_time_tz_offset(void)
{
- const time_t epoch_plus_11h = 60 * 60 * 11;
+ time_t now;
struct tm tm_local, tm_utc;
int result = 0;
/* init timezone */
tzset();
+ /* get current timestamp (need to use it to account for DST) */
+ now = time(NULL);
+
/* get local and UTC time */
- localtime_r(&epoch_plus_11h, &tm_local);
- gmtime_r(&epoch_plus_11h, &tm_utc);
+ localtime_r(&now, &tm_local);
+ gmtime_r(&now, &tm_utc);
+
+ /* account for year/month/day change by adding/subtracting from the hours */
+ if (tm_local.tm_mday != tm_utc.tm_mday) {
+ tm_local.tm_hour += (tm_local.tm_mday - tm_utc.tm_mday) * 24;
+ }
/* hours shift in seconds */
result += (tm_local.tm_hour - tm_utc.tm_hour) * 3600;
@@ -1639,7 +1647,7 @@
return LY_ESYS;
}
- /* get timezone offset */
+ /* get timezone offset (do not use tm_gmtoff to avoid portability problems) */
zonediff_s = ly_time_tz_offset();
zonediff_h = zonediff_s / 60 / 60;
zonediff_m = zonediff_s / 60 % 60;