残念ながら(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](http://rurema.clear-code.com/1.9.3/method/Date/s/strptime.html)
フォーマットはUNIXの`strptime`に依存するので、そこを確認します。
>#STRPTIME
##名前
strptime - 文字列であらわされている時間を tm 構造体の時間に変換する
##説明
strptime() 関数は strftime(3) の逆関数である。
>個々のフィールドディスクリプターは **% とそれに続く文字** からなり、 後者にフィールドディスクリプターを置き換える内容を指定する。 format 文字列中の **他の全ての文字には、入力文字列にマッチする文字がなければならない** 。 フォーマット文字列中にある **空白は例外であり、 入力文字列中の 0 個以上の空白とマッチする** 。 2 つのフィールドディスクリプターの間には、 空白・英字・数字がなければならない。
strptime() 関数は、入力文字列を左から右へ処理する。 入力された **3 つの要素 (空白・文字・フォーマット) は、順に処理される** 。 入力がフォーマット文字列とマッチできない場合、関数は停止する。 残りのフォーマット文字列と入力文字列は処理されない。
>(引用者註:強調部分は引用者による。フィールドディスクリプターは省略。)
[Man page of STRPTIME](http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/strptime.3.html)
フィールドディスクリプタは、例えば`%Y`, `%m`, `%d`というやつですね。他にもいろいろありますので、上記サイトまたは[Time#strftime](http://rurema.clear-code.com/1.9.3/method/Time/i/strftime.html) / [Date#strftime](http://rurema.clear-code.com/1.9.3/method/Date/i/strftime.html)をご確認ください。
##今回の例を確認
今回あげた例では、月と日が一桁の場合に空白が入っています。
空白がなく *"06月03日"* となっていれば
```ruby
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個以上の空白 とマッチしてくれています。