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

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


tadayoshi funaba wrote:

> 日付としておかしいからです。

おかしい、というのはどういう意味でしょう?

たしかに "%s %z" は人間が日常的に扱う形式ではありません。
でも、%s が過去から未来への流れの中の 1点を指定し、
%z がその 1点の表現方法を UTC からの offset という形でを指定する、
という時刻の形式だと解釈できると思います。

時刻の表現として、(閏秒の話を除いて) とくに問題があるとは思えません。

それとも日付という言葉に私が感じる以上の意味があるのでしょうか。
日付というと私は時分秒が入っていないように感じられて、
Time や DateTime とは違う感じがするのですが、日付という言葉を選んだことに何か深い意味があるのでしょうか。

> > %s と %z に対応する値を s と z として、
> > Time.at(s).getlocal(z) とするのがそれほどおかしいことだとは思っていません。
>
> このあたりは誰かが言うと思っていました。
> 結局、'%s %z' は日付ではなくて、日付オブジェクトだと思えば、
> ちょっと納得しそうになるものなんだと思います。
> それと対称性を示せば、かなり多くの人を説得できるのかもしれません。
>
> でも俺からすると日付としてやっぱりおかしいと思います。
> オブジェクトの操作ではなくあくまで日付だと思うので。

ここでいう日付と日付オブジェクトの違いがよくわからないのですが、
もしかすると、"%s %z" をオブジェクトを生成・改変する操作の列とみなすという意味でしょうか。

もしそうだとすると、私はそのようには考えていません。
%s と %z が示す情報は独立なものだと考えています。

上の繰り返しになってしまうのですが、以下のように考えています。
* %s は過去から未来への流れの中の 1点を指定する
* %z はその 1点の表現方法を指定する

%s と %z は独立なので、矛盾なく組み合わせることが可能です。

もちろん、Time オブジェクトを生成するには表現方法を決めないといけないので、
Time.at は地方時を選択し、getlocal はそれを z で指定された方法に変えるわけですが、
それは Time.at が表現方法を指定する引数を持っていないからという以上の意味はありません。

> 逆にこれを導入しなければならない強い動機が俺にはわかりません。

git で使われているからという動機は述べられているんじゃないでしょうか。

> 逆に俺からすると、Time.strptime が互換性、統一性を捨てたのがかなり疑問です。
> 俺は元に戻す事を提案しておきます。

ここでいう互換性、統一性とはなんでしょう?
また、元というのはどの段階でしょう?


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

* 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.