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
84
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
Rails の CLI ツールの書き方/writing-rails-cli-tool
sanfrecce_osaka
0
26
外部APIが絡むテストをちょっといい感じに書く/a-little-nice-writing-external-api-testing
sanfrecce_osaka
0
14
gem_rbs_collection へのコントリビュートから始める Ruby の型の世界/contributing-gem-rbs-collection
sanfrecce_osaka
0
480
Rails と人魚の話/rails-and-mermaid
sanfrecce_osaka
0
420
パターンマッチ使ってるかい?(kyobashi.rb)/use-ruby-s-pattern-matching-on-kyobashi-rb
sanfrecce_osaka
0
210
ApplicationController の継承を分割してエラーを減らした話/dividing-application-controller
sanfrecce_osaka
1
350
Input object ではじめる入力値検証/input-value-validation-using-input-object
sanfrecce_osaka
0
540
実例で学ぶRailsアプリケーションデバッグ入門 〜ログインできちゃってました編〜/rails-application-debug-introduction
sanfrecce_osaka
2
850
String#split何もわかっていなかった/didn_t_know_anything_about_string_split
sanfrecce_osaka
0
180
Other Decks in Technology
See All in Technology
LINEスキマニ/LINEバイトにおけるバックエンド開発
lycorptech_jp
PRO
0
320
生成AI時代に若手エンジニアが最初に覚えるべき内容と、その学習法
starfish719
2
510
AI駆動開発を実現するためのアーキテクチャと取り組み
baseballyama
3
1.4k
Moto: Latent Motion Token as the Bridging Language for Learning Robot Manipulation from Videos
peisuke
0
150
第65回コンピュータビジョン勉強会
tsukamotokenji
0
150
Progressive Deliveryで支える!スケールする衛星コンステレーションの地上システム運用 / Ground Station Operation for Scalable Satellite Constellation by Progressive Delivery
iselegant
1
200
現地速報!Microsoft Ignite 2025 M365 Copilotアップデートレポート
kasada
1
1.4k
LINEギフト・LINEコマース領域の開発
lycorptech_jp
PRO
0
330
[CV勉強会@関東 ICCV2025] WoTE: End-to-End Driving with Online Trajectory Evaluation via BEV World Model
shinkyoto
0
280
重厚長大企業で、顧客価値をスケールさせるためのプロダクトづくりとプロダクト開発チームづくりの裏側 / Developers X Summit 2025
mongolyy
0
160
QAを"自動化する"ことの本質
kshino
1
140
不確実性に備える ABEMA の信頼性設計とオブザーバビリティ基盤
nagapad
1
730
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
What's in a price? How to price your products and services
michaelherold
246
12k
Thoughts on Productivity
jonyablonski
73
4.9k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Balancing Empowerment & Direction
lara
5
750
Producing Creativity
orderedlist
PRO
348
40k
Navigating Team Friction
lara
190
15k
Docker and Python
trallard
46
3.7k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
Scaling GitHub
holman
463
140k
Practical Orchestrator
shlominoach
190
11k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
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