0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Ruby】コードから学ぶTime.strptime

Posted at

はじめに

こんにちは!アメリカの大学で語学を学びながら、独学でソフトウェアエンジニアを目指している者です。

今回は、RubyのTime.strptimeを使った日付処理で期待通りに動作しなかったケースを取り上げ、その原因と解決方法を詳しく解説します。

問題のコード

以下のコードを実行すると、意図しない結果になりました。Time.strptimeを学ぶためにある教材に書いてあったコードです

p Time.strptime("令和6年12月5日", "令和%Y年%m月%d日") do |y|
  y + 2018 # 元号を西暦に変換(2018を加算)
end

出力結果

0006-12-05 00:00:00 -0700

期待する動作

"令和6年12月5日" を 2024-12-05 に変換し、Time.strptime の結果として以下のように出力されることを期待していました。

2024-12-05 00:00:00 -0700 #=> 期待していた結果
0006-12-05 00:00:00 -0700 #=> 実際の結果

原因の解明

問題の本質は、以下の2つのポイントにあります:

 p がブロックの処理を待たずに出力している

私自身も「ブロックで値を変換しているのだから、それが反映されるだろう」と思っていました。しかし、pTime.strptime の結果を出力しますが、渡されたブロックの処理が反映される前に出力が行われてしまうことが原因でした。

処理の流れ

  • Time.strptime は文字列を解析し、指定したフォーマットに基づいて Time オブジェクトを生成します。
  • ブロックが渡されている場合、フォーマットで指定された値(例:%Y の「6」)をブロックに渡して変換を行います。
  • ただし、p はメソッドの最初の戻り値を受け取り、ブロック処理の結果を反映しないまま出力することがあります。

その結果、期待していた「2024」ではなく「6」がそのまま使われ、「0006年12月5日」と解釈されてしまいます。

修正方法

Time.strptime の結果を変数に格納する

p がブロックの処理結果を反映できるように、Time.strptime の結果を変数に格納し、その後で出力します。

修正版:

t = Time.strptime("令和6年12月5日", "令和%Y年%m月%d日") do |y|
  y + 2018 # 元号を西暦に変換
end
p t

Time.strptime の仕組み

  • フォーマット指定子(例:%Y, %m, %d)に基づいて値を解析。
  • ブロックが渡されている場合、対応する値をブロックに渡して処理。
  • ブロックの結果が Time.strptime の処理結果に反映される。

まとめ

問題の原因

  • p がブロックの処理を待たずに、Time.strptime の初期状態(ブロック未処理)の結果を出力してしまったこと。

解決方法

  1. Time.strptime の結果を変数に格納してから出力する。
  2. ブロックがどのように値を受け取り、処理しているかを確認する。

Ruby の柔軟なメソッドである Time.strptime を正しく理解することで、日付や時間の処理をより効率的に行えるようになります。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?