32
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-06-05

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

32
34
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?