[icinga-checkins] icinga.org: icinga-core/mfriedrich/core: core: fix timeperiods daylight saving time problem (Luca Di Stefano) #1370

git at icinga.org git at icinga.org
Thu Apr 28 22:22:17 CEST 2011


Module: icinga-core
Branch: mfriedrich/core
Commit: 296a568b3a4f5674e39c00f438a631b58839c580
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=296a568b3a4f5674e39c00f438a631b58839c580

Author: Michael Friedrich <michael.friedrich at univie.ac.at>
Date:   Thu Apr 28 20:30:53 2011 +0200

core: fix timeperiods daylight saving time problem (Luca Di Stefano) #1370

needs further tests in t-tap/

refs #1370

---

 Changelog    |    1 +
 THANKS       |    1 +
 base/utils.c |   39 ++++++++++++++++++++++++++++++++++-----
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/Changelog b/Changelog
index 41f12e4..a4cd897 100644
--- a/Changelog
+++ b/Changelog
@@ -39,6 +39,7 @@ ENHANCEMENTS
 
 FIXES
 * core: fix flexible downtime on service hard state change doesn't get triggered/activated #1128
+* core: fix timeperiods daylight saving time problem (Luca Di Stefano) #1370
 
 * classic ui: Fixing tooltip's in status.cgi, not showing messages with carriage return #1244
 * classic ui: fixed csv export link to make it XSS save (IE) #1275
diff --git a/THANKS b/THANKS
index 0be4e3c..1f5c100 100644
--- a/THANKS
+++ b/THANKS
@@ -79,6 +79,7 @@ in various ways.  If we missed your name, let us know.
 * Karl DeBisschop
 * Tom De Blende
 * Mark DeTrano
+* Luca Di Stefano
 * Thomas Dohl
 * Mike Dorman
 * Albrecht Dress
diff --git a/base/utils.c b/base/utils.c
index 08945cc..3faa957 100644
--- a/base/utils.c
+++ b/base/utils.c
@@ -811,6 +811,24 @@ int set_environment_var(char *name, char *value, int set){
 /************************* TIME FUNCTIONS *************************/
 /******************************************************************/
 
+/* Checks if the given time is in daylight time saving period */
+int is_dlst_time(time_t *time) {
+	struct tm *bt = localtime(time);
+	return bt->tm_isdst;
+}
+
+/* Returns the shift in seconds if the given times are across the daylight time saving period change */
+int get_dlst_shift(time_t *start, time_t *end) {
+	int shift = 0, dlst_end, dlst_start;
+	dlst_start = is_dlst_time(start);
+	dlst_end = is_dlst_time(end);
+	if (dlst_start < dlst_end) {
+		shift = 3600;
+	} else if (dlst_start > dlst_end) {
+		shift = -3600;
+	}
+	return shift;
+}
 
 /*#define TEST_TIMEPERIODS_A 1*/
 
@@ -834,6 +852,7 @@ int check_time_against_period(time_t test_time, timeperiod *tperiod){
 	int test_time_mday=0;
 	int test_time_wday=0;
 	int year=0;
+	int shift;
 
 	log_debug_info(DEBUGL_FUNCTIONS,0,"check_time_against_period()\n");
 
@@ -1006,13 +1025,15 @@ int check_time_against_period(time_t test_time, timeperiod *tperiod){
 
 			/* calculate skip date start (and end) */
 			if(temp_daterange->skip_interval>1){
-
 				/* skip start date must be before test time */
 				if(start_time>test_time)
 					continue;
 
+				/* check if interval is across dlst change and gets the compensation */
+				shift=get_dlst_shift(&start_time,&midnight);
+
 				/* how many days have passed between skip start date and test time? */
-				days=(midnight-(unsigned long)start_time)/(3600*24);
+				days=(shift+midnight-(unsigned long)start_time)/(3600*24);
 
 				/* if test date doesn't fall on a skip interval day, bail out early */
 				if((days % temp_daterange->skip_interval)!=0)
@@ -1030,6 +1051,8 @@ int check_time_against_period(time_t test_time, timeperiod *tperiod){
 #ifdef TEST_TIMEPERIODS_A
 			printf("NEW START:    %lu = %s",(unsigned long)start_time,ctime(&start_time));
 			printf("NEW END:      %lu = %s",(unsigned long)end_time,ctime(&end_time));
+			printf("%d DAYS PASSED\n",days);
+			printf("DLST SHIFT:   %d",shift);
 #endif
 
 			/* time falls into the range of days */
@@ -1172,6 +1195,7 @@ void _get_next_valid_time_per_timeperiod(time_t pref_time, time_t *valid_time, t
 	int current_time_mon=0;
 	int current_time_mday=0;
 	int current_time_wday=0;
+	int shift;
 
 	/* preferred time must be now or in the future */
 	preferred_time=pref_time;
@@ -1397,9 +1421,11 @@ void _get_next_valid_time_per_timeperiod(time_t pref_time, time_t *valid_time, t
 
 				/* advance to the next possible skip date */
 				if(start_time<preferred_time){
+					/* check if interval is across dlst change and gets the compensation */
+					shift=get_dlst_shift(&start_time,&midnight);
 
 					/* how many days have passed between skip start date and preferred time? */
-					days=(midnight-(unsigned long)start_time)/(3600*24);
+					days=(shift+midnight-(unsigned long)start_time)/(3600*24);
 
 #ifdef TEST_TIMEPERIODS_B
 					printf("MIDNIGHT: %lu = %s",midnight,ctime(&midnight));
@@ -1407,6 +1433,7 @@ void _get_next_valid_time_per_timeperiod(time_t pref_time, time_t *valid_time, t
 					printf("%d DAYS PASSED\n",days);
 					printf("REMAINDER: %d\n",(days % temp_daterange->skip_interval));
 					printf("SKIP INTERVAL: %d\n",temp_daterange->skip_interval);
+					printf("DLST SHIFT: %d",shift);
 #endif
 
 					/* advance start date to next skip day */
@@ -1566,7 +1593,7 @@ void get_min_invalid_time_per_timeperiod(time_t pref_time, time_t *valid_time, t
 	int current_time_mon=0;
 	int current_time_mday=0;
 	int current_time_wday=0;
-
+	int shift;
 
 	log_debug_info(DEBUGL_FUNCTIONS,0,"get_next_valid_time_per_timeperiod()\n");
 
@@ -1771,9 +1798,11 @@ void get_min_invalid_time_per_timeperiod(time_t pref_time, time_t *valid_time, t
 
 				/* advance to the next possible skip date */
 				if(start_time<preferred_time){
+					/* check if interval is across dlst change and gets the compensation */
+					shift=get_dlst_shift(&start_time,&midnight);
 
 					/* how many days have passed between skip start date and preferred time? */
-					days=(midnight-(unsigned long)start_time)/(3600*24);
+					days=(shift+midnight-(unsigned long)start_time)/(3600*24);
 
 					/* advance start date to next skip day */
 					if((days % temp_daterange->skip_interval)==0)





More information about the icinga-checkins mailing list