1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
#include "config.h"
#if IS_LINUX
/* Linux cheats AC_CHECK_FUNCS(strptime_l), sigh. */
#define THREAD_SAFE 0
#define _XOPEN_SOURCE
#define _DEFAULT_SOURCE
#define _BSD_SOURCE
#elif HAVE_STRPTIME_L
#define THREAD_SAFE 1
#define _GNU_SOURCE
#else
#define THREAD_SAFE 0
#endif
#include <string.h>
#include <time.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>
#if defined(_WIN32)
#include "win_patch.h"
#endif // _WIN32
#if THREAD_SAFE
#if HAVE_XLOCALE_H
#include <xlocale.h>
#endif
locale_t c_locale = NULL;
void init_locale() {
if (c_locale == NULL) c_locale = newlocale(LC_TIME_MASK, "C", NULL);
}
#else
void init_locale() {
static int initialized = 0;
if (initialized == 0) {
setlocale(LC_TIME, "C");
initialized = 1;
}
}
#endif
/*
* Set the value of the TZ environment variable to UTC
* and return the old value.
*/
char *set_tz_utc() {
char *tz;
tz = getenv("TZ");
#if defined(_WIN32)
_patch_setenv("TZ", "UTC", 1);
#else
setenv("TZ", "", 1);
#endif
tzset();
return tz;
}
/*
* Set the value of the TZ environment variable to tz or
* unset the variable if tz is null;
*/
void set_tz(char *local_tz) {
if (local_tz) {
#if defined(_WIN32)
_patch_setenv("TZ", local_tz, 1);
#else
setenv("TZ", local_tz, 1);
#endif
} else {
#if defined(_WIN32)
_patch_unsetenv("TZ");
#else
unsetenv("TZ");
#endif
}
tzset();
}
time_t c_parse_unix_time(char *fmt, char *src) {
struct tm dst;
init_locale();
memset(&dst, 0, sizeof(struct tm));
#if THREAD_SAFE
strptime_l(src, fmt, &dst, c_locale);
#else
strptime(src, fmt, &dst);
#endif
return mktime(&dst);
}
#if !defined(HAVE_TIMEGM)
/* This part is for Solaris that doesn't have timegm.
* The copyright notice of timegm and is_leap is as below:
*
* Copyright (c) 1997 Kungliga Tekniska H.gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*/
static time_t
timegm (struct tm *tm)
{
static const unsigned ndays[2][12] ={
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
time_t res = 0;
unsigned i;
for (i = 70; i < tm->tm_year; ++i)
res += isleap(i + 1900) ? 366 : 365;
for (i = 0; i < tm->tm_mon; ++i)
res += ndays[isleap(tm->tm_year + 1900)][i];
res += tm->tm_mday - 1;
res *= 24;
res += tm->tm_hour;
res *= 60;
res += tm->tm_min;
res *= 60;
res += tm->tm_sec;
return res;
}
#endif /* HAVE_TIMEGM */
time_t c_parse_unix_time_gmt(char *fmt, char *src) {
struct tm dst;
char *local_tz;
init_locale();
memset(&dst, 0, sizeof(struct tm));
local_tz = set_tz_utc();
#if THREAD_SAFE
strptime_l(src, fmt, &dst, c_locale);
#else
strptime(src, fmt, &dst);
#endif
set_tz(local_tz);
return timegm(&dst);
}
size_t c_format_unix_time(char *fmt, time_t src, char* dst, int siz) {
struct tm tim;
init_locale();
localtime_r(&src, &tim);
#if THREAD_SAFE
#if defined(_WIN32)
return _patch_strftime_l(dst, siz, fmt, &tim, c_locale);
#else
return strftime_l(dst, siz, fmt, &tim, c_locale);
#endif // _WIN32
#else
#if defined(_WIN32)
return _patch_strftime(dst, siz, fmt, &tim);
#else
return strftime(dst, siz, fmt, &tim);
#endif // _WIN32
#endif
}
size_t c_format_unix_time_gmt(char *fmt, time_t src, char* dst, int siz) {
struct tm tim;
char *local_tz;
size_t dst_size;
init_locale();
gmtime_r(&src, &tim);
local_tz = set_tz_utc();
#if THREAD_SAFE
#if defined(_WIN32)
dst_size = _patch_strftime_l(dst, siz, fmt, &tim, c_locale);
#else
dst_size = strftime_l(dst, siz, fmt, &tim, c_locale);
#endif // _WIN32
#else
#if defined(_WIN32)
dst_size = _patch_strftime(dst, siz, fmt, &tim);
#else
dst_size = strftime(dst, siz, fmt, &tim);
#endif // _WIN32
#endif
set_tz(local_tz);
return dst_size;
}
|