timesteps 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSES +22 -0
- data/Note.ja.md +76 -0
- data/README.md +57 -0
- data/Rakefile +11 -0
- data/lib/timesteps/calendar.rb +104 -0
- data/lib/timesteps/datetimelike.rb +530 -0
- data/lib/timesteps/format.rb +251 -0
- data/lib/timesteps/grads.rb +43 -0
- data/lib/timesteps/parse_timestamp.rb +48 -0
- data/lib/timesteps/timestep.rb +362 -0
- data/lib/timesteps/timestepconverter.rb +63 -0
- data/lib/timesteps/timestepdatetimeext.rb +79 -0
- data/lib/timesteps/timesteppair.rb +202 -0
- data/lib/timesteps.rb +10 -0
- data/spec/allleap_spec.rb +330 -0
- data/spec/fixed360day_spec.rb +341 -0
- data/spec/noleap_spec.rb +330 -0
- data/spec/timestep_spec.rb +405 -0
- data/spec/timesteppair_spec.rb +99 -0
- data/timesteps.gemspec +26 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d9b039e00dac34bb9cf616ea94da9465feb696179d550c1b6f7f511ddf06756f
|
4
|
+
data.tar.gz: ac64b576636a5d9f45bbca34fd21ea479911a4dc260df2ef5a3adb2b5071ae6d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 237fa23fec58640aa1ab3ec9863a8f546016bc978d1b5258e5d5021fb875a55115696a3fb387dd4dc42e47cc561530b3de83604cf4cb7e2f708748183a011c67
|
7
|
+
data.tar.gz: 978d9e97ced5f11868018fc895fddb261eaf402e937a1371f0395c5f13c857dd1b3122d4e412cc723717fae8860a396fad804ffe316c80277c2516ed79b6de2e
|
data/LICENSES
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2020 Hiroki Motoyoshi.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Note.ja.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# メモ
|
2
|
+
### 時間の単位 (udunits)
|
3
|
+
* years, year
|
4
|
+
* months,month
|
5
|
+
* days, day, d
|
6
|
+
* hours, hour, h
|
7
|
+
* minutes, minute, min
|
8
|
+
* seconds, sec, s
|
9
|
+
|
10
|
+
### クラス構成
|
11
|
+
|
12
|
+
#### DateTime, DateTimeLikeクラス
|
13
|
+
class DateTime
|
14
|
+
module ParseTimeStampExt ### DateTime(-like)クラスに、`parse_timestamp`を追加する
|
15
|
+
module TimeStepsCustomExt ### TimeSteps用のDateTime refinement
|
16
|
+
extend ParseTimeStampExtension
|
17
|
+
class DateTimeLike
|
18
|
+
module DateTimeLikeExtension ### NoLeap,AllLeap,Fixed360共通のクラスメソッドを追加する
|
19
|
+
class DateTime::NoLeap < DateTimeLike
|
20
|
+
extend ParseTimeStampExtension
|
21
|
+
extend DateTimeLikeExtension
|
22
|
+
class DateTime::AllLeap < DateTimeLike
|
23
|
+
extend ParseTimeStampExtension
|
24
|
+
extend DateTimeLikeExtension
|
25
|
+
class DateTime::Fixed360Day < DateTimeLike
|
26
|
+
extend ParseTimeStampExtension
|
27
|
+
extend DateTimeLikeExtension
|
28
|
+
|
29
|
+
#### TimeStep, TimeStepsPair, TimeStepConverter クラス
|
30
|
+
+ class TimeSteps
|
31
|
+
using DateTime::TimeStepsCustomExt
|
32
|
+
+ class TimeSteps::Calendar
|
33
|
+
using DateTime::TimeStepsCustomExt
|
34
|
+
+ class TimeStepsConv
|
35
|
+
using DateTime::TimeStepsCustomExt
|
36
|
+
|
37
|
+
### DateTimeのユリウス日の起算日
|
38
|
+
-4712-01-01 00:00:00+00:00
|
39
|
+
|
40
|
+
### UDUnits-2との非互換性(CF-規約との非互換性)
|
41
|
+
udunits-2は日にちの表式にBCを用いている。
|
42
|
+
TimeSteps.newのbcオプションでparsingには対応しているものの、time_atなどで返されるDateTimeオブジェクトは
|
43
|
+
BCを考慮していない点に注意。
|
44
|
+
|
45
|
+
DateTime.parse_timestamp(spec, bc: true)
|
46
|
+
TimeSteps#parse(spec) (initialized with bc: option)
|
47
|
+
TimeSteps::Calendar#parse(spec) (initialized with bc: option)
|
48
|
+
|
49
|
+
### 暦の種類
|
50
|
+
#### standard, gregorian
|
51
|
+
|
52
|
+
* 今日使われているグレゴリオ暦
|
53
|
+
* 1582年10月4日の翌日が1582年10月15日と
|
54
|
+
することでユリウス暦で数えすぎたうるう日をスキップしている
|
55
|
+
* 1582年10月15日以降はグレゴリオ暦のうるう年ルールを採用
|
56
|
+
* 1582年10月4日以前はユリウス暦のうるう年ルールを採用
|
57
|
+
|
58
|
+
#### proleptic_gregorian
|
59
|
+
|
60
|
+
* 1582年10月15日以前もグレゴリオ暦のうるう年ルールを採用
|
61
|
+
|
62
|
+
#### proleptic_julian, julian
|
63
|
+
|
64
|
+
* 1582年10月4日以降もユリウス暦のうるう年ルールを採用
|
65
|
+
|
66
|
+
#### noleap, 365_day
|
67
|
+
|
68
|
+
* すべての年はうるう年ではないものとした暦
|
69
|
+
|
70
|
+
#### allleap, 366_day
|
71
|
+
|
72
|
+
* すべての年はうるう年であるとした暦
|
73
|
+
|
74
|
+
#### 360_day
|
75
|
+
|
76
|
+
* すべての月が30日であるとした暦
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
timesteps
|
2
|
+
================
|
3
|
+
|
4
|
+
A library for handling discrete time series in constant increments.
|
5
|
+
The main purpose of this library is to describe the time axis
|
6
|
+
when dealing with time series of observational data and climate data.
|
7
|
+
|
8
|
+
Features
|
9
|
+
--------
|
10
|
+
|
11
|
+
* TimeStep consists of a pair of origin time and a time interval.
|
12
|
+
* An instance of a TimeStep can be constructed by parsing an expression like "hours since 2001-01-01 00:00:00" (originate from udunits library)
|
13
|
+
* DateTime object can be obtained from the index value (0 for the origin time).
|
14
|
+
* The index value can be calculated from the date and time.
|
15
|
+
* TimeStep can handle special calendar-type time series such as noleap, allleap, and 360_day.
|
16
|
+
* "24:00:00" can be parsed as a valid timestamp.
|
17
|
+
* You can pairert the index values between different TimeStep instances using TimeStepConv.
|
18
|
+
|
19
|
+
Usage
|
20
|
+
-----
|
21
|
+
|
22
|
+
### TimeStep
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require "timesteps"
|
26
|
+
|
27
|
+
ts = TimeStep.new("3 hours since 2001-01-01 09:00:00", calendar: "standard")
|
28
|
+
|
29
|
+
p ts ### => #<TimeStep definition='3 hours since 2001-01-01 09:00:00.000000000 +00:00' calendar='standard'>
|
30
|
+
|
31
|
+
p ts.origin ### => #<DateTime: 2001-01-01T09:00:00+00:00 ...>
|
32
|
+
|
33
|
+
p ts.time_at(1) ### => #<DateTime: 2001-01-01T12:00:00+00:00 ...>
|
34
|
+
p ts.time_at(8) ### => #<DateTime: 2001-01-02T09:00:00+00:00 ...>
|
35
|
+
|
36
|
+
time = DateTime.parse("2001-01-02 09:00:00 +00:00")
|
37
|
+
p ts.index_at(time) ### => (8/1) <Rational>
|
38
|
+
```
|
39
|
+
|
40
|
+
### TimeStepPair
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
require "timesteps"
|
44
|
+
|
45
|
+
ts1 = TimeStep.new("3 hours since 2001-01-01 21:00:00")
|
46
|
+
ts2 = TimeStep.new("hour since 2001-01-01 09:00:00")
|
47
|
+
pair = TimeStep::Pair.new(ts1, ts2)
|
48
|
+
|
49
|
+
p pair ### => <TimeStepConv from='<TimeSteps unit='3 hour since 2001-01-01 21:00:00.000000000' calendar='standard'>' to='<TimeSteps unit='hour since 2001-01-01 09:00:00.000000000' calendar='standard'>'>
|
50
|
+
|
51
|
+
p pair.forward(0) ### 12/1 (12)
|
52
|
+
p pair.forward(2) ### 18/1 (12 + 2*3h/1h)
|
53
|
+
|
54
|
+
p pair.inverse(0) ### -4/1 ((-12h)/3h)
|
55
|
+
p pair.inverse(2) ### -10/3 ((-12h+2*1h)/3h)
|
56
|
+
```
|
57
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
|
2
|
+
class TimeStep
|
3
|
+
|
4
|
+
class Calendar
|
5
|
+
|
6
|
+
using TimeStep::DateTimeExt
|
7
|
+
|
8
|
+
# @private
|
9
|
+
SYM_365_day = "365_day".intern
|
10
|
+
# @private
|
11
|
+
SYM_366_day = "366_day".intern
|
12
|
+
# @private
|
13
|
+
SYM_360_day = "360_day".intern
|
14
|
+
|
15
|
+
def initialize (calendar = "standard", bc: false)
|
16
|
+
@name = calendar
|
17
|
+
@bc = bc
|
18
|
+
case @name.downcase.intern
|
19
|
+
when :standard, :gregorian
|
20
|
+
@calendar = :standard
|
21
|
+
when :proleptic_gregorian
|
22
|
+
@calendar = :proleptic_gregorian
|
23
|
+
when :proleptic_julian, :julian
|
24
|
+
@calendar = :proleptic_julian
|
25
|
+
when :noleap, SYM_365_day
|
26
|
+
@calendar = :noleap
|
27
|
+
when :allleap, SYM_366_day
|
28
|
+
@calendar = :allleap
|
29
|
+
when SYM_360_day
|
30
|
+
@calendar = SYM_360_day
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :name, :calendar
|
35
|
+
|
36
|
+
def == (other)
|
37
|
+
return @calendar == other.calendar && bc? == other.bc?
|
38
|
+
end
|
39
|
+
|
40
|
+
def bc?
|
41
|
+
return @bc ? true : false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Parses the given representation of date and time in the calendar,
|
45
|
+
# and creates an date time instance.
|
46
|
+
#
|
47
|
+
# @return [DateTime object]
|
48
|
+
def parse (timespec)
|
49
|
+
case @calendar
|
50
|
+
when :standard
|
51
|
+
time = DateTime.parse_timestamp(timespec, Date::ITALY, bc: @bc)
|
52
|
+
when :proleptic_gregorian
|
53
|
+
time = DateTime.parse_timestamp(timespec, Date::GREGORIAN, bc: @bc)
|
54
|
+
when :proleptic_julian
|
55
|
+
time = DateTime.parse_timestamp(timespec, Date::JULIAN, bc: @bc)
|
56
|
+
when :noleap
|
57
|
+
time = DateTime::NoLeap.parse_timestamp(timespec, bc: @bc)
|
58
|
+
when :allleap
|
59
|
+
time = DateTime::AllLeap.parse_timestamp(timespec, bc: @bc)
|
60
|
+
when SYM_360_day
|
61
|
+
time = DateTime::Fixed360Day.parse_timestamp(timespec, bc: @bc)
|
62
|
+
end
|
63
|
+
return time
|
64
|
+
end
|
65
|
+
|
66
|
+
def jday2date (jday)
|
67
|
+
case @calendar
|
68
|
+
when :standard
|
69
|
+
time = DateTime.jd(jday, 0, 0, 0, 0, Date::ITALY)
|
70
|
+
when :proleptic_gregorian
|
71
|
+
time = DateTime.jd(jday, 0, 0, 0, 0, Date::GREGORIAN)
|
72
|
+
when :proleptic_julian
|
73
|
+
time = DateTime.jd(jday, 0, 0, 0, 0, Date::JULIAN)
|
74
|
+
when :noleap
|
75
|
+
time = DateTime::NoLeap.jd(jday, 0, 0, 0, 0)
|
76
|
+
when :allleap
|
77
|
+
time = DateTime::AllLeap.jd(jday, 0, 0, 0, 0)
|
78
|
+
when SYM_360_day
|
79
|
+
time = DateTime::Fixed360Day.jd(jday, 0, 0, 0, 0)
|
80
|
+
end
|
81
|
+
return time
|
82
|
+
end
|
83
|
+
|
84
|
+
def date2jday (year, month, day)
|
85
|
+
case @calendar
|
86
|
+
when :standard
|
87
|
+
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::ITALY)
|
88
|
+
when :proleptic_gregorian
|
89
|
+
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::GREGORIAN)
|
90
|
+
when :proleptic_julian
|
91
|
+
time = DateTime.new(year, month, day, 0, 0, 0, 0, Date::JULIAN)
|
92
|
+
when :noleap
|
93
|
+
time = DateTime::NoLeap.new(year, month, day, 0, 0, 0, 0)
|
94
|
+
when :allleap
|
95
|
+
time = DateTime::AllLeap.new(year, month, day, 0, 0, 0, 0)
|
96
|
+
when SYM_360_day
|
97
|
+
time = DateTime::Fixed360Day.new(year, month, day, 0, 0, 0, 0)
|
98
|
+
end
|
99
|
+
return time.jd
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|