timesteps 0.9.3 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Note.ja.md +14 -0
- data/README.md +277 -25
- data/lib/timesteps.rb +6 -3
- data/lib/timesteps/calendar.rb +31 -18
- data/lib/timesteps/datetime_360day.rb +38 -0
- data/lib/timesteps/datetime_allleap.rb +34 -0
- data/lib/timesteps/datetime_noleap.rb +39 -0
- data/lib/timesteps/datetimelike.rb +0 -104
- data/lib/timesteps/parse_timestamp.rb +56 -41
- data/lib/timesteps/timestep.rb +154 -53
- data/lib/timesteps/{timestepconverter.rb → timestep_converter.rb} +38 -8
- data/lib/timesteps/{timestepdatetimeext.rb → timestep_datetime_ext.rb} +1 -1
- data/lib/timesteps/{timesteppair.rb → timestep_pair.rb} +28 -54
- data/spec/allleap_spec.rb +5 -5
- data/spec/fixed360day_spec.rb +5 -5
- data/spec/noleap_spec.rb +5 -5
- data/spec/timestep_spec.rb +56 -0
- data/spec/timesteppair_spec.rb +0 -1
- data/timesteps.gemspec +8 -5
- metadata +16 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c66eb1faabea2c6a697af1b84d2b6e4b36419a7fe67f11a04d448476485697e
|
4
|
+
data.tar.gz: d32805b977369e85e0bacdce593275b6f5b30569be978cd74f61a355f9b4c67f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3aba6dae421df42fd53fa5aaaf7b273c9aec3a99d48bd95f9ffd3c0f9b2e6b5a694cc6b8e0c59f3d87355ddb803258dec77d1830280e41e504f85a11ed3b87a
|
7
|
+
data.tar.gz: 835e7de674cc0dea1b51571b119bfd55922e8fe4215124048bdc0d519dfcd1ec0bcec176f3a918b844e60e4fe68105c7878b165695f6ec82e1da8e87cdb61d6e
|
data/Note.ja.md
CHANGED
data/README.md
CHANGED
@@ -9,49 +9,301 @@ Features
|
|
9
9
|
--------
|
10
10
|
|
11
11
|
* TimeStep consists of a pair of origin time and a time interval.
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
*
|
17
|
-
* You can pairert the index values between different TimeStep instances using TimeStepConv.
|
12
|
+
* Parsing a time step expression like "hours since 2001-01-01 00:00:00" (originate from udunits library)
|
13
|
+
* Obtaining time value for index value (0 for the origin time)
|
14
|
+
* Obtaining index value for time value
|
15
|
+
* Treating non-standard calendar-type such as 'noleap', 'allleap', and '360_day'
|
16
|
+
* Comparing the index values between different time step definitions
|
18
17
|
|
19
|
-
|
20
|
-
|
18
|
+
Installation
|
19
|
+
------------
|
21
20
|
|
22
|
-
|
21
|
+
gem install timesteps
|
22
|
+
|
23
|
+
To use the library in your Ruby script,
|
23
24
|
|
24
25
|
```ruby
|
25
26
|
require "timesteps"
|
27
|
+
```
|
28
|
+
|
29
|
+
Description
|
30
|
+
-----------
|
31
|
+
|
32
|
+
This library was created for time conversion and intercomparison of multiple time series data in the case of handling time series data of the type that specifies the time using indexes of time steps since origin time.
|
33
|
+
|
34
|
+
#### Time steps
|
35
|
+
|
36
|
+
The main class of this library is the TimeStep class, which holds the origin time and the interval representing the unit time step. When the TimeStep class is initialized, the following notation is used.
|
26
37
|
|
27
|
-
|
38
|
+
* "second since 1970-01-01 00:00:00 +00:00"
|
39
|
+
* "hour since 2001-01-01 00:00:00 JST"
|
40
|
+
* "3 days since 2001-01-01 00:00:00 +00:00"
|
41
|
+
* "10 years since 1901-01-01 00:00:00 +00:00"
|
28
42
|
|
29
|
-
|
30
|
-
|
31
|
-
p ts.origin ### => #<DateTime: 2001-01-01T09:00:00+00:00 ...>
|
43
|
+
This is a notation used as a time unit in Unidata's [UDUNITS](https://www.unidata.ucar.edu/software/udunits/) library, and is also used as a unit of time axis in [CF conventions](http://cfconventions.org) of NetCDF (this notation is borrowed from the UDUnit library, but it should be noted that there are many differences).
|
32
44
|
|
33
|
-
|
34
|
-
|
45
|
+
In this library, the elapsed time from the origin is expressed as an index value. For the case of "3 hours since 2001-01-01 00:00:00", the index values
|
46
|
+
are expressed as,
|
35
47
|
|
36
|
-
|
37
|
-
|
48
|
+
* "2001-01-01 00:00:00" => 0 (0 / 3 hours) ( 0 days)
|
49
|
+
* "2001-01-01 03:00:00" => 1 (1 / 3 hours) ((1/8) days)
|
50
|
+
* "2001-01-02 00:00:00" => 8 (8 / 3 hours) ( 1 days)
|
51
|
+
|
52
|
+
This is expressed as a Ruby script.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
ts = TimeStep.new("3 hours since 2001-01-01 00:00:00")
|
56
|
+
ts.index_at("2001-01-01 00:00:00") ### => 0
|
57
|
+
ts.index_at("2001-01-01 03:00:00") ### => 1
|
58
|
+
ts.index_at("2001-01-02 00:00:00") ### => 8
|
59
|
+
ts.time_at(0) ### => #<DateTime 2001-01-01T00:00:00 ...>
|
60
|
+
ts.time_at(1) ### => #<DateTime 2001-01-01T03:00:00 ...>
|
61
|
+
ts.time_at(8) ### => #<DateTime 2001-01-02T00:00:00 ...>
|
62
|
+
ts.days_at(0) ### => 0 [Integer]
|
63
|
+
ts.days_at(1) ### => (1/8) [Rational]
|
64
|
+
ts.days_at(8) ### => 1 [Integer]
|
38
65
|
```
|
39
66
|
|
40
|
-
|
67
|
+
#### Treatment of year and month units
|
68
|
+
|
69
|
+
The time units like day, hour, minute, second have constant intervals,
|
70
|
+
but the time units like years and months are not. So, the year and
|
71
|
+
month units are given special treatment in this library.
|
72
|
+
One year is counted at the same month and day as the origin time, and
|
73
|
+
one month is counted at the same day as the origin time.
|
41
74
|
|
42
75
|
```ruby
|
43
|
-
|
76
|
+
ts = TimeStep.new("year since 2000-01-15 00:00:00")
|
77
|
+
ts.index_at("2001-01-14 23:59:59") ### => 0
|
78
|
+
ts.index_at("2001-01-15 00:00:00") ### => 1
|
79
|
+
ts.index_at("2010-01-14 23:59:59") ### => 9
|
80
|
+
ts.index_at("2010-01-15 00:00:00") ### => 10
|
81
|
+
|
82
|
+
ts = TimeStep.new("month since 2000-01-15 00:00:00")
|
83
|
+
ts.index_at("2000-02-14 23:59:59") ### => 0
|
84
|
+
ts.index_at("2000-02-15 00:00:00") ### => 1
|
85
|
+
ts.index_at("2000-11-14 23:59:59") ### => 9
|
86
|
+
ts.index_at("2000-11-15 00:00:00") ### => 10
|
87
|
+
```
|
88
|
+
|
89
|
+
And, it is not possible to give a fractional index
|
90
|
+
for the units of year and month (some methods return a fractional index).
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
ts = TimeStep.new("year since 2000-01-15 00:00:00")
|
94
|
+
ts.time_at(0.5) ### => RuntimeError raised
|
95
|
+
# => in `time_at': index for years should be an integer (RuntimeError)
|
96
|
+
```
|
97
|
+
|
98
|
+
#### Calendars
|
99
|
+
|
100
|
+
The following calendars, including non-standard calendars, can be handled.
|
101
|
+
|
102
|
+
* standard, gregorian
|
103
|
+
* proleptic_gregorian
|
104
|
+
* proleptic_julian, julian
|
105
|
+
* noleap, 365_day
|
106
|
+
* allleap, 366_day
|
107
|
+
* 360_day
|
108
|
+
|
109
|
+
You can find the description for these calendar at the document of CF-Convensions ([4.4.1 Calendar](http://cfconventions.org/Data/cf-conventions/cf-conventions-1.8/cf-conventions.html#calendar)).
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
ts = TimeStep.new("day since 2000-01-01", calendar: "standard")
|
113
|
+
ts.time_at(59) ### => #<DateTime: 2000-02-29T00:00:00+00:00 ...>
|
114
|
+
|
115
|
+
ts = TimeStep.new("day since 2000-01-01", calendar: "noleap")
|
116
|
+
ts.time_at(59) ### => #<DateTime::NoLeap: 2000-03-01T00:00:00+00:00 ...>
|
117
|
+
|
118
|
+
ts = TimeStep.new("day since 2000-01-01", calendar: "360_day")
|
119
|
+
ts.time_at(59) ### => #<DateTime::Fixed360Day: 2000-02-30T00:00:00+00:00 ...>
|
120
|
+
```
|
121
|
+
|
122
|
+
In this library, DateTime class is adopted as the object that represents date and time (not Time class). Non-standard calendars ("proleptic_gregorian", "Julian") can be handled by the DateTime class, with appropriate use of the start parameter. But, other non-standard calendars ("noleap", "allleap", "360_day") can not. So, DateTimeLike class and its subclasses DateTime::NoLeap, DateTime::AllLeap, DateTime::Fixed360Day are introduced. Since many (not all) of methods in DateTime class are also implemented in DateTimeLike class, users don't need to be too aware of these class differences.
|
123
|
+
|
124
|
+
#### Parsing datetime string
|
125
|
+
|
126
|
+
In `standard` calendar, use DateTime.parse as usual.
|
127
|
+
In other calendar, you can use DateTime.parse_timestamp, which is
|
128
|
+
special method to parse date time string with specification of calendar.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
DateTime.parse_timestamp("1200-01-01") ### "standard"
|
132
|
+
DateTime.parse_timestamp("1200-01-01", calendar: "proleptic_gregorian")
|
133
|
+
DateTime.parse_timestamp("1200-01-01", calendar: "julian")
|
134
|
+
DateTime.parse_timestamp("1200-01-01", calendar: "noleap")
|
135
|
+
DateTime.parse_timestamp("1200-01-01", calendar: "allleap")
|
136
|
+
DateTime.parse_timestamp("1200-01-01", calendar: "360_day")
|
137
|
+
```
|
138
|
+
|
139
|
+
If you already have the instance of TimeStep, you can use the method named TimeStep#parse, which is called when it is necessary to convert from the string to the date and time internally.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
ts = TimeStep.new("days since 2001-01-01", calendar: "allleap")
|
143
|
+
ts.parse("2001-02-29") ### => #<DateTime::AllLeap 2001-02-29T ...>
|
144
|
+
```
|
145
|
+
|
146
|
+
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. To parse date time string of UDUNITS type, `bc` option for `Date.parse_timestamp` method.
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
DateTime.parse_timestamp("-0001-01-01")
|
150
|
+
# => #<DateTime: -0001-01-01T00:00:00+00:00 ...>
|
151
|
+
# B.C. 2
|
152
|
+
|
153
|
+
DateTime.parse_timestamp("-0001-01-01", bc: true)
|
154
|
+
# => #<DateTime: 0000-01-01T00:00:00+00:00 ...>
|
155
|
+
# B.C. 1
|
156
|
+
|
157
|
+
DateTime.parse_timestamp("BC 0001-01-01")
|
158
|
+
# => #<DateTime: 0000-01-01T00:00:00+00:00 ...>
|
159
|
+
# B.C. 1
|
160
|
+
```
|
44
161
|
|
162
|
+
#### Comparing two time series
|
163
|
+
|
164
|
+
TimeStep::Pair is a class to compare indices of two time series,
|
165
|
+
which is initialized by two time step object. It is possible to
|
166
|
+
compute the other index corresponding to the time represented
|
167
|
+
by one of the indices using TimeStep::Pair.
|
168
|
+
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
# Create TimeStepPair object
|
45
172
|
ts1 = TimeStep.new("3 hours since 2001-01-01 21:00:00")
|
46
173
|
ts2 = TimeStep.new("hour since 2001-01-01 09:00:00")
|
47
174
|
pair = TimeStep::Pair.new(ts1, ts2)
|
48
175
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
176
|
+
# You can create same object with,
|
177
|
+
# pair = TimeStep::Pair.new("3 hours since 2001-01-01 21:00:00",
|
178
|
+
# "hour since 2001-01-01 09:00:00")
|
179
|
+
|
180
|
+
# Forward conversion
|
181
|
+
pair.forward(0)
|
182
|
+
# => 12
|
183
|
+
pair.forward(2)
|
184
|
+
# => 18 (12 + 2*3h/1h)
|
185
|
+
|
186
|
+
# Inverse conversion
|
187
|
+
pair.inverse(0)
|
188
|
+
# => -4 ((-12h)/3h)
|
189
|
+
pair.inverse(2)
|
190
|
+
# => (-10/3) ((-12h+2*1h)/3h)
|
191
|
+
```
|
192
|
+
|
193
|
+
Examples
|
194
|
+
========
|
195
|
+
|
196
|
+
### Construct a TimeStep object
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
# standard calendar
|
200
|
+
ts = TimeStep.new("3 hours since 2001-01-01 09:00:00")
|
201
|
+
|
202
|
+
# noleap calendar
|
203
|
+
ts = TimeStep.new("3 hours since 2001-01-01 09:00:00", calendar: "noleap")
|
204
|
+
|
205
|
+
# specify origin time with DateTime object
|
206
|
+
ts = TimeStep.new("3 hours", since: DateTime.parse("2001-01-01 09:00:00"))
|
207
|
+
```
|
208
|
+
|
209
|
+
### Attributes of TimeStep object
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
ts = TimeStep.new("3 hours since 2001-01-01 09:00:00")
|
213
|
+
|
214
|
+
# specification
|
215
|
+
ts.definition
|
216
|
+
# => "3 hours since 2001-01-01 09:00:00.000000000 +00:00"
|
217
|
+
ts.intervalspec
|
218
|
+
# => "3 hours"
|
219
|
+
ts.originspec
|
220
|
+
# => "2001-01-01 09:00:00.000000000 +00:00"
|
221
|
+
|
222
|
+
# data for time interval
|
223
|
+
ts.numeric
|
224
|
+
# => (3/1)
|
225
|
+
ts.symbol
|
226
|
+
# => :hours
|
227
|
+
ts.interval
|
228
|
+
# => (10800/1)
|
229
|
+
|
230
|
+
# origin time
|
231
|
+
ts.origin
|
232
|
+
# => #<DateTime: 2001-01-01T09:00:00+00:00 ((2451911j,32400s,0n),+0s,2299161j)>
|
233
|
+
|
234
|
+
# calendar
|
235
|
+
ts.calendar
|
236
|
+
# => #<TimeStep::Calendar calendar='standard' bc='false'>
|
237
|
+
```
|
238
|
+
|
239
|
+
### What is the index value of the time step 'TS' corresponding to time 'T' ?
|
240
|
+
|
241
|
+
```ruby
|
242
|
+
# hours
|
243
|
+
ts = TimeStep.new("6 hours since 2000-01-15 00:00:00")
|
244
|
+
ts.index_at("2000-01-25 00:00:00")
|
245
|
+
# => 40
|
246
|
+
ts.index_at("2000-01-25 03:00:00")
|
247
|
+
# => (81/2)
|
248
|
+
```
|
249
|
+
|
250
|
+
### What is the time corresponding to index 'I' of time step 'TS' ?
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
# hours
|
254
|
+
ts = TimeStep.new("6 hours since 2000-01-15 00:00:00")
|
255
|
+
ts.time_at(40)
|
256
|
+
# => #<DateTime: 2000-01-25T00:00:00+00:00 ...>
|
257
|
+
ts.time_at(40.5)
|
258
|
+
# => #<DateTime: 2000-01-25T03:00:00+00:00 ...>
|
259
|
+
````
|
260
|
+
|
261
|
+
### What is the UNIX time stamp for the time corresponding to index 'I' of time step 'TS' ?
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
ts = TimeStep.new("hour since 2000-01-01 00:00:00")
|
265
|
+
unixtime = TimeStep.new("seconds since 1970-01-01 00:00:00")
|
266
|
+
pair = TimeStep::Pair.new(ts, unixtime)
|
267
|
+
|
268
|
+
# UNIX time for index 0
|
269
|
+
pair.forward(0)
|
270
|
+
# => 946684800
|
271
|
+
|
272
|
+
# UNIX time for index 10
|
273
|
+
pair.forward(10)
|
274
|
+
# => 946720800
|
275
|
+
````
|
276
|
+
|
277
|
+
### How to get each index for a certain time of multiple time steps having different origin times ?
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
conv = TimeStep::Converter.new("hour since 2000-01-01 00:00:00", name: "ts0")
|
281
|
+
conv["ts1"] = "hour since 2000-01-02 00:00:00"
|
282
|
+
conv["ts2"] = "hour since 2000-01-03 00:00:00"
|
283
|
+
conv["ts3"] = "hour since 2000-01-04 00:00:00"
|
284
|
+
|
285
|
+
# index 0 for ts0
|
286
|
+
conv.forward(0)
|
287
|
+
# => {"ts0"=>0, "ts1"=>-24, "ts2"=>-48, "ts3"=>-72}
|
288
|
+
|
289
|
+
# index 56 for ts0
|
290
|
+
conv.forward(56)
|
291
|
+
# => {"ts0"=>56, "ts1"=>32, "ts2"=>8, "ts3"=>-16}
|
292
|
+
|
293
|
+
# index 81 for ts0
|
294
|
+
conv.forward(81)
|
295
|
+
# => {"ts0"=>81, "ts1"=>57, "ts2"=>33, "ts3"=>9}
|
296
|
+
|
297
|
+
# indices [0, 56, 81] for ts0 with time
|
298
|
+
conv.forward(0, 56, 81, with_time: true)
|
299
|
+
# {"time"=>
|
300
|
+
# [#<DateTime: 2000-01-01T00:00:00+00:00 ((2451545j,0s,0n),+0s,2299161j)>,
|
301
|
+
# #<DateTime: 2000-01-03T08:00:00+00:00 ((2451547j,28800s,0n),+0s,2299161j)>,
|
302
|
+
# #<DateTime: 2000-01-04T09:00:00+00:00 ((2451548j,32400s,0n),+0s,2299161j)>],
|
303
|
+
# "ts0"=>[0, 56, 81],
|
304
|
+
# "ts1"=>[-24, 32, 57],
|
305
|
+
# "ts2"=>[-48, 8, 33],
|
306
|
+
# "ts3"=>[-72, -16, 9]}
|
53
307
|
|
54
|
-
p pair.inverse(0) ### -4/1 ((-12h)/3h)
|
55
|
-
p pair.inverse(2) ### -10/3 ((-12h+2*1h)/3h)
|
56
308
|
```
|
57
309
|
|
data/lib/timesteps.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
|
2
2
|
require "date"
|
3
3
|
require "timesteps/datetimelike"
|
4
|
+
require "timesteps/datetime_noleap"
|
5
|
+
require "timesteps/datetime_allleap"
|
6
|
+
require "timesteps/datetime_360day"
|
4
7
|
require "timesteps/parse_timestamp"
|
5
8
|
require "timesteps/format"
|
6
|
-
require "timesteps/
|
9
|
+
require "timesteps/timestep_datetime_ext"
|
7
10
|
require "timesteps/calendar"
|
8
11
|
require "timesteps/timestep"
|
9
|
-
require "timesteps/
|
10
|
-
require "timesteps/
|
12
|
+
require "timesteps/timestep_pair"
|
13
|
+
require "timesteps/timestep_converter"
|
data/lib/timesteps/calendar.rb
CHANGED
@@ -12,9 +12,18 @@ class TimeStep
|
|
12
12
|
# @private
|
13
13
|
SYM_360_day = "360_day".intern
|
14
14
|
|
15
|
+
DateTimeType = {
|
16
|
+
:standard => DateTime,
|
17
|
+
:proleptic_gregorian => DateTime,
|
18
|
+
:proleptic_julian => DateTime,
|
19
|
+
:noleap => DateTime::NoLeap,
|
20
|
+
:allleap => DateTime::AllLeap,
|
21
|
+
SYM_360_day => DateTime::Fixed360Day,
|
22
|
+
}
|
23
|
+
|
15
24
|
def initialize (calendar = "standard", bc: false)
|
16
|
-
@name
|
17
|
-
@bc
|
25
|
+
@name = calendar
|
26
|
+
@bc = bc
|
18
27
|
case @name.downcase.intern
|
19
28
|
when :standard, :gregorian
|
20
29
|
@calendar = :standard
|
@@ -33,6 +42,10 @@ class TimeStep
|
|
33
42
|
|
34
43
|
attr_reader :name, :calendar
|
35
44
|
|
45
|
+
def inspect
|
46
|
+
"#<TimeStep::Calendar calendar='#{@calendar.to_s}' bc='#{@bc}'>"
|
47
|
+
end
|
48
|
+
|
36
49
|
def == (other)
|
37
50
|
return @calendar == other.calendar && bc? == other.bc?
|
38
51
|
end
|
@@ -41,26 +54,26 @@ class TimeStep
|
|
41
54
|
return @bc ? true : false
|
42
55
|
end
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
# @return [DateTime object]
|
48
|
-
def parse (timespec)
|
57
|
+
def valid_datetime_type? (time)
|
58
|
+
return false unless time.is_a?(DateTimeType[@calendar])
|
49
59
|
case @calendar
|
50
60
|
when :standard
|
51
|
-
time
|
61
|
+
return time.start == Date::ITALY
|
52
62
|
when :proleptic_gregorian
|
53
|
-
time
|
63
|
+
return time.start == Date::GREGORIAN
|
54
64
|
when :proleptic_julian
|
55
|
-
time
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
return time.start == Date::JULIAN
|
66
|
+
else
|
67
|
+
return true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Parses the given representation of date and time in the calendar,
|
72
|
+
# and creates an date time instance.
|
73
|
+
#
|
74
|
+
# @return [DateTime object]
|
75
|
+
def parse (timespec, format: nil)
|
76
|
+
return DateTime.parse_timestamp(timespec, calendar: @calendar.to_s, bc: @bc, format: format)
|
64
77
|
end
|
65
78
|
|
66
79
|
def jday2date (jday)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class DateTime
|
2
|
+
|
3
|
+
# datetime class represents `360_day` calendar
|
4
|
+
#
|
5
|
+
class Fixed360Day < DateTimeLike
|
6
|
+
|
7
|
+
extend DateTimeLikeExtension
|
8
|
+
|
9
|
+
# Number of days per year
|
10
|
+
DPY = 360
|
11
|
+
|
12
|
+
# Numbers of days per months
|
13
|
+
DPM = [0,30,30,30,30,30,30,30,30,30,30,30,30]
|
14
|
+
|
15
|
+
# Astronomical Julian day number of UNIX epoch
|
16
|
+
UNIX_EPOCH_IN_AJD = Rational(4811039,2)
|
17
|
+
|
18
|
+
def valid_date?
|
19
|
+
if @day >= 31
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
if @month != 2
|
23
|
+
return Date.valid_date?(@year, @month, @day)
|
24
|
+
else
|
25
|
+
return ( @day >= 1 and @day <= 30 )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private :valid_date?
|
30
|
+
|
31
|
+
def leap?
|
32
|
+
raise NotImplementedError
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|