Class: DateTimeLike

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/timesteps/datetimelike.rb,
lib/timesteps/datetimelike_format.rb

Defined Under Namespace

Modules: DateTimeLikeExtension

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(year = -4712,, month = 1, day = 1, hour = 0, minute = 0, second = 0.0, offset = 0, start = nil) ⇒ DateTimeLike

Creates a DateTime object denoting the given calendar date.

Parameters:

  • year (Integer) (defaults to: -4712,)
  • month (Integer) (defaults to: 1)
  • day (Integer) (defaults to: 1)
  • hour (Integer) (defaults to: 0)
  • minute (Integer) (defaults to: 0)
  • second (Integer) (defaults to: 0.0)
  • offset (Integer) (defaults to: 0)
  • start (Integer) (defaults to: nil)


65
66
67
68
69
70
71
72
73
74
# File 'lib/timesteps/datetimelike.rb', line 65

def initialize (year = -4712, month = 1, day = 1, hour = 0, minute = 0, second = 0.0, offset = 0, start = nil)
  @year   = year.to_i
  @month  = month.to_i
  @day    = day.to_i
  @hour   = hour.to_i
  @minute = minute.to_i
  @second = second
  @offset = offset
  check_valid_datetime()
end

Instance Attribute Details

#dayObject (readonly) Also known as: mday

Returns the value of attribute day.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def day
  @day
end

#hourObject (readonly)

Returns the value of attribute hour.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def hour
  @hour
end

#minuteObject (readonly) Also known as: min

Returns the value of attribute minute.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def minute
  @minute
end

#monthObject (readonly) Also known as: mon

Returns the value of attribute month.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def month
  @month
end

#offsetObject (readonly)

Returns the value of attribute offset.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def offset
  @offset
end

#yearObject (readonly)

Returns the value of attribute year.



96
97
98
# File 'lib/timesteps/datetimelike.rb', line 96

def year
  @year
end

Instance Method Details

#+(days) ⇒ DateTimeFixedDPY

Returns a date object pointing other days after self.

Parameters:

  • days (Numeric)

Returns:

  • (DateTimeFixedDPY)


190
191
192
193
194
195
196
197
198
199
# File 'lib/timesteps/datetimelike.rb', line 190

def + (days)
  days = days.to_r + fraction 
  jday = jd.floor + days.floor
  fday = (days - days.floor)*24
  hour = fday.floor
  fday = (fday - hour)*60
  min  = fday.floor
  sec  = (fday - min)*60
  return self.class.jd(jday, hour, min, sec, offset)  
end

#-(other_or_days) ⇒ Object

Returns the difference between the two dates if the other is a datetime object. If the other is a numeric value, returns a date object pointing other days before self.



205
206
207
208
209
210
211
212
213
214
# File 'lib/timesteps/datetimelike.rb', line 205

def - (other_or_days)
  case other_or_days
  when Numeric
    return self + (-other_or_days)      
  when self.class
    return self.jd - other_or_days.jd
  else
    raise "other shoud be date-time object or numeric value"
  end
end

#<<(n) ⇒ DateTimeFixedDPY

Returns a date object pointing n months before self.

Parameters:

  • n (Integer)

Returns:

  • (DateTimeFixedDPY)


230
231
232
# File 'lib/timesteps/datetimelike.rb', line 230

def << (n)
  return add_months(-n)
end

#<=>(other) ⇒ Object

Compares the two dates and returns -1, zero, 1 or nil. The other should be a date object or a numeric value as an astronomical Julian day number.



363
364
365
# File 'lib/timesteps/datetimelike.rb', line 363

def <=> (other)
  return self.ajd <=> other.ajd
end

#>>(n) ⇒ DateTimeFixedDPY

Returns a date object pointing n months after self.

Parameters:

  • n (Integer)

Returns:

  • (DateTimeFixedDPY)


221
222
223
# File 'lib/timesteps/datetimelike.rb', line 221

def >> (n)
  return add_months(n)
end

#ajdNumeric

Calculates astronomical Julian day number.

Returns:

  • (Numeric)


159
160
161
# File 'lib/timesteps/datetimelike.rb', line 159

def ajd
  return jd + fraction - @offset - 1.quo(2) 
end

#compare_d(other) ⇒ Object



385
386
387
388
389
390
391
392
393
394
395
# File 'lib/timesteps/datetimelike.rb', line 385

def compare_d (other)
  sday = self.day + self.fraction + self.offset
  oday = other.day + other.fraction + other.offset
  if sday > oday
    return 1
  elsif sday < oday
    return -1
  else
    return 0
  end
end

#compare_md(other) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/timesteps/datetimelike.rb', line 367

def compare_md (other)
  sday = self.day + self.fraction + self.offset
  oday = other.day + other.fraction + other.offset
  if self.month > other.month
    return 1
  elsif self.month < other.month
    return -1
  else
    if sday > oday
      return 1
    elsif sday < oday
      return -1
    else
      return 0
    end
  end
end

#difference_in_months(other) ⇒ Integer

Calculate difference between the object and other object in months.

Returns:

  • (Integer)


409
410
411
412
413
# File 'lib/timesteps/datetimelike.rb', line 409

def difference_in_months (other)
  my    = self.new_offset(0)
  other = other.new_offset(0)
  return 12*(my.year - other.year) + my.month - other.month + my.compare_d(other).quo(2)  
end

#difference_in_years(other) ⇒ Integer

Calculate difference between the object and other object in years.

Returns:

  • (Integer)


400
401
402
403
404
# File 'lib/timesteps/datetimelike.rb', line 400

def difference_in_years (other)
  my    = self.new_offset(0)
  other = other.new_offset(0)
  return my.year - other.year + my.compare_md(other).quo(2)
end

#fractionRational

Returns time fraction in day units.

Returns:

  • (Rational)


315
316
317
# File 'lib/timesteps/datetimelike.rb', line 315

def fraction ()
  return (60*(60*@hour + @minute) + @second.to_r).quo(86400)
end

#inspectObject

Returns the value as a string for inspection.



352
353
354
355
356
357
358
# File 'lib/timesteps/datetimelike.rb', line 352

def inspect
  sec  = fraction*86400
  isec = sec.floor
  fsec = ((sec - isec)*1000000).round
  offs = (offset*86400).round
  format("#<%s: %s ((%dj,%ds,%dn),%+ds)>", self.class, to_s, jd, isec, fsec, offs)
end

#jdInteger

Calculates Julian day number from date part. Note that this method does not take into account the offset and time. If you need a Julian day number that takes the time into account, use #ajd.

Returns:

  • (Integer)


152
153
154
# File 'lib/timesteps/datetimelike.rb', line 152

def jd
  return (self.class::DPY) * (@year + 4712) + (yday - 1)
end

#new_offset(offset = 0) ⇒ DateTime

Duplicates self and resets its offset.

Parameters:

  • offset (Numeric) (defaults to: 0)

Returns:



128
129
130
131
132
133
# File 'lib/timesteps/datetimelike.rb', line 128

def new_offset (offset = 0)
  gmt  = jd + fraction - @offset + offset.to_r
  jday = gmt.floor
  fday = gmt - gmt.floor
  return self.class.jd(jday, 0, 0, 0, offset) + fday
end

#next_day(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n days after self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


284
285
286
# File 'lib/timesteps/datetimelike.rb', line 284

def next_day (n = 1)
  return add_days(n)
end

#next_month(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n months after self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


257
258
259
# File 'lib/timesteps/datetimelike.rb', line 257

def next_month (n = 1)
  return add_months(n)
end

#next_year(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n years after self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


239
240
241
# File 'lib/timesteps/datetimelike.rb', line 239

def next_year (n = 1)
  return self.class::new(@year+n, @month, @day, @hour, @minute, @second, @offset)
end

#prev_day(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n days before self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


293
294
295
# File 'lib/timesteps/datetimelike.rb', line 293

def prev_day (n = 1)
  return add_days(-n)
end

#prev_month(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n months before self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


266
267
268
# File 'lib/timesteps/datetimelike.rb', line 266

def prev_month (n = 1)
  return add_months(-n)
end

#prev_year(n = 1) ⇒ DateTimeFixedDPY

Returns a date object pointing n years before self.

Parameters:

  • n (Integer) (defaults to: 1)

Returns:

  • (DateTimeFixedDPY)


248
249
250
# File 'lib/timesteps/datetimelike.rb', line 248

def prev_year (n = 1)
  return self.class::new(@year-n, @month, @day, @hour, @minute, @second, @offset)
end

#secondRational Also known as: sec

Returns the second (0-59)

Returns:

  • (Rational)


106
107
108
# File 'lib/timesteps/datetimelike.rb', line 106

def second
  return @second.floor
end

#second_fractionRational Also known as: sec_fraction

Returns the fractional part of the second.

Returns:

  • (Rational)


113
114
115
# File 'lib/timesteps/datetimelike.rb', line 113

def second_fraction
  return @second.to_r - @second.floor
end

#strftime(fmt = '%F') ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/timesteps/datetimelike_format.rb', line 132

def strftime(fmt='%F')
  
  fmt.gsub(/%([-_0^#]+)?(\d+)?([EO]?(?::{1,3}z|.))/m) do |m|
    f = {}
    a = $&
    s, w, c = $1, $2, $3
    if s
      s.scan(/./) do |k|
        case k
        when '-'; f[:p] = '-'
        when '_'; f[:p] = "\s"
        when '0'; f[:p] = '0'
        when '^'; f[:u] = true
        when '#'; f[:x] = true
        end
      end
    end
    if w
      f[:w] = w.to_i
    end
    case c
    when 'A'; emit_ad(DAYNAMES[wday], 0, f)
    when 'a'; emit_ad(ABBR_DAYNAMES[wday], 0, f)
    when 'B'; emit_ad(MONTHNAMES[month], 0, f)
    when 'b'; emit_ad(ABBR_MONTHNAMES[month], 0, f)
    when 'C', 'EC'; emit_sn((year / 100).floor, 2, f)
    when 'c', 'Ec'; emit_a(strftime('%a %b %e %H:%M:%S %Y'), 0, f)
    when 'D'; emit_a(strftime('%m/%d/%y'), 0, f)
    when 'd', 'Od'; emit_n(day, 2, f)
    when 'e', 'Oe'; emit_a(day, 2, f)
    when 'F'
      if m == '%F'
        format('%.4d-%02d-%02d', year, month, day) # 4p
      else
        emit_a(strftime('%Y-%m-%d'), 0, f)
      end
    when 'G'; emit_sn(cwyear, 4, f)
    when 'g'; emit_n(cwyear % 100, 2, f)
    when 'H', 'OH'; emit_n(hour, 2, f)
    when 'h'; emit_ad(strftime('%b'), 0, f)
    when 'I', 'OI'; emit_n((hour % 12).nonzero? || 12, 2, f)
    when 'j'; emit_n(yday, 3, f)
    when 'k'; emit_a(hour, 2, f)
    when 'L'
      emit_n((sec_fraction / MILLISECONDS_IN_SECOND).round, 3, f)
    when 'l'; emit_a((hour % 12).nonzero? || 12, 2, f)
    when 'M', 'OM'; emit_n(minute, 2, f)
    when 'm', 'Om'; emit_n(month, 2, f)
    when 'N'
      emit_n((sec_fraction / NANOSECONDS_IN_SECOND).round, 9, f)
    when 'n'; "\n"
    when 'P'; emit_ad(strftime('%p').downcase, 0, f)
    when 'p'; emit_au(if hour < 12 then 'AM' else 'PM' end, 0, f)
    when 'Q'
      s = ((ajd - self::class::UNIX_EPOCH_IN_AJD) / MILLISECONDS_IN_DAY).round
      emit_sn(s, 1, f)
    when 'R'; emit_a(strftime('%H:%M'), 0, f)
    when 'r'; emit_a(strftime('%I:%M:%S %p'), 0, f)
    when 'S', 'OS'; emit_n(second.floor, 2, f)
    when 's'
      s = ((ajd - self::class::UNIX_EPOCH_IN_AJD) / SECONDS_IN_DAY).round
      emit_sn(s, 1, f)
    when 'T'
      if m == '%T'
        format('%02d:%02d:%02d', hour, minute, second) # 4p
      else
        emit_a(strftime('%H:%M:%S'), 0, f)
      end
    when 't'; "\t"
    when 'U', 'W', 'OU', 'OW'
      emit_n(if c[-1,1] == 'U' then wnum0 else wnum1 end, 2, f)
    when 'u', 'Ou'; emit_n(cwday, 1, f)
    when 'V', 'OV'; emit_n(cweek, 2, f)
    when 'v'; emit_a(strftime('%e-%b-%Y'), 0, f)
    when 'w', 'Ow'; emit_n(wday, 1, f)
    when 'X', 'EX'; emit_a(strftime('%H:%M:%S'), 0, f)
    when 'x', 'Ex'; emit_a(strftime('%m/%d/%y'), 0, f)
    when 'Y', 'EY'; emit_sn(year, 4, f)
    when 'y', 'Ey', 'Oy'; emit_n(year % 100, 2, f)
    when 'Z'; emit_au(strftime('%:z'), 0, f)
    when /\A(:{0,3})z/
      t = $1.size
      sign = if offset < 0 then -1 else +1 end
      fr = offset.abs
      ss = fr.div(SECONDS_IN_DAY) # 4p
      hh, ss = ss.divmod(3600)
      mm, ss = ss.divmod(60)
      if t == 3
        if    ss.nonzero? then t =  2
        elsif mm.nonzero? then t =  1
        else                   t = -1
        end
      end
      case t
      when -1
        tail = []
        sep = ''
      when 0
        f[:w] -= 2 if f[:w]
        tail = ['%02d' % mm]
        sep = ''
      when 1
        f[:w] -= 3 if f[:w]
        tail = ['%02d' % mm]
        sep = ':'
      when 2
        f[:w] -= 6 if f[:w]
        tail = ['%02d' % mm, '%02d' % ss]
        sep = ':'
      end
      ([emit_z(sign * hh, 2, f)] + tail).join(sep)
    when '%'; emit_a('%', 0, f)
    when '+'; emit_a(strftime('%a %b %e %H:%M:%S %Z %Y'), 0, f)
    else
      a
    end
  end
end

#succDateTime Also known as: next

Returns a datetime object denoting the following day.

Returns:



306
307
308
# File 'lib/timesteps/datetimelike.rb', line 306

def succ
  return add_days(1)
end

#to_sObject

Returns a string in an ISO 8601 format.



342
343
344
345
346
347
348
# File 'lib/timesteps/datetimelike.rb', line 342

def to_s
  format("%04d-%02d-%02dT%02d:%02d:%02d%s%s",
         @year, @month, @day, 
         @hour, @minute, @second.floor, 
         format_microsec, 
         format_offset)
end

#wdayInteger

Returns the day of week (0-6, Sunday is zero).

Returns:

  • (Integer)


166
167
168
# File 'lib/timesteps/datetimelike.rb', line 166

def wday 
  return (jd + 1 ) % 7
end

#ydayInteger

Returns Day of Year

Returns:

  • (Integer)


138
139
140
141
142
143
144
145
# File 'lib/timesteps/datetimelike.rb', line 138

def yday
  dpm = self.class::DPM
  doy = @day
  (@month-1).step(1,-1) do |m|
    doy += dpm[m]
  end    
  return doy
end