Forum: Ruby-core DateTime.strptime() doesn't work correctly for '%s %z'

B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 unknown (Guest)
on 2014-05-03 13:34
(Received via mailing list)
Issue #9794 has been updated by Akira Tanaka.


tadayoshi funaba wrote:
>
> 見慣れないという意味ではないです。ユリウス日のようなものも日付だと思ってますし、%s 単体では特に問題に思っていません。
>
> 全然理解できないのですが、%s に時差って意味ないですよね。

%s に UTC からの時差の情報が入っていないことに同意します。

しかし、Time オブジェクトを作るには時差 (あるいは地方時、UTC) を選ばないといけないので、
%z の情報を使ってもいいと思います。

> 田中さんはそこにオブジェクトを見てるから不自然とは感じないという事ですかね。

「そこにオブジェクトを見てる」というのがどのような意味なのかわかりません。

> > もしそうだとすると、私はそのようには考えていません。
> > %s と %z が示す情報は独立なものだと考えています。
> >
> > 上の繰り返しになってしまうのですが、以下のように考えています。
> > * %s は過去から未来への流れの中の 1点を指定する
> > * %z はその 1点の表現方法を指定する
>
> やっぱりおかしいですね。%s の表現方法は繰り返しですが %s です。

もし、Time が、地方時、UTC、固定時差以外の表現方法として
1970-01-01T00:00:00Z からの秒数を数値としてサポートしているなら、
それを選ぶのが望ましいのかもしれません。

「%s の表現方法は繰り返しですが %s です。」というのはそのような意味でしょうか?

現在のところ、Time はそのような表現方法をサポートしておらず、
地方時、UTC、固定時差のいずれかを選ばなければならないため、
入力に時差が与えられているのなら固定時差を選ぶのはあり得る選択肢だと思っています。

> 日付じゃなくて、オブジェクトの操作ですよね。

日付というのが私の言う時刻と違うのかどうか確信が持てません。
また、ふなばさんがいうオブジェクトというものが何を指しているのか分かりません。

> > > 逆にこれを導入しなければならない強い動機が俺にはわかりません。
> >
> > git で使われているからという動機は述べられているんじゃないでしょうか。
>
> git に従う理由がありません。しかも ruby でそれが表現できないわけでも
> 解析できないわけでもありません。

もちろん従わなければならないわけではありません。
私はそれが提案者の動機だと思った、ということです。

ふなばさんはそれが提案者の動機だとは考えられないのでしょうか。

> Time.strptime('0 -0200', '%s %z')
> #=> 1969-12-31 22:00:00 -0200
> Time.strptime('20010203 -0200', '%Y%m%d %z')
> #=> 2001-02-03 11:00:00 +0900
>
> 明らかに統一性がないと思います。
> 以前は %s も含めて時差はすべて無視されていました。
> これは Time の元からの仕様なので気にしていませんでしが、
> 今はおかしな事になっていると思います。

なるほど。
Time が固定時差をサポートする以前は無視されていたというのはそのとおりです。
サポートした後でも、 まだ固定時差を選ぶほうがいい場合でもそうなっていないことがあるというのもそのとおりだと思います。

というわけで Time.strptime('20010203 -0200', '%Y%m%d %z') の場合でもそうするようにしてみました。



----------------------------------------
Bug #9794: DateTime.strptime() doesn't work correctly for '%s %z'
https://bugs.ruby-lang.org/issues/9794#change-46480

* Author: Felipe Contreras
* Status: Rejected
* Priority: Low
* Assignee: tadayoshi funaba
* Category: ext
* Target version:
* ruby -v: 2.1.1p76
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN
----------------------------------------
Time.strptime() works correctly:

    Time.strptime('0 +0100', '%s %z').strftime('%s %z')
    => "0 +0100"

But DateTime.strptime() doesn't:

    DateTime.strptime('0 +0100', '%s %z').strftime('%s %z')
    => "0 +0000"

In Rubinious it does work correctly:

    DateTime.strptime('0 +0100', '%s %z').strftime('%s %z')
    => "0 +0100"

This make the RubySL date space fail:

    DateTime#strptime parses seconds and timezone correctly FAILED
    Expected "1970-01-01T00:00:00+00:00"
     to equal "1970-01-01T01:00:00+01:00"

In addition, both C and perl preserver the offset correctly when doing
'%s %z'.

So it's very clear DateTime.strptime() has to be fixed.

Patch attached.

---Files--------------------------------
0001-datetime-fix-strptime-s-z.patch (1.94 KB)
This topic is locked and can not be replied to.