Features Download
From: Felipe Contreras <felipe.contreras <at> gmail.com>
Subject: Re: Who the f*heck is Tadayoshi Funaba and why can he reject sensible patches unilaterally?
Newsgroups: gmane.comp.lang.ruby.general
Date: Saturday 3rd May 2014 03:33:21 UTC (over 4 years ago)
On Fri, May 2, 2014 at 7:50 PM, Yukihiro Matsumoto  wrote:

> Even though I can imagine your frustration (we had similar troubles
> before among Japanese programmers), Tadayoshi is one of the best
> programmers who knows about time and calendars, which are
> unfortunately very difficult for various reasons.

That might be the case, but his expertise in time and calendars give
him the right to reject fixes that everybody else (except him) have
agreed are correct?

> This is very unfortunate miscommunication across language barrier.

I hope it is just that.

> As far as I understand, strptime with %s and %z combined is undefined.
> because struct tm does not have timezone info.  In the language
> specification, "undefined" means you cannot expect anything, including
> rejection as Tadayoshi did for DateTime.

Yes, that is correct, you can consider "%s %z" as undefined in POSIX,
however by that rationale "%z" is undefined too[1], even "%s". Both
"%s" and "%z" are GNU extensions for strptime()[2].

POSIX does define "%z" for strftime()[3], but not "%s", that comes
from the Olson timezone package.

So, if both "%s" "%z" are "undefined" should Ruby ignore them? No, if
they have an understood meaning outside of POSIX, mainly GNU libc, it
makes sense for Ruby to support them, specially when it doesn't cause
any conflict to do that, and they are useful.

So how about "%s %z"? Well, it does work correctly in GNU libc (see
program below), so if we follow GNU libc for "%s", and for "%z", why
not for "%s %z"?

> %s means 'time_t value from the epoch'.  The epoch is fixed time point
> (1979-01-01 00:00 UTC).  Offsetting it according to %z seems nonsense,
> or plain wrong.  That's the reason behid his rejection.  If you were
> lucky to read Japanese, you'd have understood it.

Actually, the epoch is "1970-01-01 00:00 UTC" (not 1979), but that
doesn't mean the epoch cannot be represented in different timezones.

For example:

  d1 = DateTime.parse("1970-01-01 00:00 UTC")
  d2 = DateTime.parse("1970-01-01 01:00 +0100")
  d1 == d2
  => true

They are the same: the epoch. That means at 01:00 in Amsterdam, it was
00:00 in London: same date-time.

By saying UTC they don't mean "%s" can only be represented in UTC,
they mean when London had the time "1970-01-01 00:00", not Amsterdam.
I was confused about this at first too.

And then even if what you say is true that "%s" should only be UTC,
then why do we have this?

  DateTime.parse("1970-01-01 01:00 +0100").strftime("%s %z")
  => "0 +0100"

If strptime('0 +0100', '%s %z') should assume it's UTC, then so should
strftime("%s %z").

> Besides that, you didn't explain why you need to change the behavior.
> Why do you want to do `strptime("%s %z")` at the first hand?

I think I did: that's the format Git uses to store dates on every

> At least at the time of #7445, he didn't reject the future
> possibility, but he needs rational reason to change the undefined (and
> conforming) behavior to the other undefined behavior.  By 'reason', I
> don't mean the specific implementation behavor, nor wrong behavior.

How many more reasons do you need?

1) GNU libc supports this
2) Perl supports this
3) Rubinius supports this
4) Ruby MRI's Time supports this
5) Ruby MRI's DateTime.strftime() supports this
6) It's a widely used format used by all Git commits

I mean, seriously, what more do you need?

I have provided multiple reasons why this is desirable, but how about
*you* provide a *single* reason why "%s %z" should ignore the
time-zone. Can you do that?


  cat > test.c <<\EOF
  #define _XOPEN_SOURCE

  int main(int argc, char *argv[])
    struct tm tm;
    char buf[0x100];
    strptime(argv[1], "%s %z", &tm);
    strftime(buf, sizeof(buf), "%s %z", &tm);
    printf("%s\n", buf);
    return 0;

  gcc test.c -o test

  ./test "0 +0100"
  => 0 +0100

[1] http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html
[2] http://linux.die.net/man/3/strptime
[3] http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
[4] http://git-scm.com/book/en/Git-Internals-Git-Objects

Felipe Contreras
CD: 3ms