diff options
| author | 2023-06-17 22:20:11 +0200 | |
|---|---|---|
| committer | 2023-06-17 22:20:11 +0200 | |
| commit | 36696695692ae816e8a3d442b7647e3aba1feba5 (patch) | |
| tree | 4a06bc97e2e1091657e8884022407ee8ecea3add | |
| parent | minor native sources cleanup (diff) | |
allow constructing your own date/tm values
| -rw-r--r-- | date/init.janet | 23 | ||||
| -rw-r--r-- | src/time.c | 10 | ||||
| -rw-r--r-- | src/tm.c | 15 | ||||
| -rw-r--r-- | test/02-api.janet | 8 |
4 files changed, 43 insertions, 13 deletions
diff --git a/date/init.janet b/date/init.janet index aaf2272..215b019 100644 --- a/date/init.janet +++ b/date/init.janet @@ -1,15 +1,30 @@ (import date/native) -(defn time - `Return an opaque datetime representation of the current moment.` - [] - (native/time)) +(def time + `Return an opaque date/time representation of the current moment.` + native/time) (defn time? `Check if x is a date/time object.` [x] (= :date/time (type x))) +(defn- tm + [f &opt o] + (def out (native/tm o)) + (f out) + out) + +(def utc + `Generate a date/tm object from a compatible dictionary. Implying UTC. + Non-specified fields will be initialized to their default values (usually zero).` + (partial tm native/timegm!)) + +(def local + `Generate a date/tm object from a compatible dictionary. Implying localtime. + Non-specified fields will be initialized to their default values (usually zero).` + (partial tm native/mktime!)) + (defn tm? `Check if x is a date/tm object.` [x] @@ -22,10 +22,14 @@ static int jd_time_get(void *p, Janet key, Janet *out) { return janet_getmethod(janet_unwrap_keyword(key), jd_time_methods, out); } -// time_t is always a UTC-representation +// time_t is an arithmetic type, which means some width of int or float +// instead of trying to guess the type, +// we give the number of seconds from the zero-value of time_t +// on UNIX platforms, this is the number of seconds since UNIX epoch (1970) +// ultimately, the user knows what platform they're on, making the output useful static void jd_time_tostring(void *p, JanetBuffer *buffer) { - // print ISO 8601 - strftime_buffer("%F %T%z", gmtime(p), buffer); + double dt = difftime(*(time_t*)p, 0); + janet_formatb(buffer, "%f", dt); } static const JanetAbstractType jd_time_t = { @@ -215,15 +215,18 @@ struct tm *jd_opttm(Janet *argv, int32_t argc, int32_t n) { JANET_FN(jd_tm, "(tm {:sec 0 ...})", - "Construct a date/tm object from a compatible dictionary.") { - janet_fixarity(argc, 1); - JanetDictView view = janet_getdictionary(argv, 0); + "Construct a date/tm object from a compatible dictionary.\n" + "Note that you *must* immediate pass this into timegm or mktime.") { + janet_arity(argc, 0, 1); struct tm *out = jd_maketm(); + // default values memset(out, 0, sizeof(struct tm)); -#ifdef TM_GMTOFF - out->TM_GMTOFF = 0; -#endif + out->tm_mday = 1; // range is 1-31 + + if (argc == 0 || janet_checktype(argv[0], JANET_NIL)) return janet_wrap_abstract(out); + + JanetDictView view = janet_getdictionary(argv, 0); for (int32_t i = 0; i < view.cap; i++) { const JanetKV e = view.kvs[i]; diff --git a/test/02-api.janet b/test/02-api.janet index eb0666f..2a9c0ec 100644 --- a/test/02-api.janet +++ b/test/02-api.janet @@ -19,3 +19,11 @@ (assert (date/format now :default true)) # format string (assert (date/format now :%c)) + +# ensure tm + gmtime are spec-compliant +(def u (date/utc {:year 1970})) +(def l (date/local {:year 1970})) +(assert (= u + (:gmtime (:timegm u)))) +(assert (= l + (:localtime (:mktime l)))) |
