残念ながら(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個以上の空白 とマッチしてくれています。