From: Serge Petrenko via Tarantool-patches <tarantool-patches@dev.tarantool.org> To: Timur Safin <tsafin@tarantool.org> Cc: tarantool-patches@dev.tarantool.org, v.shpilevoy@tarantool.org Subject: Re: [Tarantool-patches] [PATCH v5 3/8] lua, datetime: display datetime Date: Tue, 17 Aug 2021 15:15:41 +0300 [thread overview] Message-ID: <d6090e7a-f3bc-da67-2a72-c0afa79f2f01@tarantool.org> (raw) In-Reply-To: <8dccf7ee1d6db0f8fd194ab45ae16978b74ec99b.1629071531.git.tsafin@tarantool.org> 16.08.2021 02:59, Timur Safin via Tarantool-patches пишет: > * introduced output routine for converting datetime > to their default output format. > > * use this routine for tostring() in datetime.lua > > Part of #5941 > --- > extra/exports | 1 + > src/lib/core/datetime.c | 71 ++++++++++++++++++ > src/lib/core/datetime.h | 9 +++ > src/lua/datetime.lua | 35 +++++++++ > test/app-tap/datetime.test.lua | 131 ++++++++++++++++++--------------- > test/unit/CMakeLists.txt | 2 +- > test/unit/datetime.c | 61 +++++++++++---- > 7 files changed, 236 insertions(+), 74 deletions(-) > > diff --git a/extra/exports b/extra/exports > index 80eb92abd..2437e175c 100644 > --- a/extra/exports > +++ b/extra/exports > @@ -152,6 +152,7 @@ datetime_asctime > datetime_ctime > datetime_now > datetime_strftime > +datetime_to_string > decimal_unpack > decimal_from_string > decimal_unpack > diff --git a/src/lib/core/datetime.c b/src/lib/core/datetime.c > index c48295a6f..c24a0df82 100644 > --- a/src/lib/core/datetime.c > +++ b/src/lib/core/datetime.c > @@ -29,6 +29,8 @@ > * SUCH DAMAGE. > */ > > +#include <assert.h> > +#include <limits.h> > #include <string.h> > #include <time.h> > > @@ -94,3 +96,72 @@ datetime_strftime(const struct datetime *date, const char *fmt, char *buf, > struct tm *p_tm = datetime_to_tm(date); > return strftime(buf, len, fmt, p_tm); > } > + > +#define SECS_EPOCH_1970_OFFSET ((int64_t)DT_EPOCH_1970_OFFSET * SECS_PER_DAY) > + > +/* NB! buf may be NULL, and we should handle it gracefully, returning > + * calculated length of output string > + */ > +int > +datetime_to_string(const struct datetime *date, char *buf, uint32_t len) > +{ > +#define ADVANCE(sz) \ > + if (buf != NULL) { \ > + buf += sz; \ > + len -= sz; \ > + } \ > + ret += sz; > + > + int offset = date->offset; > + /* for negative offsets around Epoch date we could get > + * negative secs value, which should be attributed to > + * 1969-12-31, not 1970-01-01, thus we first shift > + * epoch to Rata Die then divide by seconds per day, > + * not in reverse > + */ > + int64_t secs = (int64_t)date->secs + offset * 60 + SECS_EPOCH_1970_OFFSET; > + assert((secs / SECS_PER_DAY) <= INT_MAX); > + dt_t dt = dt_from_rdn(secs / SECS_PER_DAY); > + > + int year, month, day, sec, ns, sign; > + dt_to_ymd(dt, &year, &month, &day); > + > + int hour = (secs / 3600) % 24, > + minute = (secs / 60) % 60; > + sec = secs % 60; > + ns = date->nsec; > + > + int ret = 0; > + uint32_t sz = snprintf(buf, len, "%04d-%02d-%02dT%02d:%02d", > + year, month, day, hour, minute); > + ADVANCE(sz); Please, replace snprintf + ADVANCE() with SNPRINT macro from src/trivia/util.h It does exactly what you need. > + if (sec || ns) { > + sz = snprintf(buf, len, ":%02d", sec); > + ADVANCE(sz); > + if (ns) { > + if ((ns % 1000000) == 0) > + sz = snprintf(buf, len, ".%03d", ns / 1000000); > + else if ((ns % 1000) == 0) > + sz = snprintf(buf, len, ".%06d", ns / 1000); > + else > + sz = snprintf(buf, len, ".%09d", ns); > + ADVANCE(sz); > + } > + } > + if (offset == 0) { > + sz = snprintf(buf, len, "Z"); > + ADVANCE(sz); > + } > + else { > + if (offset < 0) > + sign = '-', offset = -offset; > + else > + sign = '+'; > + > + sz = snprintf(buf, len, "%c%02d:%02d", sign, offset / 60, offset % 60); > + ADVANCE(sz); > + } > + return ret; > +} > +#undef ADVANCE > + <stripped> > diff --git a/test/app-tap/datetime.test.lua b/test/app-tap/datetime.test.lua > index 464d4bd49..244ec2575 100755 > --- a/test/app-tap/datetime.test.lua > +++ b/test/app-tap/datetime.test.lua > @@ -6,7 +6,7 @@ local date = require('datetime') > local ffi = require('ffi') > > > -test:plan(6) > +test:plan(7) > > test:test("Simple tests for parser", function(test) > test:plan(2) > @@ -17,74 +17,78 @@ test:test("Simple tests for parser", function(test) > end) > > test:test("Multiple tests for parser (with nanoseconds)", function(test) > - test:plan(168) > + test:plan(193) > -- borrowed from p5-time-moments/t/180_from_string.t > local tests = > { > - { '1970-01-01T00:00:00Z', 0, 0, 0 }, > - { '1970-01-01T02:00:00+02:00', 0, 0, 120 }, > - { '1970-01-01T01:30:00+01:30', 0, 0, 90 }, > - { '1970-01-01T01:00:00+01:00', 0, 0, 60 }, > - { '1970-01-01T00:01:00+00:01', 0, 0, 1 }, > - { '1970-01-01T00:00:00+00:00', 0, 0, 0 }, > - { '1969-12-31T23:59:00-00:01', 0, 0, -1 }, > - { '1969-12-31T23:00:00-01:00', 0, 0, -60 }, > - { '1969-12-31T22:30:00-01:30', 0, 0, -90 }, > - { '1969-12-31T22:00:00-02:00', 0, 0, -120 }, > - { '1970-01-01T00:00:00.123456789Z', 0, 123456789, 0 }, > - { '1970-01-01T00:00:00.12345678Z', 0, 123456780, 0 }, > - { '1970-01-01T00:00:00.1234567Z', 0, 123456700, 0 }, > - { '1970-01-01T00:00:00.123456Z', 0, 123456000, 0 }, > - { '1970-01-01T00:00:00.12345Z', 0, 123450000, 0 }, > - { '1970-01-01T00:00:00.1234Z', 0, 123400000, 0 }, > - { '1970-01-01T00:00:00.123Z', 0, 123000000, 0 }, > - { '1970-01-01T00:00:00.12Z', 0, 120000000, 0 }, > - { '1970-01-01T00:00:00.1Z', 0, 100000000, 0 }, > - { '1970-01-01T00:00:00.01Z', 0, 10000000, 0 }, > - { '1970-01-01T00:00:00.001Z', 0, 1000000, 0 }, > - { '1970-01-01T00:00:00.0001Z', 0, 100000, 0 }, > - { '1970-01-01T00:00:00.00001Z', 0, 10000, 0 }, > - { '1970-01-01T00:00:00.000001Z', 0, 1000, 0 }, > - { '1970-01-01T00:00:00.0000001Z', 0, 100, 0 }, > - { '1970-01-01T00:00:00.00000001Z', 0, 10, 0 }, > - { '1970-01-01T00:00:00.000000001Z', 0, 1, 0 }, > - { '1970-01-01T00:00:00.000000009Z', 0, 9, 0 }, > - { '1970-01-01T00:00:00.00000009Z', 0, 90, 0 }, > - { '1970-01-01T00:00:00.0000009Z', 0, 900, 0 }, > - { '1970-01-01T00:00:00.000009Z', 0, 9000, 0 }, > - { '1970-01-01T00:00:00.00009Z', 0, 90000, 0 }, > - { '1970-01-01T00:00:00.0009Z', 0, 900000, 0 }, > - { '1970-01-01T00:00:00.009Z', 0, 9000000, 0 }, > - { '1970-01-01T00:00:00.09Z', 0, 90000000, 0 }, > - { '1970-01-01T00:00:00.9Z', 0, 900000000, 0 }, > - { '1970-01-01T00:00:00.99Z', 0, 990000000, 0 }, > - { '1970-01-01T00:00:00.999Z', 0, 999000000, 0 }, > - { '1970-01-01T00:00:00.9999Z', 0, 999900000, 0 }, > - { '1970-01-01T00:00:00.99999Z', 0, 999990000, 0 }, > - { '1970-01-01T00:00:00.999999Z', 0, 999999000, 0 }, > - { '1970-01-01T00:00:00.9999999Z', 0, 999999900, 0 }, > - { '1970-01-01T00:00:00.99999999Z', 0, 999999990, 0 }, > - { '1970-01-01T00:00:00.999999999Z', 0, 999999999, 0 }, > - { '1970-01-01T00:00:00.0Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.00Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.0000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.00000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.000000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.0000000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.00000000Z', 0, 0, 0 }, > - { '1970-01-01T00:00:00.000000000Z', 0, 0, 0 }, > - { '1973-11-29T21:33:09Z', 123456789, 0, 0 }, > - { '2013-10-28T17:51:56Z', 1382982716, 0, 0 }, > - { '9999-12-31T23:59:59Z', 253402300799, 0, 0 }, > + {'1970-01-01T00:00Z', 0, 0, 0, 1}, > + {'1970-01-01T02:00+02:00', 0, 0, 120, 1}, > + {'1970-01-01T01:30+01:30', 0, 0, 90, 1}, > + {'1970-01-01T01:00+01:00', 0, 0, 60, 1}, > + {'1970-01-01T00:01+00:01', 0, 0, 1, 1}, > + {'1970-01-01T00:00Z', 0, 0, 0, 1}, > + {'1969-12-31T23:59-00:01', 0, 0, -1, 1}, > + {'1969-12-31T23:00-01:00', 0, 0, -60, 1}, > + {'1969-12-31T22:30-01:30', 0, 0, -90, 1}, > + {'1969-12-31T22:00-02:00', 0, 0, -120, 1}, > + {'1970-01-01T00:00:00.123456789Z', 0, 123456789, 0, 1}, > + {'1970-01-01T00:00:00.12345678Z', 0, 123456780, 0, 0}, > + {'1970-01-01T00:00:00.1234567Z', 0, 123456700, 0, 0}, > + {'1970-01-01T00:00:00.123456Z', 0, 123456000, 0, 1}, > + {'1970-01-01T00:00:00.12345Z', 0, 123450000, 0, 0}, > + {'1970-01-01T00:00:00.1234Z', 0, 123400000, 0, 0}, > + {'1970-01-01T00:00:00.123Z', 0, 123000000, 0, 1}, > + {'1970-01-01T00:00:00.12Z', 0, 120000000, 0, 0}, > + {'1970-01-01T00:00:00.1Z', 0, 100000000, 0, 0}, > + {'1970-01-01T00:00:00.01Z', 0, 10000000, 0, 0}, > + {'1970-01-01T00:00:00.001Z', 0, 1000000, 0, 1}, > + {'1970-01-01T00:00:00.0001Z', 0, 100000, 0, 0}, > + {'1970-01-01T00:00:00.00001Z', 0, 10000, 0, 0}, > + {'1970-01-01T00:00:00.000001Z', 0, 1000, 0, 1}, > + {'1970-01-01T00:00:00.0000001Z', 0, 100, 0, 0}, > + {'1970-01-01T00:00:00.00000001Z', 0, 10, 0, 0}, > + {'1970-01-01T00:00:00.000000001Z', 0, 1, 0, 1}, > + {'1970-01-01T00:00:00.000000009Z', 0, 9, 0, 1}, > + {'1970-01-01T00:00:00.00000009Z', 0, 90, 0, 0}, > + {'1970-01-01T00:00:00.0000009Z', 0, 900, 0, 0}, > + {'1970-01-01T00:00:00.000009Z', 0, 9000, 0, 1}, > + {'1970-01-01T00:00:00.00009Z', 0, 90000, 0, 0}, > + {'1970-01-01T00:00:00.0009Z', 0, 900000, 0, 0}, > + {'1970-01-01T00:00:00.009Z', 0, 9000000, 0, 1}, > + {'1970-01-01T00:00:00.09Z', 0, 90000000, 0, 0}, > + {'1970-01-01T00:00:00.9Z', 0, 900000000, 0, 0}, > + {'1970-01-01T00:00:00.99Z', 0, 990000000, 0, 0}, > + {'1970-01-01T00:00:00.999Z', 0, 999000000, 0, 1}, > + {'1970-01-01T00:00:00.9999Z', 0, 999900000, 0, 0}, > + {'1970-01-01T00:00:00.99999Z', 0, 999990000, 0, 0}, > + {'1970-01-01T00:00:00.999999Z', 0, 999999000, 0, 1}, > + {'1970-01-01T00:00:00.9999999Z', 0, 999999900, 0, 0}, > + {'1970-01-01T00:00:00.99999999Z', 0, 999999990, 0, 0}, > + {'1970-01-01T00:00:00.999999999Z', 0, 999999999, 0, 1}, > + {'1970-01-01T00:00:00.0Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.00Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.0000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.00000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.000000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.0000000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.00000000Z', 0, 0, 0, 0}, > + {'1970-01-01T00:00:00.000000000Z', 0, 0, 0, 0}, > + {'1973-11-29T21:33:09Z', 123456789, 0, 0, 1}, > + {'2013-10-28T17:51:56Z', 1382982716, 0, 0, 1}, > + {'9999-12-31T23:59:59Z', 253402300799, 0, 0, 1}, Please, squash this change into the previous commit. > } > for _, value in ipairs(tests) do > - local str, epoch, nsec, offset > - str, epoch, nsec, offset = unpack(value) > + local str, epoch, nsec, offset, check > + str, epoch, nsec, offset, check = unpack(value) > local dt = date(str) > test:ok(dt.secs == epoch, ('%s: dt.secs == %d'):format(str, epoch)) > test:ok(dt.nsec == nsec, ('%s: dt.nsec == %d'):format(str, nsec)) > test:ok(dt.offset == offset, ('%s: dt.offset == %d'):format(str, offset)) > + if check > 0 then > + test:ok(str == tostring(dt), ('%s == tostring(%s)'): > + format(str, tostring(dt))) > + end > end > end) > > @@ -203,4 +207,11 @@ test:test("Parse tiny date into seconds and other parts", function(test) > test:ok(tiny.hours == 0.00848, "hours") > end) > > > <stripped> -- Serge Petrenko
next prev parent reply other threads:[~2021-08-17 12:16 UTC|newest] Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-08-15 23:59 [Tarantool-patches] [PATCH v5 0/8] Initial datetime implementation Timur Safin via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 1/8] build: add Christian Hansen c-dt to the build Timur Safin via Tarantool-patches 2021-08-17 12:15 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:24 ` Safin Timur via Tarantool-patches 2021-08-18 8:56 ` Serge Petrenko via Tarantool-patches 2021-08-17 15:50 ` Vladimir Davydov via Tarantool-patches 2021-08-18 10:04 ` Safin Timur via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 2/8] lua: built-in module datetime Timur Safin via Tarantool-patches 2021-08-17 12:15 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:30 ` Safin Timur via Tarantool-patches 2021-08-18 8:56 ` Serge Petrenko via Tarantool-patches 2021-08-17 16:52 ` Vladimir Davydov via Tarantool-patches 2021-08-17 19:16 ` Vladimir Davydov via Tarantool-patches 2021-08-18 13:38 ` Safin Timur via Tarantool-patches 2021-08-18 10:03 ` Safin Timur via Tarantool-patches 2021-08-18 10:06 ` Safin Timur via Tarantool-patches 2021-08-18 11:45 ` Vladimir Davydov via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 3/8] lua, datetime: display datetime Timur Safin via Tarantool-patches 2021-08-17 12:15 ` Serge Petrenko via Tarantool-patches [this message] 2021-08-17 23:32 ` Safin Timur via Tarantool-patches 2021-08-17 17:06 ` Vladimir Davydov via Tarantool-patches 2021-08-18 14:10 ` Safin Timur via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 4/8] box, datetime: messagepack support for datetime Timur Safin via Tarantool-patches 2021-08-16 0:20 ` Safin Timur via Tarantool-patches 2021-08-17 12:15 ` Serge Petrenko via Tarantool-patches 2021-08-17 12:16 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:42 ` Safin Timur via Tarantool-patches 2021-08-18 9:01 ` Serge Petrenko via Tarantool-patches 2021-08-17 18:36 ` Vladimir Davydov via Tarantool-patches 2021-08-18 14:27 ` Safin Timur via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 5/8] box, datetime: datetime comparison for indices Timur Safin via Tarantool-patches 2021-08-17 12:16 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:43 ` Safin Timur via Tarantool-patches 2021-08-18 9:03 ` Serge Petrenko via Tarantool-patches 2021-08-17 19:05 ` Vladimir Davydov via Tarantool-patches 2021-08-18 17:18 ` Safin Timur via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 6/8] lua, datetime: time intervals support Timur Safin via Tarantool-patches 2021-08-17 12:16 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:44 ` Safin Timur via Tarantool-patches 2021-08-17 18:52 ` Vladimir Davydov via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 7/8] datetime: perf test for datetime parser Timur Safin via Tarantool-patches 2021-08-17 19:13 ` Vladimir Davydov via Tarantool-patches 2021-08-15 23:59 ` [Tarantool-patches] [PATCH v5 8/8] datetime: changelog for datetime module Timur Safin via Tarantool-patches 2021-08-17 12:16 ` Serge Petrenko via Tarantool-patches 2021-08-17 23:44 ` Safin Timur via Tarantool-patches 2021-08-18 9:04 ` Serge Petrenko via Tarantool-patches 2021-08-17 12:15 ` [Tarantool-patches] [PATCH v5 0/8] Initial datetime implementation Serge Petrenko via Tarantool-patches [not found] ` <20210818082222.mofgheciutpipelz@esperanza> 2021-08-18 8:25 ` Vladimir Davydov via Tarantool-patches 2021-08-18 13:24 ` Safin Timur via Tarantool-patches 2021-08-18 14:22 ` Vladimir Davydov via Tarantool-patches
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=d6090e7a-f3bc-da67-2a72-c0afa79f2f01@tarantool.org \ --to=tarantool-patches@dev.tarantool.org \ --cc=sergepetrenko@tarantool.org \ --cc=tsafin@tarantool.org \ --cc=v.shpilevoy@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v5 3/8] lua, datetime: display datetime' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox