timesteps 0.9.6 → 0.9.7
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/Note.ja.md +9 -0
- data/README.md +5 -5
- data/lib/timesteps.rb +2 -0
- 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/timeperiod.rb +50 -47
- data/lib/timesteps/timestep.rb +477 -247
- 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_range.rb +150 -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 +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bac0d24992c8693974390e294212ee592b8b1974486d8ffe95704550810ade9e
|
4
|
+
data.tar.gz: e1da906f7b7e7adc85e597dfc14dc8229ff3625f2be3652c599f56a476a10e95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e1b74b4052d4c16d2c4538c98f7328591a317494c6937a7a48d09c751037693d4235cd4a6cf73fb24f993f8a6d35a24cbcef0f4862b6b7e31ec965e552f725
|
7
|
+
data.tar.gz: c7beea6d38d54bfda596c8f5ea4b77f8ebc68660bc3cf1d7fe7c2305a6a63a7966a925caa8b579538010e14cee370934f7c68a115276a9c64b67d04fa0a69dc5
|
data/Note.ja.md
CHANGED
data/README.md
CHANGED
@@ -58,9 +58,9 @@ ts.index_at("2001-01-02 00:00:00") ### => 8
|
|
58
58
|
ts.time_at(0) ### => #<DateTime 2001-01-01T00:00:00 ...>
|
59
59
|
ts.time_at(1) ### => #<DateTime 2001-01-01T03:00:00 ...>
|
60
60
|
ts.time_at(8) ### => #<DateTime 2001-01-02T00:00:00 ...>
|
61
|
-
ts.
|
62
|
-
ts.
|
63
|
-
ts.
|
61
|
+
ts.duration_at(0) ### => 0 [Integer]
|
62
|
+
ts.duration_at(1) ### => (1/8) [Rational]
|
63
|
+
ts.duration_at(8) ### => 1 [Integer]
|
64
64
|
```
|
65
65
|
|
66
66
|
#### Treatment of year and month units
|
@@ -137,14 +137,14 @@ ts = TimeStep.new("days since 2001-01-01", calendar: "allleap")
|
|
137
137
|
ts.parse("2001-02-29") ### => #<DateTime::AllLeap 2001-02-29T ...>
|
138
138
|
```
|
139
139
|
|
140
|
-
In the UDUNITS library, negative years are treated as BCs, and A.D. 0 is treated as non-existent. This is different from how it is handled in Ruby's DateTime class.
|
140
|
+
In the UDUNITS library, negative years are treated as BCs, and A.D. 0 is treated as non-existent. This is different from how it is handled in Ruby's DateTime class.
|
141
141
|
|
142
142
|
```ruby
|
143
143
|
DateTime.parse_timestamp("-0001-01-01")
|
144
144
|
# => #<DateTime: -0001-01-01T00:00:00+00:00 ...>
|
145
145
|
# B.C. 2
|
146
146
|
|
147
|
-
DateTime.parse_timestamp("-
|
147
|
+
DateTime.parse_timestamp("0000-01-01")
|
148
148
|
# => #<DateTime: 0000-01-01T00:00:00+00:00 ...>
|
149
149
|
# B.C. 1
|
150
150
|
|
data/lib/timesteps.rb
CHANGED
@@ -11,11 +11,10 @@ class DateTime
|
|
11
11
|
# `DateTime._parse()` is called internally.
|
12
12
|
#
|
13
13
|
# @param spec [String]
|
14
|
-
# @option bc [Boolean]
|
15
14
|
#
|
16
15
|
# @return [DateTimeFixedDPY]
|
17
16
|
|
18
|
-
def self.parse_timestamp (spec, calendar: "standard",
|
17
|
+
def self.parse_timestamp (spec, format: nil, offset: nil, calendar: "standard", tz: nil)
|
19
18
|
case calendar.downcase.intern
|
20
19
|
when :standard, :gregorian
|
21
20
|
klass = DateTime
|
@@ -40,27 +39,37 @@ class DateTime
|
|
40
39
|
hash = DateTime._strptime(spec, format)
|
41
40
|
raise "date-time string '#{spec}' doesn't match with the given format '#{format}'" unless hash
|
42
41
|
else
|
43
|
-
if spec =~ /\A([+\-]?\d{4})(\-(\d{1,2}))?\z/
|
44
|
-
|
42
|
+
if spec =~ /\A([+\-]?\d{1,4})(\-(\d{1,2}))?(\s+(\w{3}|[+\-]\d{1,2}(:?\d{1,2})))?\z/
|
43
|
+
year = $1.to_i
|
44
|
+
month = $3 ? $3.to_i : 1
|
45
|
+
mday = 1
|
46
|
+
rest = $4
|
47
|
+
hash = DateTime._parse("#{year}-#{month}-#{mday} 00:00:00 #{rest}")
|
45
48
|
else
|
46
49
|
hash = DateTime._parse(spec)
|
47
50
|
end
|
48
51
|
end
|
49
|
-
year, month, day, hour, minute, second, sec_fraction,
|
52
|
+
year, month, day, hour, minute, second, sec_fraction, offset_ =
|
50
53
|
hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset)
|
51
|
-
if bc and year < 0
|
52
|
-
year = year + 1
|
53
|
-
end
|
54
54
|
hour ||= 0
|
55
55
|
minute ||= 0
|
56
56
|
second ||= 0.0
|
57
57
|
sec_fraction ||= 0.0
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
if offset_
|
59
|
+
offset = offset_.quo(86400)
|
60
|
+
else
|
61
|
+
offset ||= 0
|
62
|
+
end
|
63
|
+
if tz
|
64
|
+
time = tz.local_datetime(year, month, day, hour, minute, second.to_i, sec_fraction.to_r)
|
61
65
|
else
|
62
|
-
|
66
|
+
if hour == 24 && minute == 0 && second == 0.0
|
67
|
+
time = klass.new(year, month, day, 23, minute, second + sec_fraction, offset, start) + 1.quo(24)
|
68
|
+
else
|
69
|
+
time = klass.new(year, month, day, hour, minute, second + sec_fraction, offset, start)
|
70
|
+
end
|
63
71
|
end
|
72
|
+
return time
|
64
73
|
end
|
65
74
|
|
66
75
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
class DateTime
|
3
|
+
|
4
|
+
def timestep (interval_spec, tz: nil)
|
5
|
+
case start
|
6
|
+
when Date::ITALY
|
7
|
+
calendar = "standard"
|
8
|
+
when Date::GREGORIAN
|
9
|
+
calendar = "proleptic_gregorian"
|
10
|
+
when Date::JULIAN
|
11
|
+
calendar = "proleptic_julian"
|
12
|
+
end
|
13
|
+
return TimeStep.new(interval_spec, since: self, calendar: calendar, tz: tz)
|
14
|
+
end
|
15
|
+
|
16
|
+
def timeperiod (interval_spec, tz: nil, ends: "[]")
|
17
|
+
case start
|
18
|
+
when Date::ITALY
|
19
|
+
calendar = "standard"
|
20
|
+
when Date::GREGORIAN
|
21
|
+
calendar = "proleptic_gregorian"
|
22
|
+
when Date::JULIAN
|
23
|
+
calendar = "proleptic_julian"
|
24
|
+
end
|
25
|
+
return TimePeriod.new(interval_spec, since: self, calendar: calendar, ends: ends, tz: tz)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
class DateTime::NoLeap
|
31
|
+
|
32
|
+
def timestep (interval_spec, tz: nil)
|
33
|
+
return TimeStep.new(interval_spec, since: self, clanedar: "noleap", tz: tz)
|
34
|
+
end
|
35
|
+
|
36
|
+
def timeperiod (interval_spec, tz: nil, ends: "[]")
|
37
|
+
return TimePeriod.new(interval_spec, since: self, calendar: "noleap", ends: ends, tz: tz)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class DateTime::AllLeap
|
43
|
+
|
44
|
+
def timestep (interval_spec, tz: nil)
|
45
|
+
return TimeStep.new(interval_spec, since: self, clanedar: "allleap", tz: tz)
|
46
|
+
end
|
47
|
+
|
48
|
+
def timeperiod (interval_spec, tz: nil, ends: "[]")
|
49
|
+
return TimePeriod.new(interval_spec, since: self, calendar: "allleap", ends: ends, tz: tz)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
class DateTime::Fixed360Day
|
55
|
+
|
56
|
+
def timestep (interval_spec, tz: nil)
|
57
|
+
return TimeStep.new(interval_spec, since: self, clanedar: "360day", tz: tz)
|
58
|
+
end
|
59
|
+
|
60
|
+
def timeperiod (interval_spec, tz: nil, ends: "[]")
|
61
|
+
return TimePeriod.new(interval_spec, since: self, calendar: "360day", ends: ends, tz: tz)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -398,29 +398,18 @@ class DateTimeLike
|
|
398
398
|
#
|
399
399
|
# @return [Integer]
|
400
400
|
def difference_in_years (other)
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
end
|
405
|
-
if self.year < other.year && self.compare_md(other) > 0
|
406
|
-
extra = 1
|
407
|
-
end
|
408
|
-
return self.year - other.year + extra
|
401
|
+
my = self.new_offset(0)
|
402
|
+
other = other.new_offset(0)
|
403
|
+
return my.year - other.year + my.compare_md(other).quo(2)
|
409
404
|
end
|
410
405
|
|
411
406
|
# Calculate difference between the object and other object in months.
|
412
407
|
#
|
413
408
|
# @return [Integer]
|
414
409
|
def difference_in_months (other)
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
end
|
419
|
-
if self.month < other.month && self.compare_d(other) > 0
|
420
|
-
extra = 1
|
421
|
-
end
|
422
|
-
return 12*(self.year - other.year) + self.month - other.month + extra
|
410
|
+
my = self.new_offset(0)
|
411
|
+
other = other.new_offset(0)
|
412
|
+
return 12*(my.year - other.year) + my.month - other.month + my.compare_d(other).quo(2)
|
423
413
|
end
|
424
|
-
|
425
414
|
end
|
426
415
|
|
data/lib/timesteps/grads.rb
CHANGED
@@ -1,6 +1,24 @@
|
|
1
|
-
|
1
|
+
require "timesteps"
|
2
2
|
|
3
|
-
class
|
3
|
+
class DateTime
|
4
|
+
|
5
|
+
def self.parse_grads_time (time_string)
|
6
|
+
if time_string.strip =~ /\A(((\d{2})?(:(\d{2}))?Z)?(\d{2}))?(\w{3})(\d{4})\z/i
|
7
|
+
hour = $3 || "00"
|
8
|
+
min = $5 || "00"
|
9
|
+
day = $6 || "01"
|
10
|
+
mon = $7
|
11
|
+
year = $8
|
12
|
+
time = DateTime.parse("#{year}#{mon}#{day} #{hour}:#{min}:00")
|
13
|
+
else
|
14
|
+
raise "invalid time format"
|
15
|
+
end
|
16
|
+
return time
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
class TimeStep::Range
|
4
22
|
|
5
23
|
# @private
|
6
24
|
REGEXP_GRADS_TDEF = /\A(?:TDEF\s+)?(\d+)\s+LINEAR\s+([^\s]*?)\s+([^\s]*?)\s*\z/i
|
@@ -13,8 +31,17 @@ class TimeStep
|
|
13
31
|
"mo" => "months",
|
14
32
|
"yr" => "years",
|
15
33
|
}
|
16
|
-
|
17
|
-
|
34
|
+
|
35
|
+
module GrADSMixin
|
36
|
+
|
37
|
+
def parse_grads_time (time_string)
|
38
|
+
return DateTime.parse_grads_time(time_string)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.from_grads_tdef (tdef_string)
|
44
|
+
|
18
45
|
if tdef_string.strip =~ REGEXP_GRADS_TDEF
|
19
46
|
count = $1.to_i
|
20
47
|
time = $2
|
@@ -22,22 +49,16 @@ class TimeStep
|
|
22
49
|
else
|
23
50
|
raise "invalid grads tdef string"
|
24
51
|
end
|
25
|
-
|
26
|
-
|
27
|
-
min = $5 || "00"
|
28
|
-
day = $6 || "01"
|
29
|
-
mon = $7
|
30
|
-
year = $8
|
31
|
-
origin = DateTime.parse("#{year}#{mon}#{day} #{hour}:#{min}:00")
|
32
|
-
else
|
33
|
-
raise "invalid time format"
|
34
|
-
end
|
52
|
+
|
53
|
+
origin = DateTime.parse_grads_time(time)
|
35
54
|
|
36
55
|
increment = increment.sub(/(mn|hr|dy|mo|yr)/i) {|s| GRADS_INCREMENT[s.downcase]}
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
56
|
+
|
57
|
+
range = TimeStep.new(increment, since: origin).range(count)
|
58
|
+
range.extend GrADSMixin
|
59
|
+
|
60
|
+
return range
|
41
61
|
end
|
42
62
|
|
63
|
+
|
43
64
|
end
|
data/lib/timesteps/timeperiod.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
|
2
|
+
|
2
3
|
class TimePeriod < TimeStep
|
3
|
-
|
4
|
-
def initialize (spec, since: nil, format: nil, calendar: "standard",
|
5
|
-
super(spec, since: since, format: format,
|
6
|
-
raise "invalid
|
7
|
-
@
|
8
|
-
@include_start = (
|
9
|
-
@include_last = (
|
4
|
+
|
5
|
+
def initialize (spec, since: nil, format: nil, offset: nil, calendar: "standard", tz: nil, ends: "[]" )
|
6
|
+
super(spec, since: since, format: format, offset: offset, calendar: calendar, tz: tz)
|
7
|
+
raise "invalid ends specification" unless ends =~ /\A[\[\(][\]\)]\z/
|
8
|
+
@ends = ends
|
9
|
+
@include_start = ( ends[0] == "[" ) ? true : false
|
10
|
+
@include_last = ( ends[1] == "]" ) ? true : false
|
10
11
|
@last = time_at(1)
|
11
12
|
end
|
12
13
|
|
13
|
-
attr_reader :last
|
14
|
+
attr_reader :last, :ends
|
14
15
|
|
15
16
|
def start
|
16
17
|
return @origin
|
@@ -27,40 +28,40 @@ class TimePeriod < TimeStep
|
|
27
28
|
# Returns the value as a string for inspection.
|
28
29
|
#
|
29
30
|
def inspect
|
31
|
+
options = ""
|
32
|
+
case @calendar.name
|
33
|
+
when "standard", "gregorian"
|
34
|
+
else
|
35
|
+
options << " calendar='#{calendar.name}'"
|
36
|
+
end
|
30
37
|
left_paren = @include_start ? "[" : "("
|
31
38
|
right_paren = @include_last ? "]" : ")"
|
32
|
-
"#<TimePeriod '#{interval_spec}' #{left_paren}#{start.to_s}, #{last.to_s}#{right_paren}
|
33
|
-
end
|
34
|
-
|
35
|
-
def boundary
|
36
|
-
left_paren = @include_start ? "[" : "("
|
37
|
-
right_paren = @include_last ? "]" : ")"
|
38
|
-
return left_paren + right_paren
|
39
|
+
"#<TimePeriod '#{interval_spec}' #{left_paren}#{start.to_s}, #{last.to_s}#{right_paren} #{options}>"
|
39
40
|
end
|
40
41
|
|
41
42
|
def include? (other)
|
42
43
|
case other
|
43
44
|
when TimePeriod
|
44
45
|
if ( other.origin < @origin ) ||
|
45
|
-
( other.origin == @origin && ( not include_start
|
46
|
+
( other.origin == @origin && ( not @include_start ) && other.include_start? )
|
46
47
|
left = false
|
47
48
|
else
|
48
49
|
left = true
|
49
50
|
end
|
50
51
|
if ( @last < other.last ) ||
|
51
|
-
( @last == other.last && ( not include_last
|
52
|
+
( @last == other.last && ( not @include_last ) && other.include_last? )
|
52
53
|
right = false
|
53
54
|
else
|
54
55
|
right = true
|
55
56
|
end
|
56
57
|
return left & right
|
57
58
|
else
|
58
|
-
if include_start
|
59
|
+
if @include_start
|
59
60
|
left = @origin <= other
|
60
61
|
else
|
61
62
|
left = @origin < other
|
62
63
|
end
|
63
|
-
if include_last
|
64
|
+
if @include_last
|
64
65
|
right = other <= @last
|
65
66
|
else
|
66
67
|
right = other < @last
|
@@ -73,13 +74,13 @@ class TimePeriod < TimeStep
|
|
73
74
|
case other
|
74
75
|
when TimePeriod
|
75
76
|
if ( @origin < other.last ) ||
|
76
|
-
( @origin == other.last && include_start
|
77
|
+
( @origin == other.last && @include_start && other.include_last? )
|
77
78
|
left = true
|
78
79
|
else
|
79
80
|
left = false
|
80
81
|
end
|
81
82
|
if ( other.origin < @last ) ||
|
82
|
-
( other.origin == @last && include_last
|
83
|
+
( other.origin == @last && @include_last && other.include_start? )
|
83
84
|
right = true
|
84
85
|
else
|
85
86
|
right = false
|
@@ -116,26 +117,26 @@ class TimePeriod < TimeStep
|
|
116
117
|
if ( other.origin < @origin ) ||
|
117
118
|
( other.origin == @origin && ( not include_start? ) && other.include_start? )
|
118
119
|
left = other.origin
|
119
|
-
|
120
|
+
left_end = other.include_start? ? "[" : "("
|
120
121
|
else
|
121
122
|
left = @origin
|
122
|
-
|
123
|
+
left_end = include_start? ? "[" : "("
|
123
124
|
end
|
124
125
|
if ( @last < other.last ) ||
|
125
126
|
( @last == other.last && ( not include_last? ) && other.include_last? )
|
126
127
|
right = other.last
|
127
|
-
|
128
|
+
right_end = other.include_last? ? "]" : ")"
|
128
129
|
else
|
129
130
|
right = @last
|
130
|
-
|
131
|
+
right_end = include_last? ? ")" : "]"
|
131
132
|
end
|
132
133
|
ridx = index_at(right)
|
133
134
|
lidx = index_at(left)
|
134
135
|
numeric = (ridx - lidx) * @numeric
|
135
136
|
origin = left
|
136
137
|
interval_spec = format("%g %s", numeric, @symbol)
|
137
|
-
|
138
|
-
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar
|
138
|
+
ends = left_end + right_end
|
139
|
+
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar, ends: ends)
|
139
140
|
end
|
140
141
|
|
141
142
|
def clip (other)
|
@@ -143,60 +144,62 @@ class TimePeriod < TimeStep
|
|
143
144
|
if ( @origin < other.origin ) ||
|
144
145
|
( @origin == other.origin && include_start? && ( not other.include_start? ) )
|
145
146
|
left = other.origin
|
146
|
-
|
147
|
+
left_end = other.include_start? ? "[" : "("
|
147
148
|
else
|
148
149
|
left = @origin
|
149
|
-
|
150
|
+
left_end = include_start? ? "[" : "("
|
150
151
|
end
|
151
152
|
if ( other.last < @last ) ||
|
152
153
|
( other.last == @last && include_last? && ( not other.include_last? ) )
|
153
154
|
right = other.last
|
154
|
-
|
155
|
+
right_end = other.include_last? ? "]" : ")"
|
155
156
|
else
|
156
157
|
right = @last
|
157
|
-
|
158
|
+
right_end = include_last? ? ")" : "]"
|
158
159
|
end
|
159
160
|
ridx = index_at(right)
|
160
161
|
lidx = index_at(left)
|
161
162
|
numeric = (ridx - lidx) * @numeric
|
162
163
|
origin = left
|
163
164
|
interval_spec = format("%g %s", numeric, @symbol)
|
164
|
-
|
165
|
-
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar
|
165
|
+
ends = left_end + right_end
|
166
|
+
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar, ends: ends)
|
166
167
|
end
|
167
168
|
|
168
|
-
def split (time,
|
169
|
+
def split (time, ends: ")[")
|
169
170
|
raise "can't split period without contacted time" unless contact?(time)
|
170
171
|
# left
|
171
172
|
numeric = index_at(time) * @numeric
|
172
173
|
interval_spec = format("%g %s", numeric, @symbol)
|
173
|
-
|
174
|
-
left_period = TimePeriod.new(interval_spec, since: @origin, calendar: @calendar
|
174
|
+
ends = (@include_start ? "[" : "(") + ends[0]
|
175
|
+
left_period = TimePeriod.new(interval_spec, since: @origin, calendar: @calendar, ends: ends)
|
175
176
|
# right
|
176
177
|
numeric = (1 - index_at(time)) * @numeric
|
177
178
|
interval_spec = format("%g %s", numeric, @symbol)
|
178
|
-
|
179
|
-
right_period = TimePeriod.new(interval_spec, since: @origin, calendar: @calendar
|
179
|
+
ends = ends[1] + (@include_last ? "]" : ")")
|
180
|
+
right_period = TimePeriod.new(interval_spec, since: @origin, calendar: @calendar, ends: ends)
|
180
181
|
return left_period, right_period
|
181
182
|
end
|
182
183
|
|
183
184
|
def next
|
184
|
-
return TimePeriod.new(interval_spec, since: @last, calendar: @calendar
|
185
|
+
return TimePeriod.new(interval_spec, since: @last, calendar: @calendar, ends: ends)
|
185
186
|
end
|
186
187
|
|
187
188
|
def prev
|
188
189
|
origin = index_at(-1)
|
189
|
-
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar
|
190
|
+
return TimePeriod.new(interval_spec, since: origin, calendar: @calendar, ends: ends)
|
190
191
|
end
|
191
192
|
|
192
|
-
def
|
193
|
-
|
194
|
-
|
193
|
+
def shift_origin (index, with: "index")
|
194
|
+
case with
|
195
|
+
when :index, "index"
|
196
|
+
return TimePeriod.new(interval_spec, since: time_at(index), calendar: @calendar, ends: ends)
|
197
|
+
when :duration, "duration", :days, "days"
|
198
|
+
time = @origin + index
|
199
|
+
return TimePeriod.new(interval_spec, since: time, calendar: @calendar, ends: ends)
|
200
|
+
end
|
195
201
|
|
196
|
-
def shift_with_duration (duration)
|
197
|
-
time = @origin + duration
|
198
|
-
return TimePeriod.new(interval_spec, since: time, calendar: @calendar.name, bc: @calendar.bc?, boundary: boundary)
|
199
202
|
end
|
200
|
-
|
203
|
+
|
201
204
|
end
|
202
205
|
|