#define AP_CTIME_OPTION_USEC 0x1
/* Use more compact ISO 8601 format */
#define AP_CTIME_OPTION_COMPACT 0x2
+/* Add timezone offset from GMT ([+-]hhmm) */
+#define AP_CTIME_OPTION_GMTOFF 0x4
/**
int time_len = buflen;
int option = AP_CTIME_OPTION_NONE;
- while (arg && *arg) {
- switch (*arg) {
- case 'u': option |= AP_CTIME_OPTION_USEC;
- break;
- case 'c': option |= AP_CTIME_OPTION_COMPACT;
- break;
+ if (arg) {
+ if (arg[0] == 'u' && !arg[1]) { /* no ErrorLogFormat (fast path) */
+ option |= AP_CTIME_OPTION_USEC;
+ }
+ else if (!ap_strchr_c(arg, '%')) { /* special "%{cuz}t" formats */
+ while (*arg) {
+ switch (*arg++) {
+ case 'u':
+ option |= AP_CTIME_OPTION_USEC;
+ break;
+ case 'c':
+ option |= AP_CTIME_OPTION_COMPACT;
+ break;
+ case 'z':
+ option |= AP_CTIME_OPTION_GMTOFF;
+ break;
+ }
+ }
+ }
+ else { /* "%{strftime %-format}t" */
+ apr_size_t len = 0;
+ apr_time_exp_t expt;
+ ap_explode_recent_localtime(&expt, apr_time_now());
+ apr_strftime(buf, &len, buflen, arg, &expt);
+ return (int)len;
}
- arg++;
}
ap_recent_ctime_ex(buf, apr_time_now(), option, &time_len);
#include "util_time.h"
#include "apr_env.h"
+#include "apr_strings.h"
/* Length of ISO 8601 date/time */
#define AP_CTIME_COMPACT_LEN 20
+/* Length of timezone offset from GMT ([+-]hhmm) plus leading space */
+#define AP_CTIME_GMTOFF_LEN 6
/* Cache for exploded values of recent timestamps
*/
needed += AP_CTIME_USEC_LENGTH;
}
+ if (option & AP_CTIME_OPTION_GMTOFF) {
+ needed += AP_CTIME_GMTOFF_LEN;
+ }
+
/* Check the provided buffer length */
if (len && *len >= needed) {
*len = needed;
}
/* example without options: "Wed Jun 30 21:49:08 1993" */
- /* 123456789012345678901234 */
/* example for compact format: "1993-06-30 21:49:08" */
- /* 1234567890123456789 */
+ /* example for compact+usec+gmtoff format:
+ * "1993-06-30 22:49:08.123456 +0100"
+ */
ap_explode_recent_localtime(&xt, t);
real_year = 1900 + xt.tm_year;
*date_str++ = real_year % 100 / 10 + '0';
*date_str++ = real_year % 10 + '0';
}
- *date_str++ = 0;
+ if (option & AP_CTIME_OPTION_GMTOFF) {
+ int off = xt.tm_gmtoff;
+ char sign = '+';
+ if (off < 0) {
+ off = -off;
+ sign = '-';
+ }
+ apr_snprintf(date_str, AP_CTIME_GMTOFF_LEN + 1, " %c%.2d%.2d",
+ sign, off / 3600, (off % 3600) / 60);
+ }
+ else {
+ *date_str = 0;
+ }
return APR_SUCCESS;
}