Slide 1

Slide 1 text

© SmartHR, Inc. 「⽂字列→⽇付」の落とし⽳ 〜Ruby Date.parseの意外な挙動〜 YAPC::Fukuoka 2025 U29セッションスポンサーLT ⽥中 優輝 SmartHR プロダクトエンジニア 2025/11/14

Slide 2

Slide 2 text

⾃⼰紹介 ● tanayu(⽥中優輝) ● 株式会社SmartHR(2023/04〜) ○ 労務の基本機能を開発 ○ プロダクトエンジニアで主にバックエンドを担当 ● 福岡在住 ● YAPC初参加!

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

技術スタック ● Ruby on RailsやReactなど ○ Rubyの業務経験なしで⼊社されている⽅も2〜3割います ● Claude CodeなどAI開発⽀援ツールも利⽤可 ● 詳細はSmartHR エンジニア採⽤をご覧ください ○ https://hello-world.smarthr.co.jp 6

Slide 7

Slide 7 text

働き⽅ ● フルフレックス(コアタイムなし) ● エンジニアはフルリモートワーク可 ○ 出社⽇数の指定なし ● ワーケーションも可 ● ⼊社⽇に15⽇の有給付与 ● 勉強会やカンファレンス参加⽀援 7

Slide 8

Slide 8 text

積極採⽤中!! ● エンジニアはもちろん、QAやPM、その他業種も 積極採⽤中です! ● 新卒採⽤もやっており、積極採⽤中です! ● 少しでも興味を持たれたら、カジュアル⾯談も やっているのでお気軽にどうぞ! ● 愛する福岡から離れられないという⽅もぜひ! 8

Slide 9

Slide 9 text

SmartHRの増えてくアクキー ● このパーカーを着ている⼈が配っていますの で、ぜひ声をかけていただき、交流してくださ い! 9 メンバーが着ているパーカー 配っているアクキー

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

突然ですが皆さんは ⽂字列を⽇付として扱いたいとき ありませんか!?

Slide 12

Slide 12 text

⼤体こんなときに使いたい ● ユーザーが⼊⼒した内容をDBの⽇付型カラ ムに保存したい ● 1週間後の⽇付を取得したい ● 特定の⽇から何⽇経過しているのか算出し たい 12

Slide 13

Slide 13 text

Rubyだとメソッドが⽤意されている 13 出典:Date.parse (Ruby 3.4 リファレンスマニュアル ) Date.parse('2025-11-14') => #

Slide 14

Slide 14 text

parseは元号にも対応している ● 元号付きの⽇付を⼊⼒してもOK ● RubyのDate.parseはC⾔語で書かれている ○ RubyにはC ⾔語で書かれたネイティブコードを呼 び出す仕組みがある 14 Date.parse('R7.11.14') => #

Slide 15

Slide 15 text

とある⽇謎の挙動を観測 ● 開発の検証中に「平成30年6⽉1⽇」と⼊⼒ するとParseの結果が「2025-11-30」にな る事象に遭遇した ● この謎の挙動を究明すべくアマゾンの奥地 へ向かった 15

Slide 16

Slide 16 text

突然ですがクイズです! 正しく変換されるのはどれ!? 1. 2025年11⽉14⽇ 2. 令和7年11⽉14⽇ 16

Slide 17

Slide 17 text

正解は〜 全部想定外の⽇付でした! 1. 2025年11⽉14⽇ →invalid dateエラー 2. 令和7年11⽉14⽇ →2025-11-11 ⼀体何が起きている!? 17

Slide 18

Slide 18 text

実装を眺めてみた 18 C⾔語で書かれた処理を眺めました。内部実装⾒るの楽しい! 出典:date_parse.c

Slide 19

Slide 19 text

内部ではこんなことが起きていた ● ハイフン区切りやスラッシュ区切りなどに該当しなかった場 合の処理が⾏われていた ○ Date.parse(ʻ12’)などのときに動作する処理 ● ⽂字列中の「2桁以上14桁以下の連続した数字」で⼀番⼤き い値を抽出 ● 抽出された数字の桁数で分類 ○ 2桁は⽇、3桁は年間通算⽇(1/1から数えて何⽇⽬)、4桁は⽉⽇など ● ⾜りない桁数は現在の年⽉⽇で補われる 19

Slide 20

Slide 20 text

つまり先程のクイズだと… 1. 2025年11⽉14⽇ →2025が抽出され、20⽉25⽇と判断しエラー 2. 令和7年11⽉14⽇ →14が抽出され、14⽇と判断し2025-11-14 20

Slide 21

Slide 21 text

Date.parseはバリデータではない ● Date.parseはバリデーションの役割を担っているわけではな い ○ ドキュメントにも「This method **does not** function as a validator.」と書かれていた ■ https://ruby-doc.org/stdlib-3.0.0/libdoc/date/rdoc/Date.html#method-c-_par se ● 検証していた実装は変換できない場合のみエラーにする実装 になっており、パースで検知する仕組みになっていた ○ バリデーションとパースの責務は分離する 21

Slide 22

Slide 22 text

まとめ

Slide 23

Slide 23 text

● ⼊⼒された値をバリデーションもせずに変 換処理を実⾏しない ● 変換処理に限らず、どんな処理でも値を渡 す際は処理側が期待している値かチェック が必要 ● 標準で⽤意されているメソッドの内部を追 うのは楽しい 23

Slide 24

Slide 24 text

おわり

Slide 25

Slide 25 text

【再び】積極採⽤中!! ● エンジニアはもちろん、QAやPM、その他業種も 積極採⽤中です! ● 新卒採⽤もやっており、積極採⽤中です! ● 少しでも興味を持たれたら、カジュアル⾯談も やっているのでお気軽にどうぞ! ● 愛する福岡から離れられないという⽅もぜひ! 25