aboutsummaryrefslogtreecommitdiff
path: root/src/time.c
blob: f9bda70d179ab2a368c50016f67be2d29bd49549 (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
91
92
#include "date.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
static void jd_time_tostring(void *p, JanetBuffer *buffer) {
	// print ISO 8601
	strftime_buffer("%F %T%z", 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))",
		"Convert a date/time object into a date/tm object as UTC.") {
	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))",
		"Convert a date/time object into a date/tm object as localtime.") {
	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)",
		"Get the current moment in time as a date/time object.") {
	(void) argv;
	janet_fixarity(argc, 0);
	time_t *out = jd_maketime();
	time(out);
	return janet_wrap_abstract(out);
}

void jd_time_register(JanetTable *env, const char *regprefix) {
	const JanetRegExt cfuns[] = {
		JANET_REG("gmtime",     jd_gmtime),
		JANET_REG("localtime",  jd_localtime),
		JANET_REG("time",       jd_time),
		JANET_REG_END
	};
	janet_cfuns_ext(env, regprefix, cfuns);
}