Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Time.zone.parse('dark')/time-zone-parse-dark
Search
Masatoshi Moritsuka
May 15, 2025
Technology
0
77
Time.zone.parse('dark')/time-zone-parse-dark
Masatoshi Moritsuka
May 15, 2025
Tweet
Share
More Decks by Masatoshi Moritsuka
See All by Masatoshi Moritsuka
外部APIが絡むテストをちょっといい感じに書く/a-little-nice-writing-external-api-testing
sanfrecce_osaka
0
13
gem_rbs_collection へのコントリビュートから始める Ruby の型の世界/contributing-gem-rbs-collection
sanfrecce_osaka
0
420
Rails と人魚の話/rails-and-mermaid
sanfrecce_osaka
0
400
パターンマッチ使ってるかい?(kyobashi.rb)/use-ruby-s-pattern-matching-on-kyobashi-rb
sanfrecce_osaka
0
200
ApplicationController の継承を分割してエラーを減らした話/dividing-application-controller
sanfrecce_osaka
1
320
Input object ではじめる入力値検証/input-value-validation-using-input-object
sanfrecce_osaka
0
530
実例で学ぶRailsアプリケーションデバッグ入門 〜ログインできちゃってました編〜/rails-application-debug-introduction
sanfrecce_osaka
2
820
String#split何もわかっていなかった/didn_t_know_anything_about_string_split
sanfrecce_osaka
0
180
String#split何もわかっていなかった/didn-t-know-anything-about-string-split
sanfrecce_osaka
0
78
Other Decks in Technology
See All in Technology
Google Agentspaceを実際に導入した効果と今後の展望
mixi_engineers
PRO
3
350
Amazon Bedrock AgentCoreのフロントエンドを探す旅 (Next.js編)
kmiya84377
1
130
家族の思い出を形にする 〜 1秒動画の生成を支えるインフラアーキテクチャ
ojima_h
1
580
Nx × AI によるモノレポ活用 〜コードジェネレーター編〜
puku0x
0
400
Amazon Qで2Dゲームを作成してみた
siromi
0
120
Agent Development Kitで始める生成 AI エージェント実践開発
danishi
0
130
Intro to Software Startups: Spring 2025
arnabdotorg
0
200
Oracle Cloud Infrastructure:2025年7月度サービス・アップデート
oracle4engineer
PRO
1
130
Serverless Meetup #21
yoshidashingo
1
110
SRE新規立ち上げ! Hubbleインフラのこれまでと展望
katsuya0515
0
170
リリース2ヶ月で収益化した話
kent_code3
1
220
AIに目を奪われすぎて、周りの困っている人間が見えなくなっていませんか?
cap120
1
440
Featured
See All Featured
Unsuck your backbone
ammeep
671
58k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
21
1.4k
Producing Creativity
orderedlist
PRO
347
40k
Designing for humans not robots
tammielis
253
25k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3.1k
For a Future-Friendly Web
brad_frost
179
9.9k
Embracing the Ebb and Flow
colly
86
4.8k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
21k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Why Our Code Smells
bkeepers
PRO
337
57k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
44
2.4k
Transcript
Time.zone .parse(‘dark’) 森塚 真年(@sanfrecce_osaka) 2025/04/30 Kyobashi.rb#6 #kyobashirb
注: 言うほど闇では ないかもしれないです 良いタイトル思いつかなかった
自己紹介 森塚 真年 GitHub: @sanfrecce-osaka Twitter(X) ・Qiita: @sanfrecce_osaka 趣味: コミュニティ・勉強会
Machida.rb Hirakata.rb 株式会社Leaner Technologies Ruby3.4/Rails8.0 Next.js 14.2
本編
しばしば書きませんか? Time.zone.parse('2020-10-10T10:10:10+09:00')
ここで問題です
次の場合どうなるでしょう? 1. 例外(ArgumentError) 2. nil 3. 2020-10-10 10:10:10.000000000 JST +09:00
4. 2025-10-10 10:10:10.000000000 JST +09:00 5. 2025-04-30 00:00:00.000000000 JST +09:00 6. 該当なし # 年の最後が数字じゃなくてアルファベット Time.zone.parse('202O-10-10T10:10:10+09:00')
正解 Time.zone.parse('202O-10-10T10:10:10+09:00') # => 2025-04-30 10:10:10.000000000 JST +09:00
why?
コードを追ってみました
show_source 参考: https://onk.hatenablog.jp/entry/2022/10/10/003542 irb(main):001> $ Time.zone.parse From: /xxx/activesupport-8.0.2/lib /active_support/values/time_zone.rb:453 def
parse(str, now = now()) parts_to_time(Date._parse(str, false), now) end
Date._parse ドキュメント: 実装: https://docs.ruby-lang.org/ja/3.4/method/Date/s/_parse.html https://github.com/ruby/ruby/blob/v3_4_3/ext/date/date_core.c#L4481-L4498 irb(main):002> Date._parse('2020-10-10T10:10:10+09:00') # => {zone:
"+09:00", hour: 10, min: 10, sec: 10, # year: 2020, mon: 10, mday: 10, offset: 32400 } irb(main):003> Date._parse('202O-10-10T10:10:10+09:00') # => {zone: "+09:00", hour: 10, min: 10, sec: 10, # yday: 202, offset: 32400 }
ActiveSupport::TimeZone #parts_to_time https://github.com/rails/rails/blob/v8.0.2/activesupport/lib/active_support/values/time_zone.rb#L585-L608 irb(main):004> $ Time.zone.parts_to_time From: /xxx/activesupport-8.0.2/lib /active_support/values/time_zone.rb:585
def parts_to_time(parts, now) raise ArgumentError, "invalid date" if parts.nil? return
if parts.empty?
if parts[:seconds] time = Time.at(parts[:seconds]) else time = Time.new( parts.fetch(:year,
now.year), parts.fetch(:mon, now.month), parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day), parts.fetch(:hour, 0), parts.fetch(:min, 0), parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), parts.fetch(:offset, 0) ) end
if parts[:offset] || parts[:seconds] TimeWithZone.new(time.utc, self) else TimeWithZone.new(nil, self, time)
end end
その他の挙動 irb(main):005> Time.zone.parse('') # => nil irb(main):006> Time.zone.parse(nil) # =>
no implicit conversion of nil into String (TypeError) irb(main):007> Time.zone.parse('2020') # => argument out of range (ArgumentError) irb(main):008> Time.zone.parse('202O') # => 2025-04-30 00:00:00.000000000 JST +09:00 irb(main):009> Time.zone.parse('ほげ') # => nil irb(main):010> Time.zone.parse('ほげ-10') # => 2025-04-10 00:00:00.000000000 JST +09:00
難しい/(^o^) \
invalid な文字列は弾きたい
が rails のバリデータ ない(´ ・ω ・`) gem なさそう(´ ・ω ・`)
そこで
ActiveSupport::TimeZone #strptime irb(main):011> $ Time.zone.strptime From: /xxx/activesupport-8.0.2/lib /active_support/values/time_zone.rb:507 def strptime(str,
format, now = now()) parts_to_time(DateTime._strptime(str, format), now) end
DateTime._strptime ドキュメント: 実装: https://docs.ruby-lang.org/ja/3.4/method/DateTime/s/_strptime.html https://github.com/ruby/ruby/blob/v3_4_3/ext/date/date_core.c#L4327-L4374 irb(main):012* DateTime._strptime( irb(main):013* '2020-10-10T10:10:10+09:00', irb(main):014>
'%Y-%m-%dT%H:%M:%S') # => {year: 2020, mon: 10, mday: 10, # hour: 10, min: 10, sec: 10, # zone: "+09:00", offset: 32400 } irb(main):015* DateTime._strptime( irb(main):016* '202O-10-10T10:10:10+09:00', irb(main):017* '%Y-%m-%dT%H:%M:%S') # => nil
def parts_to_time(parts, now) raise ArgumentError, "invalid date" if parts.nil? return
if parts.empty?
irb(main):018* Time.zone.strptime( irb(main):019* '2020-10-10T10:10:10+09:00', irb(main):020> '%Y-%m-%dT%H:%M:%S') # => 2020-10-10 10:10:10.000000000
JST +09:00 irb(main):021* Time.zone.strptime( irb(main):022* '202O-10-10T10:10:10+09:00', irb(main):023> '%Y-%m-%dT%H:%M:%S') # => invalid date (ArgumentError)
グッ(๑•̀ ㅂ•́)و✧
皆さん どうしてますか?
もっといい方法あったら おしえてほすい (´ω `)
ご清聴 ありがとうございました。
None