std: add localtime/gmtime support.

This commit is contained in:
Erick Tryzelaar
2012-04-03 10:32:26 -07:00
parent 72444636d3
commit 4a4889859e
3 changed files with 304 additions and 0 deletions

View File

@@ -8,6 +8,8 @@
#include "rust_abi.h"
#include "rust_port.h"
#include <time.h>
#ifdef __APPLE__
#include <crt_externs.h>
#endif
@@ -448,6 +450,127 @@ precise_time_ns(uint64_t *ns) {
*ns = t.time_ns();
}
struct rust_tm {
int32_t tm_sec;
int32_t tm_min;
int32_t tm_hour;
int32_t tm_mday;
int32_t tm_mon;
int32_t tm_year;
int32_t tm_wday;
int32_t tm_yday;
int32_t tm_isdst;
int32_t tm_gmtoff;
rust_str *tm_zone;
int32_t tm_nsec;
};
void rust_tm_to_tm(rust_tm* in_tm, tm* out_tm) {
memset(out_tm, 0, sizeof(tm));
out_tm->tm_sec = in_tm->tm_sec;
out_tm->tm_min = in_tm->tm_min;
out_tm->tm_hour = in_tm->tm_hour;
out_tm->tm_mday = in_tm->tm_mday;
out_tm->tm_mon = in_tm->tm_mon;
out_tm->tm_year = in_tm->tm_year;
out_tm->tm_wday = in_tm->tm_wday;
out_tm->tm_yday = in_tm->tm_yday;
out_tm->tm_isdst = in_tm->tm_isdst;
}
void tm_to_rust_tm(tm* in_tm, rust_tm* out_tm, int32_t gmtoff,
const char *zone, int32_t nsec) {
out_tm->tm_sec = in_tm->tm_sec;
out_tm->tm_min = in_tm->tm_min;
out_tm->tm_hour = in_tm->tm_hour;
out_tm->tm_mday = in_tm->tm_mday;
out_tm->tm_mon = in_tm->tm_mon;
out_tm->tm_year = in_tm->tm_year;
out_tm->tm_wday = in_tm->tm_wday;
out_tm->tm_yday = in_tm->tm_yday;
out_tm->tm_isdst = in_tm->tm_isdst;
out_tm->tm_gmtoff = gmtoff;
out_tm->tm_nsec = nsec;
if (zone != NULL) {
size_t size = strlen(zone);
str_reserve_shared(&out_tm->tm_zone, size);
memcpy(out_tm->tm_zone->data, zone, size);
out_tm->tm_zone->fill = size + 1;
out_tm->tm_zone->data[size] = '\0';
}
}
#if defined(__WIN32__)
#define TZSET() _tzset()
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
#define GMTIME(clock, result) gmtime_s((result), (clock))
#define LOCALTIME(clock, result) localtime_s((result), (clock))
#define TIMEGM(result) _mkgmtime64(result)
#else
struct tm* GMTIME(const time_t *clock, tm *result) {
struct tm* t = gmtime(clock);
if (t == NULL || result == NULL) { return NULL; }
*result = *t;
return result;
}
struct tm* LOCALTIME(const time_t *clock, tm *result) {
struct tm* t = localtime(clock);
if (t == NULL || result == NULL) { return NULL; }
*result = *t;
return result;
}
#define TIMEGM(result) mktime((result)) - _timezone
#endif
#else
#define TZSET() tzset()
#define GMTIME(clock, result) gmtime_r((clock), (result))
#define LOCALTIME(clock, result) localtime_r((clock), (result))
#define TIMEGM(result) timegm(result)
#endif
extern "C" CDECL void
rust_gmtime(int64_t *sec, int32_t *nsec, rust_tm *timeptr) {
tm tm;
time_t s = *sec;
GMTIME(&s, &tm);
tm_to_rust_tm(&tm, timeptr, 0, "UTC", *nsec);
}
extern "C" CDECL void
rust_localtime(int64_t *sec, int32_t *nsec, rust_tm *timeptr) {
tm tm;
TZSET();
time_t s = *sec;
LOCALTIME(&s, &tm);
#if defined(__WIN32__)
int32_t gmtoff = -timezone;
char zone[64];
strftime(zone, sizeof(zone), "%Z", &tm);
#else
int32_t gmtoff = tm.tm_gmtoff;
const char *zone = tm.tm_zone;
#endif
tm_to_rust_tm(&tm, timeptr, gmtoff, zone, *nsec);
}
extern "C" CDECL void
rust_timegm(rust_tm* timeptr, int64_t *out) {
tm t;
rust_tm_to_tm(timeptr, &t);
*out = TIMEGM(&t);
}
extern "C" CDECL void
rust_mktime(rust_tm* timeptr, int64_t *out) {
tm t;
rust_tm_to_tm(timeptr, &t);
*out = mktime(&t);
}
extern "C" CDECL rust_sched_id
rust_get_sched_id() {
rust_task *task = rust_get_current_task();