From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 47C1C6EC40; Wed, 18 Aug 2021 02:33:12 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 47C1C6EC40 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1629243192; bh=HyADfY5/WBW+tKFsBW65GCobawGpFXjuqxzRJhVI+HM=; h=To:References:Date:In-Reply-To:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=x++avO5NHS2Wih2BgDkbhcntEmvRIk1zzubd7oQV+VoU2KUPmSPDNKHi+VO+VyGcT O3SvU3rH9atqNar02hdE0RYWKdgtjK3qodnvEG6HfxwWRZyL9cmBKyOOqCycCNIbgW 8xUuyf2PYz+3DNjbgAQZIPE9TXSamuQY7aTY3a44= Received: from smtp61.i.mail.ru (smtp61.i.mail.ru [217.69.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 11AE76EC40 for ; Wed, 18 Aug 2021 02:33:11 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 11AE76EC40 Received: by smtp61.i.mail.ru with esmtpa (envelope-from ) id 1mG8Zx-0008AF-HH; Wed, 18 Aug 2021 02:33:10 +0300 To: Serge Petrenko References: <8dccf7ee1d6db0f8fd194ab45ae16978b74ec99b.1629071531.git.tsafin@tarantool.org> Message-ID: <471b3f4b-f7d4-af25-24fa-7a64bb8b635d@tarantool.org> Date: Wed, 18 Aug 2021 02:32:57 +0300 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD92087353F0EC44DD972FF4A7D76DB5E242D14FEF1BD8BF4AC182A05F53808504026082A9CDFAD5650429C7E025DBE8A8EF59E7FFFEE4B17CD227E26F2B768EDF1 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7818460412E3A2163EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F79006377A079619B0C2EE308638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8BA03A70CEF0C3BADBEA5298987933C48117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCAA867293B0326636D2E47CDBA5A96583BD4B6F7A4D31EC0BC014FD901B82EE079FA2833FD35BB23D27C277FBC8AE2E8BAA867293B0326636D2E47CDBA5A96583BA9C0B312567BB2376E601842F6C81A19E625A9149C048EE7B96B19DC409332149AF716F719AB83ED8FC6C240DEA7642DBF02ECDB25306B2B78CF848AE20165D0A6AB1C7CE11FEE3034D30FDF2F620DBC0837EA9F3D19764C4224003CC836476EA7A3FFF5B025636E2021AF6380DFAD1A18204E546F3947CB11811A4A51E3B096D1867E19FE1407959CC434672EE6371089D37D7C0E48F6C8AA50765F790063788B3B24285A3CD0EEFF80C71ABB335746BA297DBC24807EABDAD6C7F3747799A X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A213B5FB47DCBC3458F0AFF96BAACF4158235E5A14AD4A4A4625E192CAD1D9E79D0B18DC6AC13D9A1CF5F0A19533A05E7F X-C1DE0DAB: 0D63561A33F958A514677ADAC6D9CC9E5F39E272EA4F1EC5A8AB836536507487D59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA757E10A58996CBD514410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D347215713CF3EEE9D1FA02BC1FE3DA919A2A18A1F1AC09BF282923751CDBC5663D3B0F8B98F55867CE1D7E09C32AA3244CCFDAA1B13C610840F713B50673DF94A93A92A9747B6CC88683B48618A63566E0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojuRQ/H5n28tqOcoZ/ggyO2Q== X-Mailru-Sender: B5B6A6EBBD94DAD8C64AB2DDE1BF89F439425C6F71583B4BC67ED471C2E5610009CA36E44B076DCF5C2808D6142752370A8ED71B308007E3DC85537438B7E1A423D748DE48713E689437F6177E88F7363CDA0F3B3F5B9367 X-Mras: Ok Subject: Re: [Tarantool-patches] [PATCH v5 3/8] lua, datetime: display datetime X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Safin Timur via Tarantool-patches Reply-To: Safin Timur Cc: tarantool-patches@dev.tarantool.org, v.shpilevoy@tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" My responses below, thanks... On 17.08.2021 15:15, Serge Petrenko wrote: > > > 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 >> +#include >>   #include >>   #include >> @@ -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. OMG! What a coincidence! Thanks! Updated accordingly... ----------------------------------------- diff --git a/src/lib/core/datetime.c b/src/lib/core/datetime.c index c05197efd..bdaaff555 100644 --- a/src/lib/core/datetime.c +++ b/src/lib/core/datetime.c @@ -78,15 +78,8 @@ datetime_strftime(const struct datetime *date, const char *fmt, char *buf, * calculated length of output string */ int -datetime_to_string(const struct datetime *date, char *buf, uint32_t len) +datetime_to_string(const struct datetime *date, char *buf, int 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 @@ -106,26 +99,24 @@ datetime_to_string(const struct datetime *date, char *buf, uint32_t len) 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); + int sz = 0; + SNPRINT(sz, snprintf, buf, len, "%04d-%02d-%02dT%02d:%02d", + year, month, day, hour, minute); if (sec || ns) { - sz = snprintf(buf, len, ":%02d", sec); - ADVANCE(sz); + SNPRINT(sz, snprintf, buf, len, ":%02d", sec); if (ns) { if ((ns % 1000000) == 0) - sz = snprintf(buf, len, ".%03d", ns / 1000000); + SNPRINT(sz, snprintf, buf, len, ".%03d", + ns / 1000000); else if ((ns % 1000) == 0) - sz = snprintf(buf, len, ".%06d", ns / 1000); + SNPRINT(sz, snprintf, buf, len, ".%06d", + ns / 1000); else - sz = snprintf(buf, len, ".%09d", ns); - ADVANCE(sz); + SNPRINT(sz, snprintf, buf, len, ".%09d", ns); } } if (offset == 0) { - sz = snprintf(buf, len, "Z"); - ADVANCE(sz); + SNPRINT(sz, snprintf, buf, len, "Z"); } else { if (offset < 0) @@ -133,10 +124,9 @@ datetime_to_string(const struct datetime *date, char *buf, uint32_t len) else sign = '+'; - sz = snprintf(buf, len, "%c%02d:%02d", sign, offset / 60, offset % 60); - ADVANCE(sz); + SNPRINT(sz, snprintf, buf, len, "%c%02d:%02d", sign, + offset / 60, offset % 60); } - return ret; + return sz; } -#undef ADVANCE diff --git a/src/lib/core/datetime.h b/src/lib/core/datetime.h index 3c7a7d99d..688ab59ec 100644 --- a/src/lib/core/datetime.h +++ b/src/lib/core/datetime.h @@ -62,7 +62,7 @@ struct datetime_interval { * @param len size ofoutput buffer */ int -datetime_to_string(const struct datetime *date, char *buf, uint32_t len); +datetime_to_string(const struct datetime *date, char *buf, int len); /** * Convert datetime to string using default asctime format diff --git a/src/lua/datetime.lua b/src/lua/datetime.lua index 4d946f194..96ecd1fee 100644 --- a/src/lua/datetime.lua +++ b/src/lua/datetime.lua @@ -31,7 +31,7 @@ ffi.cdef [[ // datetime.c int - datetime_to_string(const struct datetime * date, char *buf, uint32_t len); + datetime_to_string(const struct datetime * date, char *buf, int len); char * datetime_asctime(const struct datetime *date, char *buf); ----------------------------------------- > > >> +    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 >> + > > > > > >> 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. Surprisingly, that was original configuration of patches, then I've split it to smaller chunks. But yes, this test dependency shows that code should be in a single patch. Will do. [Will not push updated branch yet, to accumulate changes for Vova feedback] > > >>       } >>       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) >> >> > > > > Thanks, Timur