Help us understand the problem. What is going on with this article?

日本語表記の日時をTimeオブジェクトに変換(Time.strptimeメソッド)

More than 5 years have passed since last update.

残念ながら(require 'time'してから)Time.parseしても日本語表記の日時は理解してくれません。西洋圏の表記はかなり理解してくれるんですけどねぇ。
のでTime.strptimeを使います。
なお、DateTime.strptimeおよびDate.strptimeでも使用するフォーマットは全く同じです。

Time.strptime("2014年 6月 3日 19:20", "%Y年 %m月 %d日 %H:%M")
=> 2014-06-03 19:20:00 +0900
Time.strptime("2014年 6月23日 19:20","%Y年 %m月 %d日 %H:%M")
=> 2014-06-23 19:20:00 +0900

パースしたい文字列とフォーマット文字列を引数に与えるとTimeオブジェクトに変換してくれます。
さて。ここでは" 6月 3日"という空白付き月日表記が問題になります。詳しくは下で解説します。

解説

るりまなど確認

るりまではstrptimeの基本がDate.strptimeなので、これを参照してみます。

singleton method Date.strptime

strptime(str = '-4712-01-01', format = '%F') -> Date

与えられた雛型で日付表現を解析し、 その情報に基づいて日付オブジェクトを生成します。
Date._strptime も参照してください。 また strptime(3)、および Date#strftime も参照してください。

[PARAM] str: 日付をあらわす文字列
[PARAM] format: 書式
singleton method Date.strptime

フォーマットはUNIXのstrptimeに依存するので、そこを確認します。

STRPTIME

名前

strptime - 文字列であらわされている時間を tm 構造体の時間に変換する

説明

strptime() 関数は strftime(3) の逆関数である。

個々のフィールドディスクリプターは % とそれに続く文字 からなり、 後者にフィールドディスクリプターを置き換える内容を指定する。 format 文字列中の 他の全ての文字には、入力文字列にマッチする文字がなければならない 。 フォーマット文字列中にある 空白は例外であり、 入力文字列中の 0 個以上の空白とマッチする 。 2 つのフィールドディスクリプターの間には、 空白・英字・数字がなければならない。
strptime() 関数は、入力文字列を左から右へ処理する。 入力された 3 つの要素 (空白・文字・フォーマット) は、順に処理される 。 入力がフォーマット文字列とマッチできない場合、関数は停止する。 残りのフォーマット文字列と入力文字列は処理されない。

(引用者註:強調部分は引用者による。フィールドディスクリプターは省略。)
Man page of STRPTIME

フィールドディスクリプタは、例えば%Y, %m, %dというやつですね。他にもいろいろありますので、上記サイトまたはTime#strftime / Date#strftimeをご確認ください。

今回の例を確認

今回あげた例では、月と日が一桁の場合に空白が入っています。
空白がなく "06月03日" となっていれば

Time.strptime("2014年06月03日 19:20","%Y年%m月%d日 %H:%M")
=> 2014-06-03 19:20:00 +0900

となるので悩まなかったのですが、 " 6月 3日" なんです。
空白付き月日の文字列を対象に同じフォーマットで実行すると

Time.strptime("2014年 6月 3日 19:20","%Y年%m月%d日 %H:%M")
ArgumentError: invalid strptime format - `%Y年%m月%d日 %H:%M'

とエラーを返します。
ここで、引用した

フォーマット文字列中にある空白は例外であり、 入力文字列中の 0 個以上の空白とマッチする。

というのが効いてきます。
つまり正規表現的に表現すると、空白__*に相当します。(空白の代わりにアンダースコアを使いました)。
なので"2014年 6月 3日"にマッチするフォーマットは、最初の例で書いたように"%Y年 %m月 %d日"になります。

分の部分にも空白が入ると

分の部分も空白入りで表記している場合には、フォーマットの分の部分に空白を使えば大丈夫です。

Time.strptime("2014年 6月 3日  7: 5","%Y年 %m月 %d日 %H: %M")
=> 2014-06-03 07:05:00 +0900

見た目が奇妙だから、これはまずないでしょうけどね^^。
ちなみに、文字列" 7: 5"の直前にも空白が入って("
_7:_5")空白が2つ連なっているのですが、もともとのフォーマットで%H直前に空白が入っているので、 0個以上の空白 とマッチしてくれています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした