hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 95933b0482f4b61613ff3b21878c4d65c09b9f31
parent e787950a7c64864630eee109dd5bcd5fa7aa2963
Author: Curtis Arthaud <uku82@gmx.fr>
Date:   Wed, 10 Apr 2024 11:04:04 +0200

time::date: add v.century, v.year100

Parsing something like "%y-%m-%d" is now easier.

Co-authored-by: Byron Torres <b@torresjrjr.com>
Signed-off-by: Byron Torres <b@torresjrjr.com>
Signed-off-by: Curtis Arthaud <uku82@gmx.fr>

Diffstat:
Mtime/date/format.ha | 4++++
Mtime/date/parse.ha | 4++++
Mtime/date/virtual.ha | 101++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
3 files changed, 72 insertions(+), 37 deletions(-)

diff --git a/time/date/format.ha b/time/date/format.ha @@ -128,6 +128,8 @@ fn fmtout(out: io::handle, r: rune, d: *date) (size | io::error) = { return fmt::fprint(out, MONTHS_SHORT[_month(d) - 1]); case 'B' => return fmt::fprint(out, MONTHS[_month(d) - 1]); + case 'C' => + return fmt::fprintf(out, "{:.2}", _year(d) / 100); case 'd' => return fmt::fprintf(out, "{:.2}", _day(d)); case 'e' => @@ -197,6 +199,7 @@ fn fmtout(out: io::handle, r: rune, d: *date) (size | io::error) = { // %A -- The full name of the day of the week. // %b -- The abbreviated name of the month. // %B -- The full name of the month. +// %C -- The century digits (all but the last two digits of the year). // %d -- The day of the month (decimal, range 01 to 31). // %e -- The day of the month (decimal, range 1 to 31), left-padded space. // %F -- The full date, equivalent to %Y-%m-%d @@ -272,6 +275,7 @@ export fn format( // year ("%Y", "1994"), ("%y", "94"), + ("%C", "19"), // month name ("%b", "Jan"), ("%B", "January"), diff --git a/time/date/parse.ha b/time/date/parse.ha @@ -74,6 +74,8 @@ fn parse_specifier( v.month = scan_for(iter, MONTHS_SHORT...)? + 1; case 'B' => v.month = scan_for(iter, MONTHS...)? + 1; + case 'C' => + v.century = scan_int(iter, 2)?; case 'd', 'e' => v.day = scan_int(iter, 2)?; case 'F' => @@ -118,6 +120,8 @@ fn parse_specifier( v.weekday = scan_int(iter, 1)? - 1; case 'W' => v.week = scan_int(iter, 2)?; + case 'y' => + v.year100 = scan_int(iter, 2)?; case 'Y' => v.year = scan_int(iter, 4)?; case 'z' => diff --git a/time/date/virtual.ha b/time/date/virtual.ha @@ -52,6 +52,10 @@ export type virtual = struct { zoff: (void | time::duration), // zone abbreviation zabbr: (void | str), + // all but the last two digits of the year + century: (void | int), + // the last two digits of the year + year100: (void | int), // hour of 12 hour clock hour12: (void | int), // AM/PM (false/true) @@ -89,6 +93,8 @@ export fn newvirtual() virtual = virtual { locname = void, zoff = void, zabbr = void, + century = void, + year100 = void, hour12 = void, ampm = void, }; @@ -133,15 +139,19 @@ export fn newvirtual() virtual = virtual { // // An empty .daydate depends on: // -// - .year, .month, .day -// - .year, .yearday -// - .year, .week, .weekday +// - .year*, .month, .day +// - .year*, .yearday +// - .year*, .week, .weekday // - .isoweekyear, .isoweek, .weekday // // An empty .daytime depends on: // // - .hour*, .minute, .second, .nanosecond // +// An empty .year depends on: +// +// - .century, .year100 +// // An empty .hour depends on: // // - .hour12, .ampm @@ -190,40 +200,57 @@ export fn realize( // determine .daydate if (v.daydate is i64) { void; - } else if ( - v.year is int && - v.month is int && - v.day is int - ) { - v.daydate = calc_daydate__ymd( - v.year as int, - v.month as int, - v.day as int, - )?; - } else if ( - v.year is int && - v.yearday is int - ) { - v.daydate = calc_daydate__yd( - v.year as int, - v.yearday as int, - )?; - } else if ( - v.year is int && - v.week is int && - v.weekday is int - ) { - v.daydate = calc_daydate__ywd( - v.year as int, - v.week as int, - v.weekday as int, - )?; - } else if (false) { - // TODO: calendar.ha: calc_daydate__isoywd() - void; - } else { - // cannot deduce daydate - lacking |= insufficient::DAYDATE; + } else :daydate { + const year = + if (v.year is int) { + yield v.year as int; + } else if (v.century is int && v.year100 is int) { + let cc = v.century as int; + let yy = v.year100 as int; + if (yy < 0 || yy > 99) { + return invalid; + }; + yield cc * 100 + yy; + } else { + lacking |= lack::DAYDATE; + yield :daydate; + }; + + if ( + v.year is int && + v.month is int && + v.day is int + ) { + v.daydate = calc_daydate__ymd( + v.year as int, + v.month as int, + v.day as int, + )?; + } else if ( + v.year is int && + v.yearday is int + ) { + v.daydate = calc_daydate__yd( + v.year as int, + v.yearday as int, + )?; + } else if ( + v.year is int && + v.week is int && + v.weekday is int + ) { + v.daydate = calc_daydate__ywd( + v.year as int, + v.week as int, + v.weekday as int, + )?; + } else if (false) { + // TODO: calendar.ha: calc_daydate__isoywd() + void; + } else { + // cannot deduce daydate + lacking |= insufficient::DAYDATE; + }; }; // determine .daytime