ice_cube_chosko 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/config/locales/en.yml +178 -0
- data/config/locales/es.yml +176 -0
- data/config/locales/ja.yml +107 -0
- data/lib/ice_cube.rb +92 -0
- data/lib/ice_cube/builders/hash_builder.rb +27 -0
- data/lib/ice_cube/builders/ical_builder.rb +59 -0
- data/lib/ice_cube/builders/string_builder.rb +76 -0
- data/lib/ice_cube/deprecated.rb +36 -0
- data/lib/ice_cube/errors/count_exceeded.rb +7 -0
- data/lib/ice_cube/errors/until_exceeded.rb +7 -0
- data/lib/ice_cube/flexible_hash.rb +40 -0
- data/lib/ice_cube/i18n.rb +24 -0
- data/lib/ice_cube/null_i18n.rb +28 -0
- data/lib/ice_cube/occurrence.rb +101 -0
- data/lib/ice_cube/parsers/hash_parser.rb +91 -0
- data/lib/ice_cube/parsers/ical_parser.rb +91 -0
- data/lib/ice_cube/parsers/yaml_parser.rb +19 -0
- data/lib/ice_cube/rule.rb +123 -0
- data/lib/ice_cube/rules/daily_rule.rb +16 -0
- data/lib/ice_cube/rules/hourly_rule.rb +16 -0
- data/lib/ice_cube/rules/minutely_rule.rb +16 -0
- data/lib/ice_cube/rules/monthly_rule.rb +16 -0
- data/lib/ice_cube/rules/secondly_rule.rb +15 -0
- data/lib/ice_cube/rules/weekly_rule.rb +16 -0
- data/lib/ice_cube/rules/yearly_rule.rb +16 -0
- data/lib/ice_cube/schedule.rb +529 -0
- data/lib/ice_cube/single_occurrence_rule.rb +28 -0
- data/lib/ice_cube/time_util.rb +328 -0
- data/lib/ice_cube/validated_rule.rb +184 -0
- data/lib/ice_cube/validations/count.rb +61 -0
- data/lib/ice_cube/validations/daily_interval.rb +54 -0
- data/lib/ice_cube/validations/day.rb +71 -0
- data/lib/ice_cube/validations/day_of_month.rb +55 -0
- data/lib/ice_cube/validations/day_of_week.rb +77 -0
- data/lib/ice_cube/validations/day_of_year.rb +61 -0
- data/lib/ice_cube/validations/fixed_value.rb +95 -0
- data/lib/ice_cube/validations/hour_of_day.rb +55 -0
- data/lib/ice_cube/validations/hourly_interval.rb +54 -0
- data/lib/ice_cube/validations/lock.rb +95 -0
- data/lib/ice_cube/validations/minute_of_hour.rb +54 -0
- data/lib/ice_cube/validations/minutely_interval.rb +54 -0
- data/lib/ice_cube/validations/month_of_year.rb +54 -0
- data/lib/ice_cube/validations/monthly_interval.rb +53 -0
- data/lib/ice_cube/validations/schedule_lock.rb +46 -0
- data/lib/ice_cube/validations/second_of_minute.rb +54 -0
- data/lib/ice_cube/validations/secondly_interval.rb +51 -0
- data/lib/ice_cube/validations/until.rb +57 -0
- data/lib/ice_cube/validations/weekly_interval.rb +67 -0
- data/lib/ice_cube/validations/yearly_interval.rb +53 -0
- data/lib/ice_cube/version.rb +5 -0
- data/spec/spec_helper.rb +64 -0
- metadata +166 -0
data/lib/ice_cube.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'ice_cube/deprecated'
|
3
|
+
require 'ice_cube/i18n'
|
4
|
+
|
5
|
+
IceCube::I18n.detect_backend!
|
6
|
+
|
7
|
+
module IceCube
|
8
|
+
|
9
|
+
autoload :VERSION, 'ice_cube/version'
|
10
|
+
|
11
|
+
autoload :TimeUtil, 'ice_cube/time_util'
|
12
|
+
autoload :FlexibleHash, 'ice_cube/flexible_hash'
|
13
|
+
|
14
|
+
autoload :Rule, 'ice_cube/rule'
|
15
|
+
autoload :Schedule, 'ice_cube/schedule'
|
16
|
+
autoload :Occurrence, 'ice_cube/occurrence'
|
17
|
+
|
18
|
+
autoload :IcalBuilder, 'ice_cube/builders/ical_builder'
|
19
|
+
autoload :HashBuilder, 'ice_cube/builders/hash_builder'
|
20
|
+
autoload :StringBuilder, 'ice_cube/builders/string_builder'
|
21
|
+
|
22
|
+
autoload :HashParser, 'ice_cube/parsers/hash_parser'
|
23
|
+
autoload :YamlParser, 'ice_cube/parsers/yaml_parser'
|
24
|
+
autoload :IcalParser, 'ice_cube/parsers/ical_parser'
|
25
|
+
|
26
|
+
autoload :CountExceeded, 'ice_cube/errors/count_exceeded'
|
27
|
+
autoload :UntilExceeded, 'ice_cube/errors/until_exceeded'
|
28
|
+
|
29
|
+
autoload :ValidatedRule, 'ice_cube/validated_rule'
|
30
|
+
autoload :SingleOccurrenceRule, 'ice_cube/single_occurrence_rule'
|
31
|
+
|
32
|
+
autoload :SecondlyRule, 'ice_cube/rules/secondly_rule'
|
33
|
+
autoload :MinutelyRule, 'ice_cube/rules/minutely_rule'
|
34
|
+
autoload :HourlyRule, 'ice_cube/rules/hourly_rule'
|
35
|
+
autoload :DailyRule, 'ice_cube/rules/daily_rule'
|
36
|
+
autoload :WeeklyRule, 'ice_cube/rules/weekly_rule'
|
37
|
+
autoload :MonthlyRule, 'ice_cube/rules/monthly_rule'
|
38
|
+
autoload :YearlyRule, 'ice_cube/rules/yearly_rule'
|
39
|
+
|
40
|
+
module Validations
|
41
|
+
autoload :FixedValue, 'ice_cube/validations/fixed_value'
|
42
|
+
autoload :ScheduleLock, 'ice_cube/validations/schedule_lock'
|
43
|
+
|
44
|
+
autoload :Count, 'ice_cube/validations/count'
|
45
|
+
autoload :Until, 'ice_cube/validations/until'
|
46
|
+
|
47
|
+
autoload :SecondlyInterval, 'ice_cube/validations/secondly_interval'
|
48
|
+
autoload :MinutelyInterval, 'ice_cube/validations/minutely_interval'
|
49
|
+
autoload :DailyInterval, 'ice_cube/validations/daily_interval'
|
50
|
+
autoload :WeeklyInterval, 'ice_cube/validations/weekly_interval'
|
51
|
+
autoload :MonthlyInterval, 'ice_cube/validations/monthly_interval'
|
52
|
+
autoload :YearlyInterval, 'ice_cube/validations/yearly_interval'
|
53
|
+
autoload :HourlyInterval, 'ice_cube/validations/hourly_interval'
|
54
|
+
|
55
|
+
autoload :HourOfDay, 'ice_cube/validations/hour_of_day'
|
56
|
+
autoload :MonthOfYear, 'ice_cube/validations/month_of_year'
|
57
|
+
autoload :MinuteOfHour, 'ice_cube/validations/minute_of_hour'
|
58
|
+
autoload :SecondOfMinute, 'ice_cube/validations/second_of_minute'
|
59
|
+
autoload :DayOfMonth, 'ice_cube/validations/day_of_month'
|
60
|
+
autoload :DayOfWeek, 'ice_cube/validations/day_of_week'
|
61
|
+
autoload :Day, 'ice_cube/validations/day'
|
62
|
+
autoload :DayOfYear, 'ice_cube/validations/day_of_year'
|
63
|
+
end
|
64
|
+
|
65
|
+
# Define some useful constants
|
66
|
+
ONE_SECOND = 1
|
67
|
+
ONE_MINUTE = ONE_SECOND * 60
|
68
|
+
ONE_HOUR = ONE_MINUTE * 60
|
69
|
+
ONE_DAY = ONE_HOUR * 24
|
70
|
+
ONE_WEEK = ONE_DAY * 7
|
71
|
+
|
72
|
+
# Defines the format used by IceCube when printing out Schedule#to_s.
|
73
|
+
# Defaults to '%B %e, %Y'
|
74
|
+
def self.to_s_time_format
|
75
|
+
IceCube::I18n.t("ice_cube.date.formats.default")
|
76
|
+
end
|
77
|
+
|
78
|
+
# Sets the format used by IceCube when printing out Schedule#to_s.
|
79
|
+
def self.to_s_time_format=(format)
|
80
|
+
@to_s_time_format = format
|
81
|
+
end
|
82
|
+
|
83
|
+
# Retain backwards compatibility for schedules exported from older versions
|
84
|
+
# This represents the version number, 11 = 0.11, 1.0 will be 100
|
85
|
+
def self.compatibility
|
86
|
+
@compatibility ||= IceCube::VERSION.scan(/\d+/)[0..1].join.to_i
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.compatibility=(version)
|
90
|
+
@compatibility = version
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module IceCube
|
2
|
+
|
3
|
+
class HashBuilder
|
4
|
+
|
5
|
+
def initialize(rule = nil)
|
6
|
+
@hash = { :validations => {}, :rule_type => rule.class.name }
|
7
|
+
end
|
8
|
+
|
9
|
+
def validations
|
10
|
+
@hash[:validations]
|
11
|
+
end
|
12
|
+
|
13
|
+
def []=(key, value)
|
14
|
+
@hash[key] = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def validations_array(type)
|
18
|
+
validations[type] ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
@hash
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module IceCube
|
2
|
+
|
3
|
+
class IcalBuilder
|
4
|
+
|
5
|
+
ICAL_DAYS = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@hash = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.fixnum_to_ical_day(num)
|
12
|
+
ICAL_DAYS[num]
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
@hash[key] ||= []
|
17
|
+
end
|
18
|
+
|
19
|
+
# Build for a single rule entry
|
20
|
+
def to_s
|
21
|
+
arr = []
|
22
|
+
if freq = @hash.delete('FREQ')
|
23
|
+
arr << "FREQ=#{freq.join(',')}"
|
24
|
+
end
|
25
|
+
arr.concat(@hash.map do |key, value|
|
26
|
+
if value.is_a?(Array)
|
27
|
+
"#{key}=#{value.join(',')}"
|
28
|
+
end
|
29
|
+
end.compact)
|
30
|
+
arr.join(';')
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.ical_utc_format(time)
|
34
|
+
time = time.dup.utc
|
35
|
+
IceCube::I18n.l(time, format: '%Y%m%dT%H%M%SZ') # utc time
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.ical_format(time, force_utc)
|
39
|
+
time = time.dup.utc if force_utc
|
40
|
+
if time.utc?
|
41
|
+
":#{IceCube::I18n.l(time, format: '%Y%m%dT%H%M%SZ')}" # utc time
|
42
|
+
else
|
43
|
+
";TZID=#{IceCube::I18n.l(time, format: '%Z:%Y%m%dT%H%M%S')}" # local time specified
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.ical_duration(duration)
|
48
|
+
hours = duration / 3600; duration %= 3600
|
49
|
+
minutes = duration / 60; duration %= 60
|
50
|
+
repr = ''
|
51
|
+
repr << "#{hours}H" if hours > 0
|
52
|
+
repr << "#{minutes}M" if minutes > 0
|
53
|
+
repr << "#{duration}S" if duration > 0
|
54
|
+
"PT#{repr}"
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module IceCube
|
2
|
+
|
3
|
+
class StringBuilder
|
4
|
+
|
5
|
+
attr_writer :base
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@types = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def piece(type, prefix = nil, suffix = nil)
|
12
|
+
@types[type] ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
string = @base || ''
|
17
|
+
@types.each do |type, segments|
|
18
|
+
if f = self.class.formatter(type)
|
19
|
+
current = f.call(segments)
|
20
|
+
else
|
21
|
+
next if segments.empty?
|
22
|
+
current = self.class.sentence(segments)
|
23
|
+
end
|
24
|
+
f = IceCube::I18n.t('ice_cube.string.format')[type] ? type : 'default'
|
25
|
+
string = IceCube::I18n.t("ice_cube.string.format.#{f}", rest: string, current: current)
|
26
|
+
end
|
27
|
+
string
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.formatter(type)
|
31
|
+
@formatters[type]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.register_formatter(type, &formatter)
|
35
|
+
@formatters ||= {}
|
36
|
+
@formatters[type] = formatter
|
37
|
+
end
|
38
|
+
|
39
|
+
module Helpers
|
40
|
+
|
41
|
+
# influenced by ActiveSupport's to_sentence
|
42
|
+
def sentence(array)
|
43
|
+
case array.length
|
44
|
+
when 0 ; ''
|
45
|
+
when 1 ; array[0].to_s
|
46
|
+
when 2 ; "#{array[0]}#{IceCube::I18n.t('ice_cube.array.two_words_connector')}#{array[1]}"
|
47
|
+
else ; "#{array[0...-1].join(IceCube::I18n.t('ice_cube.array.words_connector'))}#{IceCube::I18n.t('ice_cube.array.last_word_connector')}#{array[-1]}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def nice_number(number)
|
52
|
+
literal_ordinal(number) || ordinalize(number)
|
53
|
+
end
|
54
|
+
|
55
|
+
def ordinalize(number)
|
56
|
+
IceCube::I18n.t('ice_cube.integer.ordinal', number: number, ordinal: ordinal(number))
|
57
|
+
end
|
58
|
+
|
59
|
+
def literal_ordinal(number)
|
60
|
+
IceCube::I18n.t("ice_cube.integer.literal_ordinals")[number]
|
61
|
+
end
|
62
|
+
|
63
|
+
def ordinal(number)
|
64
|
+
ord = IceCube::I18n.t("ice_cube.integer.ordinals")[number] ||
|
65
|
+
IceCube::I18n.t("ice_cube.integer.ordinals")[number % 10] ||
|
66
|
+
IceCube::I18n.t('ice_cube.integer.ordinals')[:default]
|
67
|
+
number >= 0 ? ord : IceCube::I18n.t("ice_cube.integer.negative", ordinal: ord)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
extend Helpers
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module IceCube
|
2
|
+
module Deprecated
|
3
|
+
|
4
|
+
# Define a deprecated alias for a method
|
5
|
+
# @param [Symbol] name - name of method to define
|
6
|
+
# @param [Symbol] replacement - name of method to replace (alias)
|
7
|
+
def deprecated_alias(name, replacement)
|
8
|
+
# Create a wrapped version
|
9
|
+
define_method(name) do |*args, &block|
|
10
|
+
warn "IceCube: #{self.class}##{name} is deprecated, please use ##{replacement} at: #{ caller[0] }"
|
11
|
+
send replacement, *args, &block
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Deprecate a defined method
|
16
|
+
# @param [Symbol] name - name of deprecated method
|
17
|
+
# @param [Symbol] replacement - name of the desired replacement
|
18
|
+
def deprecated(name, replacement)
|
19
|
+
# Replace old method
|
20
|
+
old_name = :"#{name}_without_deprecation"
|
21
|
+
alias_method old_name, name
|
22
|
+
# And replace it with a wrapped version
|
23
|
+
define_method(name) do |*args, &block|
|
24
|
+
warn "IceCube: #{self.class}##{name} is deprecated, please use ##{replacement} at: #{ caller[0] }"
|
25
|
+
send old_name, *args, &block
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.schedule_options(schedule, options)
|
30
|
+
if options[:start_date_override]
|
31
|
+
warn "IceCube: :start_date_override option is deprecated, please use a block {|s| s.start_time = override }. at: #{ caller[0] }"
|
32
|
+
schedule.start_time = options[:start_date_override]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module IceCube
|
4
|
+
|
5
|
+
# Find keys by symbol or string without symbolizing user input
|
6
|
+
# Due to the serialization format of ice_cube, this limited implementation
|
7
|
+
# is entirely sufficient
|
8
|
+
|
9
|
+
class FlexibleHash < SimpleDelegator
|
10
|
+
|
11
|
+
def [](key)
|
12
|
+
key = _match_key(key)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch(key)
|
17
|
+
key = _match_key(key)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete(key)
|
22
|
+
key = _match_key(key)
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def _match_key(key)
|
29
|
+
return key if __getobj__.has_key? key
|
30
|
+
if Symbol == key.class
|
31
|
+
__getobj__.keys.detect { |k| return k if k == key.to_s }
|
32
|
+
elsif String == key.class
|
33
|
+
__getobj__.keys.detect { |k| return k if k.to_s == key }
|
34
|
+
end
|
35
|
+
key
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module IceCube
|
2
|
+
module I18n
|
3
|
+
def self.t(*args)
|
4
|
+
backend.t(*args)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.l(*args)
|
8
|
+
backend.l(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.backend
|
12
|
+
@backend
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.detect_backend!
|
16
|
+
require 'i18n'
|
17
|
+
::I18n.load_path += Dir[File.expand_path('../../../config/locales/*{rb,yml}', __FILE__)]
|
18
|
+
@backend = ::I18n
|
19
|
+
rescue LoadError
|
20
|
+
require 'ice_cube/null_i18n'
|
21
|
+
@backend = NullI18n
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module IceCube
|
4
|
+
module NullI18n
|
5
|
+
def self.t(key, options = {})
|
6
|
+
base = key.to_s.split('.').reduce(config) { |hash, current_key| hash[current_key] }
|
7
|
+
|
8
|
+
base = base[options[:count] == 1 ? "one" : "other"] if options[:count]
|
9
|
+
|
10
|
+
if base.is_a?(Hash)
|
11
|
+
return base.each_with_object({}) do |(key, value), hash|
|
12
|
+
hash[key.is_a?(String) ? key.to_sym : key] = value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
options.reduce(base) { |result, (find, replace)| result.gsub("%{#{find}}", "#{replace}") }
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.l(date_or_time, options = {})
|
20
|
+
return date_or_time.strftime(options[:format]) if options[:format]
|
21
|
+
date_or_time.strftime(t('ice_cube.date.formats.default'))
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.config
|
25
|
+
@config ||= YAML.load(File.read(File.join(File.dirname(__FILE__), '..', '..', 'config', 'locales', 'en.yml')))['en']
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
module IceCube
|
5
|
+
|
6
|
+
# Wraps start_time and end_time in a single concept concerning the duration.
|
7
|
+
# This delegates to the enclosed start_time so it behaves like a normal Time
|
8
|
+
# in almost all situations, however:
|
9
|
+
#
|
10
|
+
# Without ActiveSupport, it's necessary to cast the occurrence using
|
11
|
+
# +#to_time+ before doing arithmetic, else Time will try to subtract it
|
12
|
+
# using +#to_i+ and return a new time instead.
|
13
|
+
#
|
14
|
+
# Time.now - Occurrence.new(start_time) # => 1970-01-01 01:00:00
|
15
|
+
# Time.now - Occurrence.new(start_time).to_time # => 3600
|
16
|
+
#
|
17
|
+
# When ActiveSupport::Time core extensions are loaded, it's possible to
|
18
|
+
# subtract an Occurrence object directly from a Time to get the difference:
|
19
|
+
#
|
20
|
+
# Time.now - Occurrence.new(start_time) # => 3600
|
21
|
+
#
|
22
|
+
class Occurrence < SimpleDelegator
|
23
|
+
|
24
|
+
# Report class name as 'Time' to thwart type checking.
|
25
|
+
def self.name
|
26
|
+
'Time'
|
27
|
+
end
|
28
|
+
|
29
|
+
# Optimize for common methods to avoid method_missing
|
30
|
+
extend Forwardable
|
31
|
+
def_delegators :start_time, :to_i, :<=>, :==
|
32
|
+
def_delegators :to_range, :cover?, :include?, :each, :first, :last
|
33
|
+
|
34
|
+
attr_reader :start_time, :end_time
|
35
|
+
|
36
|
+
def initialize(start_time, end_time=nil)
|
37
|
+
@start_time = start_time
|
38
|
+
@end_time = end_time || start_time
|
39
|
+
__setobj__ @start_time
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_a?(klass)
|
43
|
+
klass == ::Time || super
|
44
|
+
end
|
45
|
+
alias_method :kind_of?, :is_a?
|
46
|
+
|
47
|
+
def intersects? other
|
48
|
+
if other.is_a?(Occurrence) || other.is_a?(Range)
|
49
|
+
lower_bound_1 = first + 1
|
50
|
+
upper_bound_1 = last # exclude end
|
51
|
+
lower_bound_2 = other.first + 1
|
52
|
+
upper_bound_2 = other.last + 1
|
53
|
+
if (lower_bound_2 <=> upper_bound_2) > 0
|
54
|
+
false
|
55
|
+
elsif (lower_bound_1 <=> upper_bound_1) > 0
|
56
|
+
false
|
57
|
+
else
|
58
|
+
(upper_bound_1 <=> lower_bound_2) >= 0 and
|
59
|
+
(upper_bound_2 <=> lower_bound_1) >= 0
|
60
|
+
end
|
61
|
+
else
|
62
|
+
cover? other
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def comparable_time
|
67
|
+
start_time
|
68
|
+
end
|
69
|
+
|
70
|
+
def duration
|
71
|
+
end_time - start_time
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_range
|
75
|
+
start_time..end_time
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_time
|
79
|
+
start_time
|
80
|
+
end
|
81
|
+
|
82
|
+
# Shows both the start and end time if there is a duration.
|
83
|
+
# Optional format argument (e.g. :long, :short) supports Rails
|
84
|
+
# time formats and is only used when ActiveSupport is available.
|
85
|
+
#
|
86
|
+
def to_s(format=nil)
|
87
|
+
if format && to_time.public_method(:to_s).arity != 0
|
88
|
+
t0, t1 = start_time.to_s(format), end_time.to_s(format)
|
89
|
+
else
|
90
|
+
t0, t1 = start_time.to_s, end_time.to_s
|
91
|
+
end
|
92
|
+
duration > 0 ? "#{t0} - #{t1}" : t0
|
93
|
+
end
|
94
|
+
|
95
|
+
def overnight?
|
96
|
+
offset = start_time + 3600 * 24
|
97
|
+
midnight = Time.new(offset.year, offset.month, offset.day)
|
98
|
+
midnight < end_time
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|