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 24B3A6EC43; Tue, 17 Aug 2021 15:16:40 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 24B3A6EC43 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1629202600; bh=vhvuQzaF26vbf8+tNqdGssEhnXmD0eYlJdU9ez6l+XE=; 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=Xqkhp4GWLChTYx2zXR3HJXQNT/a5impaTPrY0FYesE1qVEFUXqKwq84+OcwcWxTak wOTGH9jnP9a0bFwEuoh1WMuMWuJxc6QVhvqnGknPcK5YO+dB+J7Fp/6f8ZOH8AcqCC vcHD8ocUxIlYSj64XJdzOQ1ZwUdkslJY1ExqCM/Q= Received: from smtp54.i.mail.ru (smtp54.i.mail.ru [217.69.128.34]) (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 E62656EC45 for ; Tue, 17 Aug 2021 15:15:42 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E62656EC45 Received: by smtp54.i.mail.ru with esmtpa (envelope-from ) id 1mFy0L-0008Qu-H7; Tue, 17 Aug 2021 15:15:42 +0300 To: Timur Safin References: <8dccf7ee1d6db0f8fd194ab45ae16978b74ec99b.1629071531.git.tsafin@tarantool.org> Message-ID: Date: Tue, 17 Aug 2021 15:15:41 +0300 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 MIME-Version: 1.0 In-Reply-To: <8dccf7ee1d6db0f8fd194ab45ae16978b74ec99b.1629071531.git.tsafin@tarantool.org> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD92087353F0EC44DD9736CF3E71F18CE0C3E1D5927724F4AAA182A05F5380850401D5C39CD48216EDCAC9D4FD729A996923C33CB19AEC63E7088227B434CF298FD X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE707BCAA832FAF0FF2C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE78D182E101C1D80758F08D7030A58E5AD1A62830130A00468AEEEE3FBA3A834EE7353EFBB553375665B73F950BC6E7FFB2C0A1EA4DC7D0758974B2FDAB2BB2706A471835C12D1D9774AD6D5ED66289B5278DA827A17800CE71AE4D56B06699BBC9FA2833FD35BB23D2EF20D2F80756B5F868A13BD56FB6657A471835C12D1D977725E5C173C3A84C3CA5A41EBD8A3A0199FA2833FD35BB23DF004C906525384302BEBFE083D3B9BA71A620F70A64A45A98AA50765F79006372E808ACE2090B5E1725E5C173C3A84C3C5EA940A35A165FF2DBA43225CD8A89FB26E97DCB74E6252A91E23F1B6B78B78B5C8C57E37DE458BEDA766A37F9254B7 X-C1DE0DAB: 0D63561A33F958A59F0C29232FDE0B52D12C113D6BCA04A6BFC43F2AF79F862CD59269BC5F550898D99A6476B3ADF6B47008B74DF8BB9EF7333BD3B22AA88B938A852937E12ACA7567C209D01CC1E34B410CA545F18667F91A7EA1CDA0B5A7A0 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D34ECB3E21D3CD9CB4FD0BAAFA90D98FA7516773C82FA71ADC5E3BC9F2465B8D40B1786B2A4102A316C1D7E09C32AA3244CC3A41BCC5B0AE3150EB0245A128E2FE9F94338140B71B8EE83B48618A63566E0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojuRQ/H5n28toiV2MtNw25BQ== X-Mailru-Sender: 3B9A0136629DC9125D61937A2360A446536073F9A9F7FACE7D7D105B41A42DBD8D50A612EA6A48DA424AE0EB1F3D1D21E2978F233C3FAE6EE63DB1732555E4A8EE80603BA4A5B0BC112434F685709FCF0DA7A0AF5A3A8387 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: Serge Petrenko via Tarantool-patches Reply-To: Serge Petrenko Cc: tarantool-patches@dev.tarantool.org, v.shpilevoy@tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" 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. > + 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. > } > 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) > > > -- Serge Petrenko