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
73
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
3
gem_rbs_collection へのコントリビュートから始める Ruby の型の世界/contributing-gem-rbs-collection
sanfrecce_osaka
0
390
Rails と人魚の話/rails-and-mermaid
sanfrecce_osaka
0
380
パターンマッチ使ってるかい?(kyobashi.rb)/use-ruby-s-pattern-matching-on-kyobashi-rb
sanfrecce_osaka
0
190
ApplicationController の継承を分割してエラーを減らした話/dividing-application-controller
sanfrecce_osaka
1
300
Input object ではじめる入力値検証/input-value-validation-using-input-object
sanfrecce_osaka
0
520
実例で学ぶRailsアプリケーションデバッグ入門 〜ログインできちゃってました編〜/rails-application-debug-introduction
sanfrecce_osaka
2
800
String#split何もわかっていなかった/didn_t_know_anything_about_string_split
sanfrecce_osaka
0
170
String#split何もわかっていなかった/didn-t-know-anything-about-string-split
sanfrecce_osaka
0
78
Other Decks in Technology
See All in Technology
Snowflake Summit 2025 データエンジニアリング関連新機能紹介 / Snowflake Summit 2025 What's New about Data Engineering
tiltmax3
0
310
20250625 Snowflake Summit 2025活用事例 レポート / Nowcast Snowflake Summit 2025 Case Study Report
kkuv
1
310
Liquid Glass革新とSwiftUI/UIKit進化
fumiyasac0921
0
230
Fabric + Databricks 2025.6 の最新情報ピックアップ
ryomaru0825
1
140
M3 Expressiveの思想に迫る
chnotchy
0
110
mrubyと micro-ROSが繋ぐロボットの世界
kishima
2
330
Agentic Workflowという選択肢を考える
tkikuchi1002
1
530
AWS Summit Japan 2025 Community Stage - App workflow automation by AWS Step Functions
matsuihidetoshi
1
280
第9回情シス転職ミートアップ_テックタッチ株式会社
forester3003
0
250
Кто отправит outbox? Валентин Удальцов, автор канала Пых
lamodatech
0
350
HiMoR: Monocular Deformable Gaussian Reconstruction with Hierarchical Motion Representation
spatial_ai_network
0
110
「Chatwork」の認証基盤の移行とログ活用によるプロダクト改善
kubell_hr
1
190
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
524
40k
BBQ
matthewcrist
89
9.7k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
31
1.2k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
A designer walks into a library…
pauljervisheath
207
24k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Done Done
chrislema
184
16k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
490
Unsuck your backbone
ammeep
671
58k
The Language of Interfaces
destraynor
158
25k
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