time_zone_scheduler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +9 -0
- data/.yardopts +3 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +37 -0
- data/Rakefile +31 -0
- data/lib/time_zone_scheduler.rb +245 -0
- data/lib/time_zone_scheduler/version.rb +3 -0
- data/time_zone_scheduler.gemspec +25 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 47bbf93e0e186627215c28e7e4daaca94a368ec1
|
4
|
+
data.tar.gz: a436d640921114695ccbb20d19c8e0a3c3d0077a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb5d0a1560de701b440b75f9eb5dfbf3648fa1aab2e7fa7af7229af1f7cbaf98a8c2c99c672436afeaadf791c1d8108de87d1751e1cae4ba28c654d472f90fbc
|
7
|
+
data.tar.gz: 7b03973320b7f210d603c169cb6d27417b53469229c47c2a2010129051f47d3a273d62f50f8a5ce8c9efccee893956e4681ecca46f012fc092888f5e1b745b8f
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Artsy, Eloy Durán <eloy.de.enige@gmail.com>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# TimeZoneScheduler
|
2
|
+
|
3
|
+
[](https://travis-ci.org/alloy/time_zone_scheduler)
|
4
|
+
|
5
|
+
A Ruby library that assists in scheduling events whilst taking time zones into account. E.g. when to best deliver
|
6
|
+
notifications such as push notifications or emails.
|
7
|
+
|
8
|
+
NOTE: _It is not yet battle-tested. This will all follow over the next few weeks._
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'time_zone_scheduler'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install time_zone_scheduler
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
See [the documentation](http://www.rubydoc.info/gems/time_zone_scheduler).
|
29
|
+
|
30
|
+
## Contributing
|
31
|
+
|
32
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/alloy/time_zone_scheduler.
|
33
|
+
|
34
|
+
## License
|
35
|
+
|
36
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
37
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
desc "Install all dependencies"
|
2
|
+
task :bootstrap do
|
3
|
+
if system('which bundle')
|
4
|
+
sh "bundle install"
|
5
|
+
#sh "git submodule update --init"
|
6
|
+
else
|
7
|
+
$stderr.puts "\033[0;31m[!] Please install the bundler gem manually: $ [sudo] gem install bundler\e[0m"
|
8
|
+
exit 1
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'bundler/gem_tasks'
|
14
|
+
|
15
|
+
desc "Generate documentation"
|
16
|
+
task :doc do
|
17
|
+
sh "yard doc"
|
18
|
+
end
|
19
|
+
|
20
|
+
require "rake/testtask"
|
21
|
+
Rake::TestTask.new(:test) do |t|
|
22
|
+
t.libs << "test"
|
23
|
+
t.libs << "lib"
|
24
|
+
t.test_files = FileList['test/**/*_test.rb']
|
25
|
+
end
|
26
|
+
|
27
|
+
task :default => :test
|
28
|
+
|
29
|
+
rescue LoadError
|
30
|
+
$stderr.puts "\033[0;33m[!] Disabling rake tasks because the environment couldn’t be loaded. Be sure to run `rake bootstrap` first.\e[0m"
|
31
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
require "time_zone_scheduler/version"
|
2
|
+
|
3
|
+
require "active_support/core_ext/time/zones"
|
4
|
+
require 'active_support/duration'
|
5
|
+
|
6
|
+
# A Ruby library that assists in scheduling events whilst taking time zones into account. E.g. when to best deliver
|
7
|
+
# notifications such as push notifications or emails.
|
8
|
+
#
|
9
|
+
# It relies on ActiveSupport’s time and time zone functionality and expects a current system time zone to be specified
|
10
|
+
# through `Time.zone`.
|
11
|
+
#
|
12
|
+
# ### Terminology
|
13
|
+
#
|
14
|
+
# Consider a server sending notifications to a user:
|
15
|
+
#
|
16
|
+
# - **system time**: The local time of the server in the current time zone, as specified with `Time.zone`.
|
17
|
+
# - **reference time**: The time that needs to be e.g. converted into the user’s destination time zone.
|
18
|
+
# - **destination time zone**: The time zone that the user resides in.
|
19
|
+
# - **destination time**: The local time of the time zone that the user resides in.
|
20
|
+
#
|
21
|
+
class TimeZoneScheduler
|
22
|
+
VERSION = "0.1.0"
|
23
|
+
|
24
|
+
# @return [ActiveSupport::TimeZone]
|
25
|
+
# the destination time zone for the various calculations this class performs.
|
26
|
+
#
|
27
|
+
attr_reader :destination_time_zone
|
28
|
+
|
29
|
+
# @param [String, ActiveSupport::TimeZone] destination_time_zone
|
30
|
+
# the destination time zone that calculations will be performed in.
|
31
|
+
#
|
32
|
+
def initialize(destination_time_zone)
|
33
|
+
@destination_time_zone = Time.find_zone!(destination_time_zone)
|
34
|
+
end
|
35
|
+
|
36
|
+
# This calculation takes the local date and time of day of the reference time and converts that to the exact same date
|
37
|
+
# and time of day in the destination time zone and returns it in the system time. In other words, you’d use this to
|
38
|
+
# calculate the system time at which a specific date and time of day occurs in the destination time zone.
|
39
|
+
#
|
40
|
+
# For instance, you could use this to schedule notifications that should be sent to users on specific days of the week
|
41
|
+
# at times of the day that they are most likely to be good for the user. E.g. every Thursday at 10AM.
|
42
|
+
#
|
43
|
+
# @example Calculate the system time that corresponds to Sunday 2015-10-25 at 10AM in the Pacific/Niue time zone.
|
44
|
+
#
|
45
|
+
# Time.zone = "Pacific/Kiritimati" # Set the system time zone
|
46
|
+
# scheduler = TimeZoneScheduler.new("Pacific/Niue")
|
47
|
+
# reference_time = Time.parse("2015-10-25 10:00 UTC")
|
48
|
+
# system_time = scheduler.schedule_on_date(reference_time, false)
|
49
|
+
#
|
50
|
+
# p reference_time # => Sun, 25 Oct 2015 10:00:00 UTC +00:00
|
51
|
+
# p system_time # => Mon, 26 Oct 2015 11:00:00 LINT +14:00
|
52
|
+
#
|
53
|
+
# p system_time.sunday? # => false
|
54
|
+
# p system_time.hour # => 11
|
55
|
+
#
|
56
|
+
# p local_time = system_time.in_time_zone("Pacific/Niue")
|
57
|
+
# p local_time.sunday? # => true
|
58
|
+
# p local_time.hour # => 10
|
59
|
+
#
|
60
|
+
# @param [Time] reference_time
|
61
|
+
# the reference date and time of day that’s to be scheduled in the destination time zone.
|
62
|
+
#
|
63
|
+
# @param [Boolean] raise_if_time_has_passed
|
64
|
+
# whether or not to check if the time in the destination time zone has already passed.
|
65
|
+
#
|
66
|
+
# @raise [ArgumentError]
|
67
|
+
# in case the check is enabled, this is raised if the time in the destination time zone has already passed.
|
68
|
+
#
|
69
|
+
# @return [Time]
|
70
|
+
# the system time that corresponds to the time scheduled in the destination time zone.
|
71
|
+
#
|
72
|
+
def schedule_on_date(reference_time, raise_if_time_has_passed = true)
|
73
|
+
destination_time = @destination_time_zone.parse(reference_time.strftime('%F %T'))
|
74
|
+
system_time = destination_time.in_time_zone(Time.zone)
|
75
|
+
if raise_if_time_has_passed && system_time < Time.zone.now
|
76
|
+
raise ArgumentError, "The specified time has already passed in the #{@destination_time_zone.name} timezone."
|
77
|
+
end
|
78
|
+
system_time
|
79
|
+
end
|
80
|
+
|
81
|
+
# This calculation schedules the time to be at the same time as the reference time (real time), except when that time,
|
82
|
+
# in the destination time zone, falls _outside_ of the specified timeframe. In that case it delays the time until the
|
83
|
+
# next minimum time of the timeframe is reached.
|
84
|
+
#
|
85
|
+
# For instance, you could use this to schedule notifications about an event starting in either real-time, if that’s a
|
86
|
+
# good time for the user in their time zone, or otherwise delay it to the next good time.
|
87
|
+
#
|
88
|
+
# @example Return the real time, as the reference time falls in the specified timeframe in the Europe/Amsterdam time zone.
|
89
|
+
#
|
90
|
+
# Time.zone = "UTC" # Set the system time zone
|
91
|
+
# scheduler = TimeZoneScheduler.new("Europe/Amsterdam")
|
92
|
+
# reference_time = Time.parse("2015-10-25 12:00 UTC")
|
93
|
+
# system_time = scheduler.schedule_in_timeframe(reference_time, "10:00".."14:00")
|
94
|
+
# local_time = system_time.in_time_zone("Europe/Amsterdam")
|
95
|
+
#
|
96
|
+
# p reference_time # => Sun, 25 Oct 2015 12:00:00 UTC +00:00
|
97
|
+
# p system_time # => Sun, 25 Oct 2015 12:00:00 UTC +00:00
|
98
|
+
# p local_time # => Sun, 25 Oct 2015 13:00:00 CET +01:00
|
99
|
+
#
|
100
|
+
# @example Delay the reference time so that it’s not scheduled before 10AM in the Pacific/Kiritimati time zone.
|
101
|
+
#
|
102
|
+
# Time.zone = "UTC" # Set the system time zone
|
103
|
+
# scheduler = TimeZoneScheduler.new("Pacific/Kiritimati")
|
104
|
+
# reference_time = Time.parse("2015-10-25 12:00 UTC")
|
105
|
+
# system_time = scheduler.schedule_in_timeframe(reference_time, "10:00".."14:00")
|
106
|
+
# local_time = system_time.in_time_zone("Pacific/Kiritimati")
|
107
|
+
#
|
108
|
+
# p reference_time # => Sun, 25 Oct 2015 12:00:00 UTC +00:00
|
109
|
+
# p system_time # => Sun, 25 Oct 2015 20:00:00 UTC +00:00
|
110
|
+
# p local_time # => Mon, 26 Oct 2015 10:00:00 LINT +14:00
|
111
|
+
#
|
112
|
+
# @example Delay the reference time so that it’s not scheduled after 2PM in the Europe/Moscow time zone.
|
113
|
+
#
|
114
|
+
# Time.zone = "UTC" # Set the system time zone
|
115
|
+
# scheduler = TimeZoneScheduler.new("Europe/Moscow")
|
116
|
+
# reference_time = Time.parse("2015-10-25 12:00 UTC")
|
117
|
+
# system_time = scheduler.schedule_in_timeframe(reference_time, "10:00".."14:00")
|
118
|
+
# local_time = system_time.in_time_zone("Europe/Moscow")
|
119
|
+
#
|
120
|
+
# p reference_time # => Sun, 25 Oct 2015 12:00:00 UTC +00:00
|
121
|
+
# p system_time # => Mon, 26 Oct 2015 07:00:00 UTC +00:00
|
122
|
+
# p local_time # => Mon, 26 Oct 2015 10:00:00 MSK +03:00
|
123
|
+
#
|
124
|
+
# @param [Time] reference_time
|
125
|
+
# the reference time that’s to be re-scheduled in the destination time zone if it falls outside the timeframe.
|
126
|
+
#
|
127
|
+
# @param [Range<String..String>] timeframe
|
128
|
+
# a range of times (of the day) in which the scheduled time should fall.
|
129
|
+
#
|
130
|
+
# @return [Time]
|
131
|
+
# either the original reference time, if it falls in the timeframe, or the delayed time.
|
132
|
+
#
|
133
|
+
def schedule_in_timeframe(reference_time, timeframe)
|
134
|
+
timeframe = TimeFrame.new(@destination_time_zone, reference_time, timeframe)
|
135
|
+
if timeframe.reference_before_timeframe?
|
136
|
+
timeframe.min
|
137
|
+
elsif timeframe.reference_after_timeframe?
|
138
|
+
timeframe.min.tomorrow
|
139
|
+
else
|
140
|
+
reference_time
|
141
|
+
end.in_time_zone(Time.zone)
|
142
|
+
end
|
143
|
+
|
144
|
+
# This checks if the reference time falls in the given timeframe in the destination time zone.
|
145
|
+
#
|
146
|
+
# For instance, you could use this to disable playing a sound for notifications that **have** to be scheduled in real
|
147
|
+
# time, but you don’t necessarily want to e.g. wake the user.
|
148
|
+
#
|
149
|
+
# @example Return that 1PM in the Europe/Amsterdam time zone falls in the timeframe.
|
150
|
+
#
|
151
|
+
# Time.zone = "UTC" # Set the system time zone
|
152
|
+
# scheduler = TimeZoneScheduler.new("Europe/Amsterdam")
|
153
|
+
# reference_time = Time.parse("2015-10-25 12:00 UTC")
|
154
|
+
#
|
155
|
+
# p scheduler.in_timeframe?(reference_time, "08:00".."14:00") # => true
|
156
|
+
#
|
157
|
+
# @example Return that 3PM in the Europe/Moscow time zone falls outside the timeframe.
|
158
|
+
#
|
159
|
+
# Time.zone = "UTC" # Set the system time zone
|
160
|
+
# scheduler = TimeZoneScheduler.new("Europe/Moscow")
|
161
|
+
# reference_time = Time.parse("2015-10-25 12:00 UTC")
|
162
|
+
#
|
163
|
+
# p scheduler.in_timeframe?(reference_time, "08:00".."14:00") # => true
|
164
|
+
#
|
165
|
+
# @param [Time] reference_time
|
166
|
+
# the reference time that’s to be checked if it falls in the timeframe in the destination time zone.
|
167
|
+
#
|
168
|
+
# @param [Range<String..String>] timeframe
|
169
|
+
# a range of times (of the day) in which the reference time should fall.
|
170
|
+
#
|
171
|
+
# @return [Boolean]
|
172
|
+
# whether or not the reference time falls in the specified timeframe in the destination time zone.
|
173
|
+
#
|
174
|
+
def in_timeframe?(reference_time, timeframe)
|
175
|
+
TimeFrame.new(@destination_time_zone, reference_time, timeframe).reference_in_timeframe?
|
176
|
+
end
|
177
|
+
|
178
|
+
# @!visibility private
|
179
|
+
#
|
180
|
+
# Assists in calculations regarding timeframes. It caches the results so the caller doesn’t need to worry about cost.
|
181
|
+
#
|
182
|
+
class TimeFrame
|
183
|
+
# @param [ActiveSupport::TimeZone] destination_time_zone
|
184
|
+
# @param [Time] reference_time
|
185
|
+
# @param [Range<String..String>] timeframe
|
186
|
+
#
|
187
|
+
def initialize(destination_time_zone, reference_time, timeframe)
|
188
|
+
@destination_time_zone, @reference_time, @timeframe = destination_time_zone, reference_time, timeframe
|
189
|
+
end
|
190
|
+
|
191
|
+
# @return [Time]
|
192
|
+
# the minimum time of the timeframe range in the destination time zone.
|
193
|
+
#
|
194
|
+
def min
|
195
|
+
@min ||= @destination_time_zone.parse("#{local_date} #{@timeframe.min}")
|
196
|
+
end
|
197
|
+
|
198
|
+
# @return [Time]
|
199
|
+
# the maximum time of the timeframe range in the destination time zone.
|
200
|
+
#
|
201
|
+
def max
|
202
|
+
@max ||= @destination_time_zone.parse("#{local_date} #{@timeframe.max}")
|
203
|
+
end
|
204
|
+
|
205
|
+
# @return [Boolean]
|
206
|
+
# whether the reference time falls before the timeframe.
|
207
|
+
#
|
208
|
+
def reference_before_timeframe?
|
209
|
+
local_time < min
|
210
|
+
end
|
211
|
+
|
212
|
+
# @return [Boolean]
|
213
|
+
# whether the reference time falls after the timeframe.
|
214
|
+
#
|
215
|
+
def reference_after_timeframe?
|
216
|
+
local_time > max
|
217
|
+
end
|
218
|
+
|
219
|
+
# @note First checks if the reference time falls before the timeframe, because if that fails {#max} never needs to
|
220
|
+
# be performed for {TimeZoneScheduler#schedule_in_timeframe} to be able to perform its work.
|
221
|
+
#
|
222
|
+
# @return [Boolean]
|
223
|
+
# whether the reference time falls in the timeframe.
|
224
|
+
#
|
225
|
+
def reference_in_timeframe?
|
226
|
+
!reference_before_timeframe? && !reference_after_timeframe?
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
# @return [Time]
|
232
|
+
# the reference time in the destination timezone.
|
233
|
+
#
|
234
|
+
def local_time
|
235
|
+
@local_time ||= @reference_time.in_time_zone(@destination_time_zone)
|
236
|
+
end
|
237
|
+
|
238
|
+
# @return [String]
|
239
|
+
# the date of the reference time in the destination timezone.
|
240
|
+
#
|
241
|
+
def local_date
|
242
|
+
@date ||= local_time.strftime('%F')
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'time_zone_scheduler/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "time_zone_scheduler"
|
8
|
+
spec.version = TimeZoneScheduler::VERSION
|
9
|
+
spec.authors = ["Eloy Durán"]
|
10
|
+
spec.email = ["eloy.de.enige@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "A library that assists in scheduling events whilst taking time zones into account."
|
13
|
+
spec.homepage = "https://github.com/alloy/time_zone_scheduler"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_runtime_dependency "activesupport"
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
24
|
+
spec.add_development_dependency "timecop", "~> 0.8.0"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: time_zone_scheduler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eloy Durán
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: timecop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.8.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.0
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- eloy.de.enige@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- .travis.yml
|
92
|
+
- .yardopts
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- lib/time_zone_scheduler.rb
|
98
|
+
- lib/time_zone_scheduler/version.rb
|
99
|
+
- time_zone_scheduler.gemspec
|
100
|
+
homepage: https://github.com/alloy/time_zone_scheduler
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.5.0
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: A library that assists in scheduling events whilst taking time zones into
|
124
|
+
account.
|
125
|
+
test_files: []
|
126
|
+
has_rdoc:
|