timesteps 0.9.6 → 1.0.1
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 +4 -4
- data/.yardopts +1 -0
- data/{LICENSES → LICENSE} +0 -0
- data/NEWS.md +8 -0
- data/Note.ja.md +9 -0
- data/README.md +15 -7
- data/lib/timesteps/datetime_parse_timestamp.rb +21 -12
- data/lib/timesteps/datetime_timestep.rb +64 -0
- data/lib/timesteps/datetimelike.rb +6 -17
- data/lib/timesteps/grads.rb +39 -18
- data/lib/timesteps/time.rb +14 -0
- data/lib/timesteps/timeperiod.rb +50 -47
- data/lib/timesteps/timestep.rb +480 -248
- data/lib/timesteps/timestep_calendar.rb +49 -29
- data/lib/timesteps/timestep_converter.rb +19 -22
- data/lib/timesteps/timestep_datetime_ext.rb +6 -16
- data/lib/timesteps/timestep_pair.rb +37 -24
- data/lib/timesteps/timestep_query.rb +12 -4
- data/lib/timesteps/timestep_range.rb +155 -0
- data/lib/timesteps.rb +4 -0
- data/spec/allleap_spec.rb +4 -15
- data/spec/fixed360day_spec.rb +4 -15
- data/spec/noleap_spec.rb +2 -13
- data/spec/timestep_spec.rb +4 -27
- data/timesteps.gemspec +3 -3
- metadata +9 -4
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
autoload :TZInfo, "tzinfo"
|
3
|
+
|
2
4
|
class TimeStep
|
3
5
|
|
4
6
|
class Calendar
|
@@ -23,12 +25,11 @@ class TimeStep
|
|
23
25
|
|
24
26
|
# Construct the object
|
25
27
|
#
|
26
|
-
def initialize (calendar = "standard",
|
28
|
+
def initialize (calendar = "standard", tz: nil)
|
27
29
|
unless calendar.is_a?(String)
|
28
30
|
raise ArgumentError, "argument calendar '#{calendar}' should be string"
|
29
31
|
end
|
30
32
|
@name = calendar
|
31
|
-
@bc = bc
|
32
33
|
case @name.downcase.intern
|
33
34
|
when :standard, :gregorian
|
34
35
|
@calendar = :standard
|
@@ -43,22 +44,30 @@ class TimeStep
|
|
43
44
|
when SYM_360_day
|
44
45
|
@calendar = SYM_360_day
|
45
46
|
end
|
47
|
+
if tz
|
48
|
+
raise "'standard' calendar needed for tz" unless @calendar == :standard
|
49
|
+
case tz
|
50
|
+
when nil
|
51
|
+
when String
|
52
|
+
@tz = TZInfo::Timezone.get(tz)
|
53
|
+
when TZInfo::Timezone
|
54
|
+
@tz = tz
|
55
|
+
else
|
56
|
+
raise "invalid tz specification"
|
57
|
+
end
|
58
|
+
end
|
46
59
|
end
|
47
60
|
|
48
|
-
attr_reader :name, :calendar
|
49
|
-
|
61
|
+
attr_reader :name, :calendar, :tz
|
62
|
+
|
50
63
|
def inspect
|
51
|
-
"#<TimeStep::Calendar calendar='#{@calendar.to_s}'
|
64
|
+
"#<TimeStep::Calendar calendar='#{@calendar.to_s}'>"
|
52
65
|
end
|
53
66
|
|
54
67
|
def == (other)
|
55
|
-
return @calendar == other.calendar
|
56
|
-
end
|
57
|
-
|
58
|
-
def bc?
|
59
|
-
return @bc ? true : false
|
68
|
+
return @calendar == other.calendar
|
60
69
|
end
|
61
|
-
|
70
|
+
|
62
71
|
def valid_datetime_type? (time)
|
63
72
|
return false unless time.is_a?(DateTimeType[@calendar])
|
64
73
|
case @calendar
|
@@ -77,10 +86,31 @@ class TimeStep
|
|
77
86
|
# and creates an date time instance.
|
78
87
|
#
|
79
88
|
# @return [DateTime object]
|
80
|
-
def parse (timespec, format: nil)
|
81
|
-
return DateTime.parse_timestamp(timespec, calendar: @calendar.to_s,
|
89
|
+
def parse (timespec, format: nil, offset: nil)
|
90
|
+
return DateTime.parse_timestamp(timespec, calendar: @calendar.to_s, format: format, tz: @tz, offset: offset)
|
82
91
|
end
|
83
|
-
|
92
|
+
|
93
|
+
def time_new (year, month, day, hour=0, min=0, sec=0, offset=0)
|
94
|
+
case @calendar
|
95
|
+
when :standard
|
96
|
+
time = DateTime.new(year, month, day, hour, min, sec, offset, Date::ITALY)
|
97
|
+
when :proleptic_gregorian
|
98
|
+
time = DateTime.new(year, month, day, hour, min, sec, offset, Date::GREGORIAN)
|
99
|
+
when :proleptic_julian
|
100
|
+
time = DateTime.new(year, month, day, hour, min, sec, offset, Date::JULIAN)
|
101
|
+
when :noleap
|
102
|
+
time = DateTime::NoLeap.new(year, month, day, hour, min, sec, offset)
|
103
|
+
when :allleap
|
104
|
+
time = DateTime::AllLeap.new(year, month, day, hour, min, sec, offset)
|
105
|
+
when SYM_360_day
|
106
|
+
time = DateTime::Fixed360Day.new(year, month, day, hour, min, sec, offset)
|
107
|
+
end
|
108
|
+
if @tz
|
109
|
+
time = @tz.to_local(time)
|
110
|
+
end
|
111
|
+
return time
|
112
|
+
end
|
113
|
+
|
84
114
|
def jday2date (jday)
|
85
115
|
case @calendar
|
86
116
|
when :standard
|
@@ -96,27 +126,17 @@ class TimeStep
|
|
96
126
|
when SYM_360_day
|
97
127
|
time = DateTime::Fixed360Day.jd(jday, 0, 0, 0, 0)
|
98
128
|
end
|
129
|
+
if @tz
|
130
|
+
time = @tz.to_local(time)
|
131
|
+
end
|
99
132
|
return time
|
100
133
|
end
|
101
134
|
|
102
135
|
def date2jday (year, month, day)
|
103
|
-
|
104
|
-
when :standard
|
105
|
-
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::ITALY)
|
106
|
-
when :proleptic_gregorian
|
107
|
-
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::GREGORIAN)
|
108
|
-
when :proleptic_julian
|
109
|
-
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::JULIAN)
|
110
|
-
when :noleap
|
111
|
-
time = DateTime::NoLeap.new(year, month, day, 0, 0, 0, 0)
|
112
|
-
when :allleap
|
113
|
-
time = DateTime::AllLeap.new(year, month, day, 0, 0, 0, 0)
|
114
|
-
when SYM_360_day
|
115
|
-
time = DateTime::Fixed360Day.new(year, month, day, 0, 0, 0, 0)
|
116
|
-
end
|
117
|
-
return time.jd
|
136
|
+
return time_new(year, month, day).jd
|
118
137
|
end
|
119
138
|
|
120
139
|
end
|
121
140
|
|
122
141
|
end
|
142
|
+
|
@@ -2,12 +2,11 @@ require "timesteps"
|
|
2
2
|
|
3
3
|
class TimeStep::Converter
|
4
4
|
|
5
|
-
def initialize (reference, name: "reference", calendar: "standard"
|
5
|
+
def initialize (reference, name: "reference", calendar: "standard")
|
6
6
|
@calendar = calendar
|
7
|
-
@bc = bc
|
8
7
|
case reference
|
9
8
|
when String
|
10
|
-
@reference = TimeStep.new(reference, calendar: calendar
|
9
|
+
@reference = TimeStep.new(reference, calendar: calendar)
|
11
10
|
when TimeStep
|
12
11
|
@reference = reference
|
13
12
|
else
|
@@ -21,9 +20,9 @@ class TimeStep::Converter
|
|
21
20
|
# Append or reset new target time step for the given name.
|
22
21
|
#
|
23
22
|
def add_timestep (spec, name:)
|
24
|
-
@pair[name] = TimeStep::Pair.new(@reference, spec, calendar: @calendar
|
23
|
+
@pair[name] = TimeStep::Pair.new(@reference, spec, calendar: @calendar)
|
25
24
|
@target[name] = @pair[name].to
|
26
|
-
return @
|
25
|
+
return @pair[name]
|
27
26
|
end
|
28
27
|
|
29
28
|
# Append or reset new target time step for the given name.
|
@@ -35,14 +34,14 @@ class TimeStep::Converter
|
|
35
34
|
# Return target time step of the given name.
|
36
35
|
#
|
37
36
|
def [] (name)
|
38
|
-
return @
|
37
|
+
return @pair[name]
|
39
38
|
end
|
40
39
|
|
41
40
|
# Relete target of the given name.
|
42
41
|
#
|
43
42
|
def delete (name)
|
44
|
-
@pair.delete(name)
|
45
43
|
@target.delete(name)
|
44
|
+
@pair.delete(name)
|
46
45
|
end
|
47
46
|
|
48
47
|
# Returns the time represented by the given index as DateTime object
|
@@ -56,11 +55,18 @@ class TimeStep::Converter
|
|
56
55
|
|
57
56
|
# Converts index refering `from` timestep to index refering `to`timestep.
|
58
57
|
#
|
59
|
-
def forward (*indices, with_time:
|
58
|
+
def forward (*indices, with_time: nil)
|
60
59
|
if with_time
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
case with_time
|
61
|
+
when String
|
62
|
+
hash = {
|
63
|
+
"time" => time_at(*indices).map{|t| t.strftime(with_time) }
|
64
|
+
}
|
65
|
+
else
|
66
|
+
hash = {
|
67
|
+
"time" => time_at(*indices)
|
68
|
+
}
|
69
|
+
end
|
64
70
|
else
|
65
71
|
hash = {}
|
66
72
|
end
|
@@ -70,8 +76,8 @@ class TimeStep::Converter
|
|
70
76
|
return hash
|
71
77
|
end
|
72
78
|
|
73
|
-
def range (
|
74
|
-
indices = @reference.range(
|
79
|
+
def range (other, with_time: false)
|
80
|
+
indices = @reference.range(other)
|
75
81
|
return forward(*indices, with_time: with_time)
|
76
82
|
end
|
77
83
|
|
@@ -80,14 +86,5 @@ class TimeStep::Converter
|
|
80
86
|
return forward(*indices, with_time: with_time)
|
81
87
|
end
|
82
88
|
|
83
|
-
def valid? (*indices)
|
84
|
-
hash = {}
|
85
|
-
@pair.each do |name, conv|
|
86
|
-
hash[name] = conv.to.valid?(*conv.forward(*indices))
|
87
|
-
end
|
88
|
-
return hash
|
89
|
-
end
|
90
|
-
|
91
|
-
|
92
89
|
end
|
93
90
|
|
@@ -46,28 +46,18 @@ class TimeStep
|
|
46
46
|
#
|
47
47
|
# @return [Integer]
|
48
48
|
def difference_in_years (other)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
if self.year < other.year && self.compare_md(other) > 0
|
54
|
-
extra = 1
|
55
|
-
end
|
56
|
-
return self.year - other.year + extra
|
49
|
+
my = self
|
50
|
+
other = other.new_offset(self.offset)
|
51
|
+
return my.year - other.year + my.compare_md(other).quo(2)
|
57
52
|
end
|
58
53
|
|
59
54
|
# Calculate difference between the object and other object in months.
|
60
55
|
#
|
61
56
|
# @return [Integer]
|
62
57
|
def difference_in_months (other)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
67
|
-
if self.month < other.month && self.compare_d(other) > 0
|
68
|
-
extra = 1
|
69
|
-
end
|
70
|
-
return 12*(self.year - other.year) + self.month - other.month + extra
|
58
|
+
my = self
|
59
|
+
other = other.new_offset(self.offset)
|
60
|
+
return 12*(my.year - other.year) + my.month - other.month + my.compare_d(other).quo(2)
|
71
61
|
end
|
72
62
|
|
73
63
|
end
|
@@ -8,21 +8,19 @@ class TimeStep::Pair
|
|
8
8
|
# The `from` and `to` arguments are either TimeStep or a string representing
|
9
9
|
# the time step definition ("<INTERVAL> since <TIME>").
|
10
10
|
# If a string representing the time step definition is given as an argument
|
11
|
-
# `from` or `to`, the options `calendar`
|
11
|
+
# `from` or `to`, the options `calendar` are used to construct
|
12
12
|
# TimeStep. The option `calendar` specifies the calendar for datetime
|
13
|
-
# calculation.
|
14
|
-
# timestamp for negative year.
|
13
|
+
# calculation.
|
15
14
|
#
|
16
15
|
# @param from [TimeStep, String]
|
17
16
|
# @param to [TimeStep, String]
|
18
17
|
# @option calendar [String, TimeStep::Calendar]
|
19
|
-
# @option bc [Boolean]
|
20
18
|
#
|
21
|
-
def initialize (from, to, calendar: "standard"
|
19
|
+
def initialize (from, to, calendar: "standard")
|
22
20
|
|
23
21
|
case from
|
24
22
|
when String
|
25
|
-
@from = TimeStep.new(from, calendar: calendar
|
23
|
+
@from = TimeStep.new(from, calendar: calendar)
|
26
24
|
when TimeStep
|
27
25
|
@from = from
|
28
26
|
else
|
@@ -31,7 +29,7 @@ class TimeStep::Pair
|
|
31
29
|
|
32
30
|
case to
|
33
31
|
when String
|
34
|
-
@to = TimeStep.new(to, calendar: calendar
|
32
|
+
@to = TimeStep.new(to, calendar: calendar)
|
35
33
|
when TimeStep
|
36
34
|
@to = to
|
37
35
|
else
|
@@ -66,13 +64,17 @@ class TimeStep::Pair
|
|
66
64
|
"#<TimeStep::Pair from='#{from.inspect}' to='#{to.inspect}'>"
|
67
65
|
end
|
68
66
|
|
67
|
+
def invert
|
68
|
+
return TimeStep::Pair.new(@to, @from)
|
69
|
+
end
|
70
|
+
|
69
71
|
# Returns true if other has same contents of `from` and `to` as self has.
|
70
72
|
#
|
71
73
|
# @return [Boolean]
|
72
74
|
def == (other)
|
73
75
|
return @from == other.from && @to == other.to
|
74
76
|
end
|
75
|
-
|
77
|
+
|
76
78
|
# Returns the time represented by the given index as DateTime object
|
77
79
|
#
|
78
80
|
# @param indices [Numeric,Array<Numeric>]
|
@@ -85,10 +87,16 @@ class TimeStep::Pair
|
|
85
87
|
# Converts index refering `from` timestep to index refering `to`timestep.
|
86
88
|
#
|
87
89
|
def forward (*indices, &block)
|
88
|
-
if indices.size == 1
|
90
|
+
if indices.empty? || indices.size == 1 && indices.first.is_a?(Range)
|
91
|
+
return forward(*@from.range(*indices), &block)
|
92
|
+
elsif indices.size == 1
|
89
93
|
index = indices.first.to_r
|
90
94
|
if @numeric_conversion
|
91
|
-
|
95
|
+
if @to_interval == 0
|
96
|
+
value = 0
|
97
|
+
else
|
98
|
+
value = (index*@from_interval + @difference).quo(@to_interval)
|
99
|
+
end
|
92
100
|
else
|
93
101
|
case @from_symbol
|
94
102
|
when :years, :months
|
@@ -97,12 +105,14 @@ class TimeStep::Pair
|
|
97
105
|
target = @from_origin + index*(@from_interval.quo(86400))
|
98
106
|
end
|
99
107
|
case @to_symbol
|
100
|
-
when :years
|
101
|
-
|
108
|
+
when :years
|
109
|
+
diff = target.difference_in_years(@to_origin)
|
110
|
+
value = diff.quo(@to.numeric)
|
102
111
|
when :months
|
103
|
-
|
112
|
+
diff = target.difference_in_months(@to_origin)
|
113
|
+
value = diff.quo(@to.numeric)
|
104
114
|
else
|
105
|
-
value = (target.ajd - @to_origin.ajd).quo(@to_interval)
|
115
|
+
value = (target.ajd - @to_origin.ajd).quo(@to_interval)*86400
|
106
116
|
end
|
107
117
|
end
|
108
118
|
value = value.to_i if value.denominator == 1
|
@@ -126,18 +136,19 @@ class TimeStep::Pair
|
|
126
136
|
return forward(*indices) {|index| @to.time_at(index) }
|
127
137
|
end
|
128
138
|
|
129
|
-
def range (ge: nil, gt: nil, lt: nil, le: nil)
|
130
|
-
indices = @from.range(ge: ge, gt: gt, lt: lt, le: le)
|
131
|
-
return forward(*indices)
|
132
|
-
end
|
133
|
-
|
134
139
|
# Converts index refering `to` timestep to index refering `from` timestep.
|
135
140
|
#
|
136
141
|
def inverse (*indices, &block)
|
137
|
-
if indices.size == 1
|
142
|
+
if indices.empty? || indices.size == 1 && indices.first.is_a?(Range)
|
143
|
+
return inverse(*@to.range(*indices), &block)
|
144
|
+
elsif indices.size == 1
|
138
145
|
index = indices.first.to_r
|
139
146
|
if @numeric_conversion
|
140
|
-
|
147
|
+
if @from_interval == 0
|
148
|
+
value = 0
|
149
|
+
else
|
150
|
+
value = (index*@to_interval - @difference).quo(@from_interval)
|
151
|
+
end
|
141
152
|
else
|
142
153
|
case @to_symbol
|
143
154
|
when :years, :months
|
@@ -147,11 +158,13 @@ class TimeStep::Pair
|
|
147
158
|
end
|
148
159
|
case @from_symbol
|
149
160
|
when :years
|
150
|
-
|
161
|
+
diff = target.difference_in_years(@from_origin)
|
162
|
+
value = diff.quo(@from.numeric)
|
151
163
|
when :months
|
152
|
-
|
164
|
+
diff = target.difference_in_months(@from_origin)
|
165
|
+
value = diff.quo(@from.numeric)
|
153
166
|
else
|
154
|
-
value = (target.ajd - @from_origin.ajd).quo(@from_interval)
|
167
|
+
value = (target.ajd - @from_origin.ajd).quo(@from_interval)*86400
|
155
168
|
end
|
156
169
|
end
|
157
170
|
value = value.to_i if value.denominator == 1
|
@@ -4,11 +4,11 @@ class TimeStep::Query
|
|
4
4
|
|
5
5
|
def initialize (timestep, format: nil)
|
6
6
|
@timestep = timestep
|
7
|
-
@format =
|
7
|
+
@format = format
|
8
8
|
end
|
9
9
|
|
10
10
|
def __format__ (time)
|
11
|
-
return ( @
|
11
|
+
return ( @format.nil? ) ? time : time.strftime(@format)
|
12
12
|
end
|
13
13
|
|
14
14
|
private :__format__
|
@@ -19,7 +19,7 @@ class TimeStep::Query
|
|
19
19
|
|
20
20
|
def just_before_time_of (time)
|
21
21
|
idx = @timestep.index_at(time)
|
22
|
-
if idx.
|
22
|
+
if idx.denominator == 1
|
23
23
|
time0 = time
|
24
24
|
else
|
25
25
|
time0 = @timestep.time_at(idx.floor)
|
@@ -29,7 +29,7 @@ class TimeStep::Query
|
|
29
29
|
|
30
30
|
def just_after_time_of (time)
|
31
31
|
idx = @timestep.index_at(time)
|
32
|
-
if idx.
|
32
|
+
if idx.denominator == 1
|
33
33
|
time0 = time
|
34
34
|
else
|
35
35
|
time0 = @timestep.time_at(idx.ceil)
|
@@ -47,3 +47,11 @@ class TimeStep::Query
|
|
47
47
|
|
48
48
|
end
|
49
49
|
|
50
|
+
class TimeStep
|
51
|
+
|
52
|
+
def query (format = nil)
|
53
|
+
return TimeStep::Query.new(self, format: format)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
class TimeStep::Range
|
4
|
+
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize (timestep, start = nil, last = nil, count: nil, ends: "[]")
|
8
|
+
|
9
|
+
raise "'ends' option should be one of '[]', '()', '(]', '[)" unless ends =~ /\A[\[\(][\]\)]\z/
|
10
|
+
include_start = ends[0] == "["
|
11
|
+
include_last = ends[1] == "]"
|
12
|
+
|
13
|
+
if last
|
14
|
+
case start
|
15
|
+
when Numeric
|
16
|
+
when Time
|
17
|
+
start = timestep.index_at(start.to_datetime)
|
18
|
+
when DateTime, DateTimeLike, String
|
19
|
+
start = timestep.index_at(start)
|
20
|
+
else
|
21
|
+
raise "unknown type of argument"
|
22
|
+
end
|
23
|
+
case last
|
24
|
+
when Numeric
|
25
|
+
when Time
|
26
|
+
last = timestep.index_at(last.to_datetime)
|
27
|
+
when DateTime, DateTimeLike, String
|
28
|
+
last = timestep.index_at(last)
|
29
|
+
else
|
30
|
+
raise "unknown argument"
|
31
|
+
end
|
32
|
+
else
|
33
|
+
case start
|
34
|
+
when Integer
|
35
|
+
count = start
|
36
|
+
start = 0
|
37
|
+
last = count - 1
|
38
|
+
when String
|
39
|
+
raise "count should be set" unless count.is_a?(Integer)
|
40
|
+
start = timestep.index_at(start)
|
41
|
+
last = start + count - 1
|
42
|
+
when TimePeriod
|
43
|
+
period = range
|
44
|
+
return initialize(timestep, period.origin..period.last, ends: period.ends)
|
45
|
+
else
|
46
|
+
raise "unknown argument"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if include_start
|
51
|
+
start = start.ceil
|
52
|
+
else
|
53
|
+
start = start.floor + 1
|
54
|
+
end
|
55
|
+
|
56
|
+
if include_last
|
57
|
+
last = last.floor
|
58
|
+
else
|
59
|
+
last = last.ceil - 1
|
60
|
+
end
|
61
|
+
|
62
|
+
@timestep = timestep.new_origin(timestep.time_at(start))
|
63
|
+
@start_time = timestep.time_at(start)
|
64
|
+
@last_time = timestep.time_at(last)
|
65
|
+
|
66
|
+
@start = @timestep.index_at(@start_time)
|
67
|
+
@last = @timestep.index_at(@last_time)
|
68
|
+
@count = @last - @start + 1
|
69
|
+
end
|
70
|
+
|
71
|
+
attr_reader :timestep, :count, :start, :last, :start_time, :last_time
|
72
|
+
|
73
|
+
def_delegators :@timestep, :numeric, :symbol, :interval,
|
74
|
+
:origin, :offset, :calendar, :definition,
|
75
|
+
:parse, :time_at, :index_at, :duration_at, :[]
|
76
|
+
|
77
|
+
|
78
|
+
# FIXME
|
79
|
+
def valid? (*indices)
|
80
|
+
if @count
|
81
|
+
if indices.size == 1
|
82
|
+
index = indices.first
|
83
|
+
if index >= 0 and index < @count
|
84
|
+
return true
|
85
|
+
else
|
86
|
+
return false
|
87
|
+
end
|
88
|
+
else
|
89
|
+
return indices.map{|index| valid?(index) }
|
90
|
+
end
|
91
|
+
else
|
92
|
+
if indices.size == 1
|
93
|
+
return true
|
94
|
+
else
|
95
|
+
return indices.map{|index| true }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns TimeStep object which has origin time determined
|
101
|
+
# by the given `index`.
|
102
|
+
#
|
103
|
+
# @param index [Numeric]
|
104
|
+
#
|
105
|
+
# @return [TimeStep]
|
106
|
+
def shift_origin (index)
|
107
|
+
case with
|
108
|
+
when :index, "index"
|
109
|
+
timestep = @timestep.shift_origin(index)
|
110
|
+
return TimeStep::Range.new(timestep, count: @count)
|
111
|
+
when :duration, "duration", :days, "days"
|
112
|
+
timestep = @timestep.shift_origin(index, with: "duration")
|
113
|
+
return TimeStep::Range.new(timestep, count: @count)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns TimeStep object which has origin time specified
|
118
|
+
# by the given `time`.
|
119
|
+
#
|
120
|
+
# @param time [DateTime]
|
121
|
+
#
|
122
|
+
# @return [TimeStep]
|
123
|
+
def new_origin (time, truncate: false)
|
124
|
+
timestep = @timestep.new_origin(time, truncate: truncate)
|
125
|
+
return TimeStep::Range.new(timestep, count: @count)
|
126
|
+
end
|
127
|
+
|
128
|
+
include Enumerable
|
129
|
+
|
130
|
+
def each_time (&block)
|
131
|
+
if block
|
132
|
+
(@start..@last).each do |k|
|
133
|
+
block.call(@timestep.time_at(k))
|
134
|
+
end
|
135
|
+
else
|
136
|
+
return Enumerator.new {|y|
|
137
|
+
(@start..@last).each do |k|
|
138
|
+
y << @timestep.time_at(k)
|
139
|
+
end
|
140
|
+
}
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
alias each each_time
|
145
|
+
|
146
|
+
def each_index (&block)
|
147
|
+
(@start..@last).each(&block)
|
148
|
+
end
|
149
|
+
|
150
|
+
def map_index (&block)
|
151
|
+
(@start..@last).map(&block)
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
data/lib/timesteps.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
require "date"
|
3
|
+
require "timesteps/time"
|
3
4
|
require "timesteps/datetimelike"
|
4
5
|
require "timesteps/datetimelike_format"
|
5
6
|
require "timesteps/datetime_noleap"
|
@@ -12,3 +13,6 @@ require "timesteps/timestep"
|
|
12
13
|
require "timesteps/timestep_pair"
|
13
14
|
require "timesteps/timestep_converter"
|
14
15
|
require "timesteps/timeperiod"
|
16
|
+
require "timesteps/timestep_range"
|
17
|
+
require "timesteps/datetime_timestep"
|
18
|
+
require "timesteps/timestep_query"
|
data/spec/allleap_spec.rb
CHANGED
@@ -123,17 +123,6 @@ describe "AllLeap.parse_timestamp" do
|
|
123
123
|
|
124
124
|
end
|
125
125
|
|
126
|
-
example "with bc option" do
|
127
|
-
|
128
|
-
d1 = DateTime::AllLeap.new(0, 1, 1, 0, 0, 0, 0)
|
129
|
-
d2 = DateTime.parse_timestamp('BC 0001-1-1 00:00:00', calendar: "allleap")
|
130
|
-
d3 = DateTime.parse_timestamp('-0001-1-1 00:00:00', calendar: "allleap", bc: true)
|
131
|
-
|
132
|
-
is_asserted_by { d2 == d1 }
|
133
|
-
is_asserted_by { d3 == d1 }
|
134
|
-
|
135
|
-
end
|
136
|
-
|
137
126
|
example '2000-12-31 24:00:00' do
|
138
127
|
|
139
128
|
d1 = DateTime::AllLeap.new(2001, 1, 1, 0, 0, 0, 0)
|
@@ -301,8 +290,8 @@ describe "AllLeap#difference_in_years" do
|
|
301
290
|
d3 = DateTime::AllLeap.new(2002, 3, 5, 9, 35, 11.5, 9.quo(24))
|
302
291
|
d4 = DateTime::AllLeap.new(2002, 3, 5, 9, 35, 12.5, 9.quo(24))
|
303
292
|
|
304
|
-
is_asserted_by { d2.difference_in_years(d1) ==
|
305
|
-
is_asserted_by { d3.difference_in_years(d1) ==
|
293
|
+
is_asserted_by { d2.difference_in_years(d1) == 1.quo(2) }
|
294
|
+
is_asserted_by { d3.difference_in_years(d1) == 1.quo(2) }
|
306
295
|
is_asserted_by { d4.difference_in_years(d1) == 1 }
|
307
296
|
|
308
297
|
end
|
@@ -319,8 +308,8 @@ describe "AllLeap#difference_in_months" do
|
|
319
308
|
d4 = DateTime::AllLeap.new(2001, 4, 5, 9, 35, 12.5, 9.quo(24))
|
320
309
|
d5 = DateTime::AllLeap.new(2002, 3, 5, 9, 35, 12.5, 9.quo(24))
|
321
310
|
|
322
|
-
is_asserted_by { d2.difference_in_months(d1) ==
|
323
|
-
is_asserted_by { d3.difference_in_months(d1) ==
|
311
|
+
is_asserted_by { d2.difference_in_months(d1) == 1.quo(2) }
|
312
|
+
is_asserted_by { d3.difference_in_months(d1) == 1.quo(2) }
|
324
313
|
is_asserted_by { d4.difference_in_months(d1) == 1 }
|
325
314
|
is_asserted_by { d5.difference_in_months(d1) == 12 }
|
326
315
|
|
data/spec/fixed360day_spec.rb
CHANGED
@@ -133,17 +133,6 @@ describe "Fixed360Day.parse_timestamp" do
|
|
133
133
|
|
134
134
|
end
|
135
135
|
|
136
|
-
example "with bc option" do
|
137
|
-
|
138
|
-
d1 = DateTime::Fixed360Day.new(0, 1, 1, 0, 0, 0, 0)
|
139
|
-
d2 = DateTime.parse_timestamp('BC 0001-1-1 00:00:00', calendar: "360_day")
|
140
|
-
d3 = DateTime.parse_timestamp('-0001-1-1 00:00:00', calendar: "360_day", bc: true)
|
141
|
-
|
142
|
-
is_asserted_by { d2 == d1 }
|
143
|
-
is_asserted_by { d3 == d1 }
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
136
|
example '2000-12-31 24:00:00' do
|
148
137
|
|
149
138
|
d1 = DateTime::Fixed360Day.new(2001, 1, 1, 0, 0, 0, 0)
|
@@ -312,8 +301,8 @@ describe "Fixed360Day#difference_in_years" do
|
|
312
301
|
d3 = DateTime::Fixed360Day.new(2002, 3, 5, 9, 35, 11.5, 9.quo(24))
|
313
302
|
d4 = DateTime::Fixed360Day.new(2002, 3, 5, 9, 35, 12.5, 9.quo(24))
|
314
303
|
|
315
|
-
is_asserted_by { d2.difference_in_years(d1) ==
|
316
|
-
is_asserted_by { d3.difference_in_years(d1) ==
|
304
|
+
is_asserted_by { d2.difference_in_years(d1) == 1.quo(2) }
|
305
|
+
is_asserted_by { d3.difference_in_years(d1) == 1.quo(2) }
|
317
306
|
is_asserted_by { d4.difference_in_years(d1) == 1 }
|
318
307
|
|
319
308
|
end
|
@@ -330,8 +319,8 @@ describe "Fixed360Day#difference_in_months" do
|
|
330
319
|
d4 = DateTime::Fixed360Day.new(2001, 4, 5, 9, 35, 12.5, 9.quo(24))
|
331
320
|
d5 = DateTime::Fixed360Day.new(2002, 3, 5, 9, 35, 12.5, 9.quo(24))
|
332
321
|
|
333
|
-
is_asserted_by { d2.difference_in_months(d1) ==
|
334
|
-
is_asserted_by { d3.difference_in_months(d1) ==
|
322
|
+
is_asserted_by { d2.difference_in_months(d1) == 1.quo(2) }
|
323
|
+
is_asserted_by { d3.difference_in_months(d1) == 1.quo(2) }
|
335
324
|
is_asserted_by { d4.difference_in_months(d1) == 1 }
|
336
325
|
is_asserted_by { d5.difference_in_months(d1) == 12 }
|
337
326
|
|