dynamic_time_zone 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f8859c4b02e73021acd66c1ac986c8cca9912d7635c9e4ee132336490fe861e7
4
+ data.tar.gz: 91b40fa53158123ad1cd31f381c1d2a57d8b4a76609aec7f9f7285d0ced37c04
5
+ SHA512:
6
+ metadata.gz: ca8fcd52405e323f33eefe0f4d6210d68b37259e60ceacf1712cb1e2f6f8e40042913100e9d2f76578551404c97a3d8a8f384dd83673f22985524a44718b431e
7
+ data.tar.gz: e7a88247168258e5367dfa5e40d81f724faaf996a7c9101eabfc15fb6ea5e6f1a34c4b714374e4505788be40a8a628128e68874043d0187dc8035e2f86d1be60
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'active_support/core_ext/date_time/conversions'
5
+ require 'active_support/time_with_zone'
6
+ require 'active_support/core_ext/time/zones'
7
+ require 'active_support/core_ext/numeric/time'
8
+ require 'tzinfo'
9
+
10
+ module DynamicTimeZone
11
+ class << self
12
+ attr_accessor :enabled
13
+ end
14
+
15
+ REGEX_PATTERN = %r{DynamicTimeZone\/(\+|-)(\d+)}.freeze
16
+ end
17
+
18
+ DynamicTimeZone.enabled = false
19
+
20
+ require 'dynamic_time_zone/validator'
21
+ require 'dynamic_time_zone/identifier_builder'
22
+ require 'dynamic_time_zone/time_zone_data_source'
23
+ require 'dynamic_time_zone/localtime_patch'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicTimeZone
4
+ class IdentifierBuilder
5
+ def from_target_datetime(year:, month:, day:, hour:)
6
+ now = DateTime.now.new_offset
7
+ target = DateTime.new(year, month, day, hour, now.minute, now.second)
8
+ offset = target.to_i - now.to_i
9
+ 'DynamicTimeZone/' + (offset.negative? ? '' : '+') + offset.to_s
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LocaltimePatch
4
+ def localtime(utc_offset = nil)
5
+ return super unless DynamicTimeZone.enabled
6
+
7
+ utc + (utc_offset || 0).seconds
8
+ end
9
+ alias_method :getlocal, :localtime
10
+ end
11
+
12
+ ActiveSupport::TimeWithZone.prepend(LocaltimePatch)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicTimeZone
4
+ module TestHelper
5
+ def with_isolated_time_zone_and_dynamic_time_zone_setting
6
+ old_time_zone = Time.zone
7
+ old_enabled = DynamicTimeZone.enabled
8
+ old_data_source = TZInfo::DataSource.get
9
+
10
+ TZInfo::DataSource.set(DynamicTimeZone::TimeZoneDataSource.new)
11
+ DynamicTimeZone.enabled = true
12
+
13
+ yield
14
+ ensure
15
+ Time.zone = old_time_zone
16
+ DynamicTimeZone.enabled = old_enabled
17
+ TZInfo::DataSource.set(old_data_source)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicTimeZone
4
+ class TimeZoneDataSource < TZInfo::ZoneinfoDataSource
5
+ def load_timezone_info(identifier)
6
+ return super unless DynamicTimeZone.enabled
7
+
8
+ pattern_matches = identifier.scan(DynamicTimeZone::REGEX_PATTERN).last
9
+ return super if pattern_matches.nil?
10
+
11
+ sign, offset_amount = pattern_matches
12
+ offset_amount = offset_amount.to_i
13
+ offset_amount = 0 - offset_amount if sign == '-'
14
+
15
+ timezone_info = TZInfo::TransitionDataTimezoneInfo.new(identifier)
16
+ timezone_info.offset(identifier, offset_amount, 0, 'DynamicTimeZone')
17
+ timezone_info
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicTimeZone
4
+ class Validator
5
+ def valid?(identifier)
6
+ DynamicTimeZone.enabled && !identifier.scan(REGEX_PATTERN).last.nil?
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DynamicTimeZone
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dynamic_time_zone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Appfolio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tzinfo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5.2'
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '6.1'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '5.2'
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '6.1'
47
+ description:
48
+ email:
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/dynamic_time_zone.rb
54
+ - lib/dynamic_time_zone/identifier_builder.rb
55
+ - lib/dynamic_time_zone/localtime_patch.rb
56
+ - lib/dynamic_time_zone/test_helper.rb
57
+ - lib/dynamic_time_zone/time_zone_data_source.rb
58
+ - lib/dynamic_time_zone/validator.rb
59
+ - lib/dynamic_time_zone/version.rb
60
+ homepage:
61
+ licenses: []
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.0.8
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Dynamically set the offset from UTC from timezone identifier
82
+ test_files: []