aboutsummaryrefslogtreecommitdiff
path: root/src/time.c
blob: da190cfb3114f5197a2062b8f42c8cbd05c862b9 (plain) (blame)
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
#include "date.h"
#include "janet.h"

// wrappers around time_t

static JanetMethod jd_time_methods[] = {
	{"gmtime",    jd_gmtime},
	{"localtime", jd_localtime},
	{NULL, NULL},
};

static int jd_time_compare(void *lhs, void *rhs) {
	time_t lhv = (*(time_t*)lhs);
	time_t rhv = (*(time_t*)rhs);
	return difftime(lhv, rhv);
}

static int jd_time_get(void *p, Janet key, Janet *out) {
	(void) p;
	if (!janet_checktype(key, JANET_KEYWORD)) {
		return 0;
	}
	return janet_getmethod(janet_unwrap_keyword(key), jd_time_methods, out);
}

// time_t is always a UTC-representation
// we hard-code the offset because of a macOS bug
static void jd_time_tostring(void *p, JanetBuffer *buffer) {
	strftime_buffer("%F %T.000 +0000", gmtime(p), buffer);
}

static const JanetAbstractType jd_time_t = {
	"date/time",
	NULL,
	NULL,
	jd_time_get,
	NULL,
	NULL,
	NULL,
	jd_time_tostring,
	jd_time_compare,
	JANET_ATEND_COMPARE
};

time_t *jd_gettime(Janet *argv, int32_t n) {
	return (time_t*)janet_getabstract(argv, n, &jd_time_t);
}

time_t *jd_maketime(void) {
	return janet_abstract(&jd_time_t, sizeof(time_t));
}

JANET_FN(jd_gmtime,
		"(gmtime (time))",
		"") {
	janet_fixarity(argc, 1);
	time_t *time   = jd_gettime(argv, 0);
	struct tm *tm  = gmtime(time);
	struct tm *out = jd_maketm();
	*out = *tm;
	return janet_wrap_abstract(out);
}

JANET_FN(jd_localtime,
		"(localtime (time))",
		"") {
	janet_fixarity(argc, 1);
	time_t *time   = jd_gettime(argv, 0);
	struct tm *tm  = localtime(time);
	struct tm *out = jd_maketm();
	*out = *tm;
	return janet_wrap_abstract(out);
}

JANET_FN(jd_time,
		"(time)",
		"") {
	(void) argv;
	janet_fixarity(argc, 0);
	time_t *out = jd_maketime();
	time(out);
	return janet_wrap_abstract(out);
}

const JanetRegExt jd_time_cfuns[] = {
	JANET_REG("gmtime",     jd_gmtime),
	JANET_REG("localtime",  jd_localtime),
	JANET_REG("time",       jd_time),
	JANET_REG_END
};