From: Steve Simon <steve@quintile.net>
To: 9front@9front.org
Subject: Re: [9front] Date and time handling.
Date: Wed, 8 Apr 2020 07:48:18 +0100 [thread overview]
Message-ID: <43B494B5-78E6-4967-ACE5-289ADD02CD2F@quintile.net> (raw)
In-Reply-To: <09D185393BD8E86D37288FC967E7EA69@eigenstate.org>
well done!
i tried to do this years ago whilst writing an ical parser - and gave up in horror.
-Steve
> On 8 Apr 2020, at 5:57 am, ori@eigenstate.org wrote:
>
> Hi,
>
> Date handling on 9front is almost adequate today if you don't
> have to parse dates or deal with timezones, and don't do
> multithreading. Otherwise, it's difficult to get right, and
> we often don't.
>
> We've got a crappy home-rolled date parser in seconds(1),
> a few in the upas source tree to deal with mail formats,
> and git9 has a few hacks around this as well.
>
> Out of tree, joe9 has been trying to write code that takes
> stock information in one timezone and moves them to another,
> and our APIs there are completely inadequate.
>
> So, I tried to write a library that is adequate, without
> being complicated.
>
> It allows working with times in multiple timezones at the
> same time. It is thread safe, including timezone loading.
> It allows parsing and formatting arbitrary formats. It lets
> you adjust the day and figure out the timeshift-shift
> adjusted time.
>
> Eventually, when it's ready (not yet), I'd like to put this
> into libc. The API additions are small, and all of our curent
> time APIs can be implemented trivially in terms of this api.
> At worst, I'd like to add the field additions from struct tmd
> to it.
>
> There are a few known bugs -- not all fields of the time struct
> are filled in yet, for example.
>
> The code is here:
>
> https://git.eigenstate.org/ori/date.git
>
> The formatted draft of the manpage is below, for comments and
> thoughts:
>
> TMDATE(2) TMDATE(2)
>
> NAME
> tmnow, tmtime, tmstime, tmshiftzone, tmparse, tmfmt, tmnorm,
> - convert date and time
>
> SYNOPSIS
> #include <u.h>
> #include <libc.h>
>
> typedef struct Tmd Tmd;
> struct {
> vlong abs; /* milliseconds since Jan 1 1970, GMT */
> int sec; /* seconds (range 0..59) */
> int min; /* minutes (0..59) */
> int hour; /* hours (0..23) */
> int mday; /* day of the month (1..31) */
> int mon; /* month of the year (0..11) */
> int year; /* year A.D. - 1900 */
> int wday; /* day of week (0..6, Sunday = 0) */
> int yday; /* day of year (0..365) */
> char zone[]; /* time zone name */
> int tzoff; /* time zone delta from GMT */
> };
>
> Tm *tmnow(Tm *tm, char *tz);
> Tm *tmtime(Tm *tm, vlong abs, char *tz);
> Tm *tmstime(Tm *tm, vlong sec, char *tz);
> Tm *tmshiftzone(Tm *dst, Tm *src, char *tz);
> Tm *tmparse(Tm *dst, char *fmt, char *tm);
> int tmfmt(char *buf, usize nbuf, char *fmt, Tm *tm);
> void tmnorm(Tm *tm);
> void tmfmtinstall(char *fmt);
>
> DESCRIPTION
> This family of functions handles simple date and time manpu-
> lation. Times are represented as an absolute instant in
> time, combined with a time zone.
>
> Time zones are represented as strings. They can be provided
> as the abbreviated timezone name, the full timezone name,
> the path to a timezone file, or an absolute offset in the
> HHMM form.
>
> When given as a timezone name, any instant-dependent adjust-
> ments such as leap seconds and daylight savings time will be
> applied to the derived fields of struct tm, but will not
> affect the absolute time. The time zone name local always
> refers to the time in /env/timezone.
>
> Tmnow gets the current time of day in the requested time
> zone.
>
> Tmtime converts the millisecond-resolution timestamp 'abs'
> into a Tm struct in the requested timezone.
>
> Tmstime is identical to tmtime, but accepts the time in sec-
> onds.
>
> Tmshiftzone moves a time from one timezone to another, doing
> the appropriate conversions.
>
> Tmparse parses a time from a string according to the format
> argument. The format argument takes the form of a special
> date string, with the following components:
>
> 1,Jan,January
> Represents the month in numeric, short, or long form,
> respectively.
>
> 2 The day of month.
>
> 3,Mon,Monday
> The day of week in numeric, short, or long form,
> respectively.
>
> 3,15 The hour in 12 or 24 hour time, respectively.
>
> 4 The minute.
>
> 5 The second.
>
> 6,2006
> The year in 2 and 4 digit forms, respectively.
>
> 7,MST
> The time zone offset in numeric or abbreviated form.
> As a special case, 7:00 will fill in both the hour and
> minutes in the timezone.
>
> _ Pads the following field with spaces. 0 Pads the fol-
> lowing field with zeroes.
>
> If the format argument is nil, it makes an attempt to parse
> common human readable date formats. These formats include
> ISO-8601,RFC-3339 and RFC-2822 dates.
>
> Tmfmt formats a Tm struct according to the format fmt. If
> fmt is nil, we format as in ctime(2). At most nbuf-1 char-
> actters are written into buf, which is nul-terminated.
>
> Tmrecalc takes a manually adjusted Tm structure, and recal-
> culates the absolute time from it. This recalculation
> respects the time zone stored in struct tm. It also takes
> out of range values and wraps them around, simplifying cal-
> culations
>
> Tmfmtinstall installs a time format specifier %T. The time
> format behaves as in tmfmt
>
> Examples
> All examples assume tmfmtinstall has been called.
>
> Get the current date in the local timezone, GMT, and
> US_Pacific time. Print it using the default format.
>
> Tm t;
> print("local: %T0, tmnow(&t, "local"));
> print"gmt: %T0, tmnow(&t, "GMT"));
> print("eastern: %T0, tmnow(&t, "US_Pacific"));
>
> Compare if two times are the same, regardless of timezone.
>
> Tm a, b;
>
> tmparse(&a, nil, "Tue Dec 10 12:36:00 PST 2019");
> tmparse(&b, nil, "Tue Dec 10 15:36:00 EST 2019");
> if(a.abs == b.abs)
> print("same0);
> else
> print("different0);
>
> Add a day to two times. Because we picked daylight savings
> time to adjust over, only 23 hours are added.
>
> Tm t;
> tmparse(&t, nil, "Sun Nov 2 13:11:11 PST 2019");
> tm.day++;
> tmrecalc(&t);
> print("%T", &t); /* Mon Nov 3 13:11:11 PST 2019 */
next prev parent reply other threads:[~2020-04-08 6:48 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-08 3:56 ori
2020-04-08 6:48 ` Steve Simon [this message]
2020-04-09 14:12 ` [9front] " ori
2020-04-12 6:20 ` ori
2020-04-12 18:27 ` magma698hfsp273p9f
2020-04-13 0:36 ` [9front] " ori
2020-04-16 20:40 ` ori
2020-05-04 4:08 ` ori
2020-05-05 17:29 ` magma698hfsp273p9f
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=43B494B5-78E6-4967-ACE5-289ADD02CD2F@quintile.net \
--to=steve@quintile.net \
--cc=9front@9front.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).