timesteps 0.9.7 → 1.0.2
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 +14 -0
- data/Note.ja.md +0 -2
- data/README.md +15 -3
- data/lib/timesteps/datetime_timestep.rb +28 -0
- data/lib/timesteps/time.rb +14 -0
- data/lib/timesteps/timestep.rb +18 -2
- data/lib/timesteps/timestep_query.rb +12 -4
- data/lib/timesteps/timestep_range.rb +27 -22
- data/lib/timesteps.rb +2 -0
- data/spec/timestep_spec.rb +13 -0
- data/timesteps.gemspec +3 -3
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6700d400608b814af5cd0fcc0136f8ef717a6e26939a1d91cf37abf65a7afa94
|
4
|
+
data.tar.gz: 3c34321b6468f3136732a3b6e16137486f6fcb1710049e07d208a663048b0730
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc989ec56ef1812a6d8afc2e4e6d6b70b6b67d6490a88a5db5a38eb3942a80ba28fb61c968f29242dc562b039524943ec6fadd43adfd57c70a1b2b80880c378b
|
7
|
+
data.tar.gz: bcfcf00eeb435e11d9a4fbc7366050f048acb1478c46cbdb9bc40175dabf32b80ba0777f18d4ec7582deaa0077ea5ee7558ef3dd3847c5ff44a44da334cb78cd
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private
|
data/{LICENSES → LICENSE}
RENAMED
File without changes
|
data/NEWS.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
NEWS
|
2
|
+
====
|
3
|
+
|
4
|
+
0.9.9 -> 1.0.2
|
5
|
+
--------------
|
6
|
+
|
7
|
+
* [Add] DateTime#next, DateTime#prev
|
8
|
+
* [Add] TimeStep#right_time?
|
9
|
+
|
10
|
+
0.9.8 -> 0.9.9
|
11
|
+
--------------
|
12
|
+
|
13
|
+
* [Mod] TimeStep::Range.new was modified to accept `start` and `last` argument of mixed type (Integer, DateTime, DateTimeLike, String).
|
14
|
+
|
data/Note.ja.md
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
|
1
|
+
TimeSteps
|
2
2
|
================
|
3
3
|
|
4
4
|
A library for handling discrete time series in constant increments.
|
5
|
-
The primary purpose
|
5
|
+
The primary purpose is to describe the time axis
|
6
6
|
when dealing with time series of observational data and climate data.
|
7
7
|
|
8
|
+
This library relies heavily on the DateTime class. However,
|
9
|
+
the DateTime class has been deprecated,
|
10
|
+
so please keep that in mind when using this library.
|
11
|
+
|
8
12
|
Features
|
9
13
|
--------
|
10
14
|
|
11
|
-
* TimeStep holds an origin time and
|
15
|
+
* TimeStep holds an origin time and a unit time interval.
|
12
16
|
* Parsing a time step expression like "hours since 2001-01-01 00:00:00" (originate from udunits library)
|
13
17
|
* Obtaining time value for the index value (0 for the origin time)
|
14
18
|
* Obtaining index value for the time value
|
@@ -195,6 +199,13 @@ ts = TimeStep.new("3 hours since 2001-01-01 09:00:00", calendar: "noleap")
|
|
195
199
|
|
196
200
|
# specify origin time with DateTime object
|
197
201
|
ts = TimeStep.new("3 hours", since: DateTime.parse("2001-01-01 09:00:00"))
|
202
|
+
|
203
|
+
# hourly increments whose origin is the most recent convenient time to the current time
|
204
|
+
ts = TimeStep.new("1 hour").new_origin(DateTime.now, truncate: true)
|
205
|
+
|
206
|
+
# hourly increments whose origin is the most recent convenient time to the current time
|
207
|
+
# with +0900 time offset
|
208
|
+
ts = TimeStep.new("1 hour", offset: "+0900").new_origin(DateTime.now, truncate: true)
|
198
209
|
```
|
199
210
|
|
200
211
|
### Attributes of TimeStep object
|
@@ -296,5 +307,6 @@ conv.forward(0, 56, 81, with_time: true)
|
|
296
307
|
# "ts2"=>[-48, 8, 33],
|
297
308
|
# "ts3"=>[-72, -16, 9]}
|
298
309
|
|
310
|
+
|
299
311
|
```
|
300
312
|
|
@@ -25,6 +25,34 @@ class DateTime
|
|
25
25
|
return TimePeriod.new(interval_spec, since: self, calendar: calendar, ends: ends, tz: tz)
|
26
26
|
end
|
27
27
|
|
28
|
+
def next (*args)
|
29
|
+
case args.size
|
30
|
+
when 1
|
31
|
+
num = 1
|
32
|
+
unit = args[0]
|
33
|
+
when 2
|
34
|
+
num = args[0]
|
35
|
+
unit = args[1]
|
36
|
+
else
|
37
|
+
raise "invalid number of argumets"
|
38
|
+
end
|
39
|
+
return TimeStep.new(unit, since: self).time_at(num)
|
40
|
+
end
|
41
|
+
|
42
|
+
def prev (*args)
|
43
|
+
case args.size
|
44
|
+
when 1
|
45
|
+
num = 1
|
46
|
+
unit = args[0]
|
47
|
+
when 2
|
48
|
+
num = args[0]
|
49
|
+
unit = args[1]
|
50
|
+
else
|
51
|
+
raise "invalid number of argumets"
|
52
|
+
end
|
53
|
+
return TimeStep.new(unit, since: self).time_at(-num)
|
54
|
+
end
|
55
|
+
|
28
56
|
end
|
29
57
|
|
30
58
|
class DateTime::NoLeap
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Time
|
4
|
+
def to_datetime
|
5
|
+
# Convert seconds + microseconds into a fractional number of seconds
|
6
|
+
seconds = sec + Rational(usec, 10**6)
|
7
|
+
|
8
|
+
# Convert a UTC offset measured in minutes to one measured in a
|
9
|
+
# fraction of a day.
|
10
|
+
offset = Rational(utc_offset, 60 * 60 * 24)
|
11
|
+
|
12
|
+
DateTime.new(year, month, day, hour, min, seconds, offset)
|
13
|
+
end
|
14
|
+
end
|
data/lib/timesteps/timestep.rb
CHANGED
@@ -451,6 +451,7 @@ class TimeStep
|
|
451
451
|
def index_at (*times, format: nil)
|
452
452
|
if times.size == 1
|
453
453
|
time = times.first
|
454
|
+
time = time.to_datetime if time.is_a?(Time)
|
454
455
|
time = @calendar.parse(time, format: format, offset: @origin.offset) if time.is_a?(String)
|
455
456
|
case @symbol
|
456
457
|
when :years
|
@@ -515,8 +516,9 @@ class TimeStep
|
|
515
516
|
# @param time [DateTime, String]
|
516
517
|
#
|
517
518
|
# @return [TimeStep]
|
518
|
-
def new_origin (time)
|
519
|
+
def new_origin (time, truncate: false)
|
519
520
|
time = @calendar.parse(time, offset: @origin.offset) if time.is_a?(String)
|
521
|
+
time = self.truncate(time) if truncate
|
520
522
|
if @wday
|
521
523
|
origin = time - time.wday + WDAY[@wday]
|
522
524
|
origin -= 7 unless time >= origin
|
@@ -626,7 +628,7 @@ class TimeStep
|
|
626
628
|
# @return [TimeStep::Pair]
|
627
629
|
def in (unit)
|
628
630
|
other = TimeStep.new(unit, since: @origin, calendar: @calendar)
|
629
|
-
|
631
|
+
return Pair.new(self, other)
|
630
632
|
end
|
631
633
|
|
632
634
|
# Creates new timestep pair object which refers `other` from `self`
|
@@ -695,5 +697,19 @@ class TimeStep
|
|
695
697
|
return TimeStep::Range.new(self, start, last, count: count, ends: ends)
|
696
698
|
end
|
697
699
|
|
700
|
+
# Check whether the given time is right or not for timestep.
|
701
|
+
#
|
702
|
+
# @example
|
703
|
+
# ts = TimeStep.new("1 hour")
|
704
|
+
# ts.right_time?(ts.parse("2001-01-01 01:00:00"))
|
705
|
+
# # => true
|
706
|
+
# ts.right_time?(ts.parse("2001-01-01 01:30:00"))
|
707
|
+
# # => false
|
708
|
+
#
|
709
|
+
# @return [TimeStep::Range]
|
710
|
+
def right_time? (time)
|
711
|
+
return index_at(time).integer?
|
712
|
+
end
|
713
|
+
|
698
714
|
end
|
699
715
|
|
@@ -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
|
+
|
@@ -13,16 +13,19 @@ class TimeStep::Range
|
|
13
13
|
if last
|
14
14
|
case start
|
15
15
|
when Numeric
|
16
|
-
|
16
|
+
when Time
|
17
|
+
start = timestep.index_at(start.to_datetime)
|
17
18
|
when DateTime, DateTimeLike, String
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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)
|
26
29
|
else
|
27
30
|
raise "unknown argument"
|
28
31
|
end
|
@@ -45,22 +48,24 @@ class TimeStep::Range
|
|
45
48
|
end
|
46
49
|
|
47
50
|
if include_start
|
48
|
-
|
51
|
+
start = start.ceil
|
49
52
|
else
|
50
|
-
|
53
|
+
start = start.floor + 1
|
51
54
|
end
|
52
55
|
|
53
56
|
if include_last
|
54
|
-
|
57
|
+
last = last.floor
|
55
58
|
else
|
56
|
-
|
59
|
+
last = last.ceil - 1
|
57
60
|
end
|
58
61
|
|
59
|
-
@timestep
|
60
|
-
@
|
61
|
-
|
62
|
-
|
63
|
-
@
|
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
|
64
69
|
end
|
65
70
|
|
66
71
|
attr_reader :timestep, :count, :start, :last, :start_time, :last_time
|
@@ -115,8 +120,8 @@ class TimeStep::Range
|
|
115
120
|
# @param time [DateTime]
|
116
121
|
#
|
117
122
|
# @return [TimeStep]
|
118
|
-
def new_origin (time)
|
119
|
-
timestep = @timestep.new_origin(time)
|
123
|
+
def new_origin (time, truncate: false)
|
124
|
+
timestep = @timestep.new_origin(time, truncate: truncate)
|
120
125
|
return TimeStep::Range.new(timestep, count: @count)
|
121
126
|
end
|
122
127
|
|
@@ -124,12 +129,12 @@ class TimeStep::Range
|
|
124
129
|
|
125
130
|
def each_time (&block)
|
126
131
|
if block
|
127
|
-
@start
|
132
|
+
(@start..@last).each do |k|
|
128
133
|
block.call(@timestep.time_at(k))
|
129
134
|
end
|
130
135
|
else
|
131
136
|
return Enumerator.new {|y|
|
132
|
-
@start
|
137
|
+
(@start..@last).each do |k|
|
133
138
|
y << @timestep.time_at(k)
|
134
139
|
end
|
135
140
|
}
|
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"
|
@@ -14,3 +15,4 @@ require "timesteps/timestep_converter"
|
|
14
15
|
require "timesteps/timeperiod"
|
15
16
|
require "timesteps/timestep_range"
|
16
17
|
require "timesteps/datetime_timestep"
|
18
|
+
require "timesteps/timestep_query"
|
data/spec/timestep_spec.rb
CHANGED
@@ -436,3 +436,16 @@ describe "TimeStep#new_origin" do
|
|
436
436
|
|
437
437
|
end
|
438
438
|
|
439
|
+
|
440
|
+
describe "TimeStep#right_time?" do
|
441
|
+
|
442
|
+
example do
|
443
|
+
|
444
|
+
ts = TimeStep.new("1 hour")
|
445
|
+
is_asserted_by { ts.right_time?(ts.parse("2001-01-01 01:00:00")) == true }
|
446
|
+
is_asserted_by { ts.right_time?(ts.parse("2001-01-01 01:30:00")) == false }
|
447
|
+
|
448
|
+
end
|
449
|
+
|
450
|
+
end
|
451
|
+
|
data/timesteps.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
|
2
2
|
Gem::Specification::new do |s|
|
3
|
-
version = "0.
|
3
|
+
version = "1.0.2"
|
4
4
|
|
5
|
-
files = Dir.glob("**/*") - [
|
5
|
+
files = Dir.glob("**/*") + [".yardopts"] - [
|
6
6
|
Dir.glob("timesteps-*.gem"),
|
7
7
|
Dir.glob("doc/**/*"),
|
8
8
|
Dir.glob("examples/**/*"),
|
@@ -20,7 +20,7 @@ Gem::Specification::new do |s|
|
|
20
20
|
describe the time axis when dealing with time series of observational data and climate data.
|
21
21
|
HERE
|
22
22
|
s.version = version
|
23
|
-
s.
|
23
|
+
s.license = 'MIT'
|
24
24
|
s.author = "Hiroki Motoyoshi"
|
25
25
|
s.email = ""
|
26
26
|
s.homepage = 'https://github.com/himotoyoshi/timesteps'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timesteps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroki Motoyoshi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: " A library for time conversion and intercomparison of multiple time
|
14
14
|
series data \n in the case of handling time series data of the type that specifies
|
@@ -22,7 +22,9 @@ executables: []
|
|
22
22
|
extensions: []
|
23
23
|
extra_rdoc_files: []
|
24
24
|
files:
|
25
|
-
-
|
25
|
+
- ".yardopts"
|
26
|
+
- LICENSE
|
27
|
+
- NEWS.md
|
26
28
|
- Note.ja.md
|
27
29
|
- README.md
|
28
30
|
- Rakefile
|
@@ -35,6 +37,7 @@ files:
|
|
35
37
|
- lib/timesteps/datetimelike.rb
|
36
38
|
- lib/timesteps/datetimelike_format.rb
|
37
39
|
- lib/timesteps/grads.rb
|
40
|
+
- lib/timesteps/time.rb
|
38
41
|
- lib/timesteps/timeperiod.rb
|
39
42
|
- lib/timesteps/timestep.rb
|
40
43
|
- lib/timesteps/timestep_calendar.rb
|
@@ -68,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
71
|
- !ruby/object:Gem::Version
|
69
72
|
version: '0'
|
70
73
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
74
|
+
rubygems_version: 3.1.2
|
72
75
|
signing_key:
|
73
76
|
specification_version: 4
|
74
77
|
summary: A library for handling discrete time series in constant increments
|