summaryrefslogtreecommitdiffstats
path: root/runtime/datetime.c
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-03-29 18:04:12 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-03-29 18:04:12 +0200
commitb88ba949f8d657034f808034321fabbd65bf8078 (patch)
tree2cf7d0c34d4e9fa6db3625d0833382d74fe7b698 /runtime/datetime.c
parent3dccce084a65376b7555aec77c4cf1368cdd9cb7 (diff)
downloadrsyslog-b88ba949f8d657034f808034321fabbd65bf8078.tar.gz
rsyslog-b88ba949f8d657034f808034321fabbd65bf8078.tar.xz
rsyslog-b88ba949f8d657034f808034321fabbd65bf8078.zip
added "date-unixtimestamp" property replacer option to format as a unix timestamp
Diffstat (limited to 'runtime/datetime.c')
-rw-r--r--runtime/datetime.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/runtime/datetime.c b/runtime/datetime.c
index d30c6e0b..830c67e3 100644
--- a/runtime/datetime.c
+++ b/runtime/datetime.c
@@ -850,6 +850,117 @@ int formatTimestamp3164(struct syslogTime *ts, char* pBuf, int bBuggyDay)
}
+/**
+ * format a timestamp as a UNIX timestamp; subsecond resolution is
+ * discarded.
+ * Note that this code can use some refactoring. I decided to use it
+ * because mktime() requires an upfront TZ update as it works on local
+ * time. In any case, it is worth reconsidering to move to mktime() or
+ * some other method.
+ * Important: pBuf must point to a buffer of at least 11 bytes.
+ * rgerhards, 2012-03-29
+ */
+int formatTimestampUnix(struct syslogTime *ts, char *pBuf)
+{
+ long MonthInDays, NumberOfYears, NumberOfDays, i;
+ int utcOffset;
+ time_t TimeInUnixFormat;
+
+ /* Counting how many Days have passed since the 01.01 of the
+ * selected Year (Month level), according to the selected Month*/
+
+ switch(ts->month)
+ {
+ case 1:
+ MonthInDays = 0; //until 01 of January
+ break;
+ case 2:
+ MonthInDays = 31; //until 01 of February - leap year handling down below!
+ break;
+ case 3:
+ MonthInDays = 59; //until 01 of March
+ break;
+ case 4:
+ MonthInDays = 90; //until 01 of April
+ break;
+ case 5:
+ MonthInDays = 120; //until 01 of Mai
+ break;
+ case 6:
+ MonthInDays = 151; //until 01 of June
+ break;
+ case 7:
+ MonthInDays = 181; //until 01 of July
+ break;
+ case 8:
+ MonthInDays = 212; //until 01 of August
+ break;
+ case 9:
+ MonthInDays = 243; //until 01 of September
+ break;
+ case 10:
+ MonthInDays = 273; //until 01 of Oktober
+ break;
+ case 11:
+ MonthInDays = 304; //until 01 of November
+ break;
+ case 12:
+ MonthInDays = 334; //until 01 of December
+ break;
+ }
+
+
+ /* 1) Counting how many Years have passed since 1970
+ 2) Counting how many Days have passed since the 01.01 of the selected Year
+ (Day level) according to the Selected Month and Day. Last day doesn't count,
+ it should be until last day
+ 3) Calculating this period (NumberOfDays) in seconds*/
+
+ NumberOfYears = ts->year - 1970;
+ NumberOfDays = MonthInDays + ts->day - 1;
+ TimeInUnixFormat = NumberOfYears * 31536000 + NumberOfDays * 86400;
+
+ /* Now we need to adjust the number of years for leap
+ * year processing. If we are in Jan or Feb, this year
+ * will never be considered - because we haven't arrived
+ * at then end of Feb right now. [Feb, 29th in a leap year
+ * is handled correctly, because the day (29) is correctly
+ * added to the date serial]
+ */
+ if(ts->month < 3)
+ NumberOfYears--;
+
+ /*...AND ADDING ONE DAY FOR EACH YEAR WITH 366 DAYS
+ * note that we do not handle 2000 any special, as it was a
+ * leap year. The current code works OK until 2100, when it will
+ * break. As we do not process future dates, we accept that fate...
+ * the whole thing could be refactored by a table-based approach.
+ */
+ for(i = 1;i <= NumberOfYears; i++)
+ {
+ /* If i = 2 we have 1972, which was a Year with 366 Days
+ and if (i + 2) Mod (4) = 0 we have a Year after 1972
+ which is also a Year with 366 Days (repeated every 4 Years) */
+ if ((i == 2) || (((i + 2) % 4) == 0))
+ { /*Year with 366 Days!!!*/
+ TimeInUnixFormat += 86400;
+ }
+ }
+
+ /*Add Hours, minutes and seconds */
+ TimeInUnixFormat += ts->hour*60*60;
+ TimeInUnixFormat += ts->minute*60;
+ TimeInUnixFormat += ts->second;
+ /* do UTC offset */
+ utcOffset = ts->OffsetHour*3600 + ts->OffsetMinute*60;
+ if(ts->OffsetMode == '+')
+ utcOffset *= -1; /* if timestamp is ahead, we need to "go back" to UTC */
+ TimeInUnixFormat += utcOffset;
+ snprintf(pBuf, 11, "%u", (unsigned) TimeInUnixFormat);
+ return 11;
+}
+
+
/* queryInterface function
* rgerhards, 2008-03-05
*/
@@ -874,6 +985,7 @@ CODESTARTobjQueryInterface(datetime)
pIf->formatTimestampSecFrac = formatTimestampSecFrac;
pIf->formatTimestamp3339 = formatTimestamp3339;
pIf->formatTimestamp3164 = formatTimestamp3164;
+ pIf->formatTimestampUnix = formatTimestampUnix;
finalize_it:
ENDobjQueryInterface(datetime)