Share
Embed
Transcript
36 slides
-
ࣗݾհ • ໊લ: ᖒҪ એ ʢ͞Θ͍ ͷͿͻ͜ʣ • twitter/github: nobuhikosawai
• ΤϯδχΞྺ: 2 • αʔόʔαΠυ(Rails) • ϑϩϯτΤϯυ(React.js) -
ࣗݾհ • ೖࣾͨ͠࠷ॳͷϓϩ δΣΫτͰ͍͖ͳΓ ଟݴޠԽΛߦ͏ => ϒϩάॻ͍ͨ => ͪΐͬͱόζͬͨ
https://goo.gl/AgGNoL -
ࣗݾհ • ϥΠϒϥϦ(globalize)ͷ όάΛݟ͚ͭͯOSSʹ ߩݙ • ࣾOSS׆ಈͷҰ؏Ͱ ग़ͨ͠ͷɻ ৄࡉͪ͜Βͷൃදʹ ৄ͍͠Ͱ͢ɻˣ
https://www.slideshare.net/ ota42y/fincoss ଟݴޠԽΤϯδχΞ -
λΠϜκʔϯͱ • ඪ४࣌: ͋Δࠃ͍Ҭ͕ڞ௨Ͱ͏࣌ؒʢຊɺΞϝϦΧͷभʣ • λΠϜκʔϯ: ಉ͡ඪ४࣌Λ͏ҬΛλΠϜκʔϯͱ͍͏ • UTC: ڠఆੈք࣌ɻඪ४࣌Ͱ༻͍Δ࣌ࠁɺUTC͔ΒͷࠩͰදݱ͢Δ
• Φϑηοτ: ͜ͷࠩͷ͜ͱΛoffsetʢ࣌ࠩʣͱݺͿ͜ͱ͕͋Δɻ https://ja.wikipedia.org/wiki/%E6%A8%99%E6%BA%96%E6%99%82 https://ja.wikipedia.org/wiki/%E6%99%82%E9%96%93%E5%B8%AF_(%E6%A8%99%E6%BA%96%E6%99%82) -
RailsͰλΠϜκʔϯΛऔΓѻ͏ํ๏ • ActiveSupport::TimeWithZoneΛ͏ͷ͕Ұൠతɻ ࣌ɺλΠϜκʔϯΛѻ͑ΔRailsಠࣗΫϥεɻ Time.zone.local(2018, 8, 1) # => Wed,
01 Aug 2018 00:00:00 JST +09:00 • config/application.rbҎԼͷઃఆΛࢀর config.time_zone = ‘Asia/Tokyo' RubyͱRailsʹ͓͚ΔTime, Date, DateTime, TimeWithZoneͷҧ͍ - Qiita -
RailsͰλΠϜκʔϯΛऔΓѻ͏ํ๏ • TimezoneͷऔΓѻ͍ActiveSupport::TimeZoneΫϥε͕ ߦ͍ͬͯΔɻ Time.zone # => #<ActiveSupport::TimeZone:0x00007fb455f642b0 @name="Asia/ Tokyo",
@tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil> ActiveSupport::TimeZone.new('Asia/Tokyo') #্͜Εͱಉ͡ # => #<ActiveSupport::TimeZone:0x00007fb455f642b0 @name="Asia/ Tokyo", @tzinfo=#<TZInfo::DataTimezone: Asia/Tokyo>, @utc_offset=nil> #ଞͷTimezoneΛࢦఆ ActiveSupport::TimeZone.new(‘America/New_York'). local(2018, 1, 1) # => Mon, 01 Jan 2018 00:00:00 EST -05:00 -
RailsͰλΠϜκʔϯΛऔΓѻ͏ํ๏ • ActiveSupport::TimeZoneoffsetͷඵͰ newͰ͖Δ ActiveSupport::TimeZone.new(9 * 3600) # Asia/Tokyo #
=> #<ActiveSupport::TimeZone:0x00007fb454dbfb40 @name="Osaka", @tzinfo=#<TZInfo::DataTimezone: Asia/ Tokyo>, @utc_offset=nil> -
λΠϜκʔϯͱ • αϚʔλΠϜ • Ն࣌ؒɺDST (daylight saving time) • Ң͕ߴ͘Նͷর͕͍࣌ؒҬͰɺ໌Δ͍࣌ؒΛ༗ޮ׆༻͢
ΔͨΊʹಋೖ͞ΕΔ • य़ʹ1࣌ؒ͢͢Ίͯɺळʹ1࣌ؒ͢ɻ • railsͰ.dst?ͱ͍͏αϚʔλΠϜఆͷϝιου͕͋Δ • ಉ͡ࠃͰҬʹΑͬͯ͋ͬͨΓͳ͔ͬͨΓ͢Δ -
͕͜͜มͩΑRailsͷλΠϜκʔϯ • UTC -7 • America/DenverαϚʔλΠϜ͋Δ • America/Phoenix (Arizonaʣ αϚʔλΠϜ͕ͳ͍
• RailsͰtz = ActiveSupport::TimeZone.new(-7 * 3600) ͢ΔͱͲ͏ͳΔ ͔ʁ • tz.local(2018, 8, 1).dst? => true/false ͲͪΒͰ͠ΐ͏͔ʁ ΫΠζ1 -
͕͜͜มͩΑRailsͷλΠϜκʔϯ • UTC -6 • America/ChicagoͳͲ͕͋Δ • શͯͷभͰαϚʔλΠϜ͕͋Δ • RailsͰ
tz = ActiveSupport::TimeZone.new(-6 * 3600) ͢ΔͱͲ͏ ͳΔ͔ʁ • tz.local(2018, 8, 1).dst? => true/false ͲͪΒͰ͠ΐ͏͔ʁ ΫΠζ2 -
͕͜͜มͩΑRailsͷλΠϜκʔϯ • UTC -6 • ਖ਼ղfalse • Central America (
‘America/Guatemara’) ͕ ώοτ͢ΔʢΞϝϦΧͷೆʹ͋Δผͷࠃʣ ΫΠζ2 -
͕͜͜มͩΑRailsͷλΠϜκʔϯ ΫΠζ2 tz = ActiveSupport::TimeZone.new(-6 * 3600) #=> #<ActiveSupport::TimeZone:0x00007fb454db53e8 @name="Central
America", @tzinfo=#<TZInfo::DataTimezone: America/ Guatemala>, @utc_offset=nil> tz.local(2018, 8, 1).dst? #=> false -
͕͜͜มͩΑRailsͷλΠϜκʔϯ tz = ActiveSupport::TimeZone.new(-5 * 3600) #-28800 #=> #<ActiveSupport::TimeZone:0x00007fb4572b3460 @name="Pacific
Time (US & Canada)", @tzinfo=#<TZInfo::DataTimezone: America/Los_Angeles>, @utc_offset=nil> tz.local(2018, 1, 1) #=> Mon, 01 Jan 2018 00:00:00 PST -08:00 tz.local(2018, 1, 1).utc_offset # => -28800 tz.local(2018, 8, 1) #=> Wed, 01 Aug 2018 00:00:00 PDT -07:00 tz.local(2018, 8, 1).utc_offset # => -25200 ʢ-28800Ͱnewͨ͠ͷʹʂʂʣ • উखʹoffset͕มΘͬͯͯࠔΔ -
͜ΕͰ͍͍ͷ͔RailsͷλΠϜκʔϯ • ࠲ΞϓϦΛ࡞ΔྫΛߟ͑Δ • rallsdm࠲͕ೆதͨ͠ΒpushΛૹΔ “ࠓrailsdmͰ͢ɻ” • rubykaigi࠲͕ೆதͨ͠ΒpushΛૹΔɻ”ࠓrubykaigiͰ͢ɻ” • αʔόʔͰόονॲཧͰpushΛ͓͘Δ
• αϚʔλΠϜΛߟྀ͢Δඞཁͳ͍ • offset͚ͩΘ͔ͬͯΕ͍͍ => offsetͰnew͍ͨ͠ʂ -
͜ΕͰ͍͍ͷ͔RailsͷλΠϜκʔϯ • JavaʹSwiftʹTimeZoneࣈͰݻఆ͢Δػೳ͕͋Δ • Swift • secondsFromGMT • Java •
ZonedDateTime • OffsetDateTime -
͜ΕͰ͍͍ͷ͔RailsͷλΠϜκʔϯ • RailsͰৗʹ࣮TimeZone͕औΓѻΘΕΔΑ͏ʹͳ͍ͬͯΔ • ෦ͰTimezoneͷhashΛ͍࣋ͬͯΔ class TimeZone # Keys are
Rails TimeZone names, values are TZInfo identifiers. MAPPING = { "International Date Line West" => "Etc/GMT+12", "Midway Island" => "Pacific/Midway", "American Samoa" => "Pacific/Pago_Pago", "Hawaii" => "Pacific/Honolulu", "Alaska" => "America/Juneau", "Pacific Time (US & Canada)" => "America/Los_Angeles", "Tijuana" => "America/Tijuana", -
͜ΕͰ͍͍ͷ͔RailsͷλΠϜκʔϯ hashΛϧʔϓͰճͯ͠ɺΘ͟Θ͟StringͰNumericͰnewͰ͖ΔΑ͏ʹ͍ͯ͠Δ def [](arg) case arg when String begin @lazy_zones_map[arg]
||= create(arg) rescue TZInfo::InvalidTimezoneIdentifier nil end when Numeric, ActiveSupport::Duration # ←͜͜ arg *= 3600 if arg.abs <= 13 all.find { |z| z.utc_offset == arg.to_i } else raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}" end end https://github.com/rails/rails/blob/db8cce202b8e81154773e5195a3ae35e873427e6/ activesupport/lib/active_support/values/time_zone.rb#L229 -
VirtualTimeZoneRails • ࣈͰnewͨ͠ͱ͖࣮λΠϜκʔϯΛࢀর͠ͳ͍Α͏ʹ͢ ΔgemΛ࡞ͨ͠ https://github.com/nobuhikosawai/virtual_time_zone_rails tz = ActiveSupport::TimeZone.new(9 * 3600)
# => #<ActiveSupport::TimeZone:0x007ff3dab57e50 @name="secondsFromGMT#32400", @tzinfo=#<TZInfo::VirtualTimezone: secondsFromGMT#32400>, @utc_offset=nil> tz.local(2018, 8, 1) #=> Wed, 01 Aug 2018 00:00:00 VirtualTimeZone +09:00 -
VirtualTimeZoneRails gemͷ࡞Γํ • RailsʹPRૹΔͷͰ͔͍ͷͰmonkey patchΛͯΔ • ͬͨ͜ͱେ͖͘2ͭ • ActiveSupport::TimeZoneͷnewΛ্ॻ͖ •
newͨ͠ͱ͖ɺ࣮λΠϜκʔϯͰͳ͘ԾతͳλΠϜ κʔϯVirtualTimeZoneΛఆٛͯͦ͠ΕΛฦ͢Α͏ʹ͢Δ -
VirtualTimeZoneRails require 'tzinfo/virtual_timezone' require 'active_support/values/time_zone' ActiveSupport::TimeZone.class_eval do class << self
alias_method :square_brackets, :[] def [](arg) case arg when Numeric, ActiveSupport::Duration # ←্͚ͩ͜͜ॻ͖ tzinfo = TZInfo::VirtualTimezone.new(arg) @lazy_zones_map[arg] ||= create(tzinfo.name, nil, tzinfo) else square_brackets(arg) end end end end -
VirtualTimeZoneRails • TZInfo::TimezoneΛܧঝͨ͠TZInfo::VirtualTimezoneΛఆٛ ܧঝؔ - TZInfo::Timezone - InfoTimezone - DataTimezone
←λΠϜκʔϯ໊Ͱnew͢ΔͱฦΔͭ - LinkedTimezone - TimezoneProxy - VirtualTimezone ←ࠓճՃͨ͠Ϋϥε • TZInfo෦తʹTimezonePeriodɺTimezoneOffsetΫϥε Λ༻͍ͯ࣌ࠩΛදݱ͍ͯ͠ΔͷͰɺ͜ΕΒΛݻఆͯ͠ฦ͢Α͏ ʹมߋ -
VirtualTimeZoneRails module TZInfo class VirtualTimezone < Timezone def self.new(seconds_from_gmt) vt
= super() vt.send(:setup, seconds_from_gmt) vt end # Returns the TimezonePeriod based on the given seconds from GMT. def period_for_utc(_utc) TimezonePeriod.new(nil, nil, @offset) end ... private def setup(seconds_from_gmt) @seconds_from_gmt = seconds_from_gmt @offset = TimezoneOffset.new(@seconds_from_gmt, 0, :VirtualTimeZone) end end end