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

31e9336577dcba34f9ea8025a763c900?d=identicon&s=25 unknown (Guest)
on 2014-05-03 11:06
(Received via mailing list)
Issue #9794 has been updated by tadayoshi funaba.


Akira Tanaka wrote:
> tadayoshi funaba wrote:
> > 言語の問題もあるんだろうけど、俺が英語に堪能でも Felipe Contreras に俺の考えを解らせるのは無理じゃないかという気がする。
>
> 私も "%s %z" がなんでそんなにいけないのか理解していません。

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

> Ruby の strptime は struct tm じゃなくて DateTime や Time のオブジェクトを生成し、
> DateTime や Time のオブジェクトは自分がどんなモノなのかを自分自身で把握しているため、
> "%s %z" についてはこのへんの問題は避けられるように思っています。

主張の根拠になっているのがバグだから直せだからです。
ruby 側の都合の話ではありません。

> %s と %z に対応する値を s と z として、
> Time.at(s).getlocal(z) とするのがそれほどおかしいことだとは思っていません。

このあたりは誰かが言うと思っていました。
結局、'%s %z' は日付ではなくて、日付オブジェクトだと思えば、
ちょっと納得しそうになるものなんだと思います。
それと対称性を示せば、かなり多くの人を説得できるのかもしれません。

でも俺からすると日付としてやっぱりおかしいと思います。
オブジェクトの操作ではなくあくまで日付だと思うので。
逆にこれを導入しなければならない強い動機が俺にはわかりません。

> %s が存在しない実装、ということについては、どういう意味かわかりません。
> 今の Ruby 本体は C の strptime() も strftime() も使っていません。
> 勘違いしていなければ、ext/date も使っていないように思います。
> そのため環境に依存する部分はないように思います。

%s が存在しないというのは ruby の事ではなくて、他の処理系の事です。
'%s %z' が使えて当たり前というのが彼の考えのようですから。


> ふなばさんはわかっているような気もするのですが、lib/time.rb の strptime と私との関係について、
> 知らない人も多いような気がするのでいちおう書いておきますと、
> lib/time.rb に strptime を足したのはまつもとさんです。
> その時点で意見や判断を求められたことはなく、関わっていません。

誤解されているようですが、別に lib/time.rb が使うのがダメという事ではありません。
使ってる事に文句を言ってのではなく、単に第一義的にはユーザーが使うものとして用意したという事です。
俺としてはまさにこういう時の為に _strptime はあると思っていますが。
まったく意図していなかった流れですが、まつもとさんが入れたのは言われて思い出しました。

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


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

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