Class: ThirdBase::DateTime
Overview
ThirdBase’s DateTime class, which builds on the Date class and adds a time component of hours, minutes, seconds, microseconds, and an offset from UTC.
Constant Summary collapse
- PARSER_LIST =
[]
- DEFAULT_PARSER_LIST =
[:time, :iso, :us, :num]
- DEFAULT_PARSERS =
{}
- TIME_RE_STRING =
'(?:[T ]?([\d ]?\d):(\d\d)(?::(\d\d(\.\d+)?))?([ap]m?)? ?(Z|[+-](?:\d\d:?(?:\d\d)?))?)?'
- STRPTIME_PROC_H =
proc{|h,x| h[:hour] = x.to_i}
- STRPTIME_PROC_M =
proc{|h,x| h[:min] = x.to_i}
- STRPTIME_PROC_P =
proc{|h,x| h[:meridian] = x.downcase == 'pm' ? :pm : :am}
- STRPTIME_PROC_S =
proc{|h,x| h[:sec] = x.to_i}
- STRPTIME_PROC_s =
proc do |h,x| j, i = x.to_i.divmod(86400) hours, i = i.divmod(3600) minutes, seconds = i.divmod(60) h.merge!(:jd=>j+UNIXEPOCH, :hour=>hours, :min=>minutes, :sec=>seconds) end
- STRPTIME_PROC_z =
proc{|h,x| x=x.gsub(':',''); h[:offset] = (x == 'Z' ? 0 : x[0..2].to_i*3600 + x[3..4].to_i*60)}
Constants inherited from Date
ThirdBase::Date::ABBR_DAYNAMES, ThirdBase::Date::ABBR_DAYNAME_RE_PATTERN, ThirdBase::Date::ABBR_MONTHNAMES, ThirdBase::Date::ABBR_MONTHNAME_RE_PATTERN, ThirdBase::Date::CUMMULATIVE_MONTH_DAYS, ThirdBase::Date::DAYNAMES, ThirdBase::Date::DAYS_IN_MONTH, ThirdBase::Date::DAY_NUM_MAP, ThirdBase::Date::FULL_DAYNAME_RE_PATTERN, ThirdBase::Date::FULL_MONTHNAME_RE_PATTERN, ThirdBase::Date::LEAP_CUMMULATIVE_MONTH_DAYS, ThirdBase::Date::LEAP_DAYS_IN_MONTH, ThirdBase::Date::MONTHNAMES, ThirdBase::Date::MONTHNAME_RE_PATTERN, ThirdBase::Date::MONTH_NUM_MAP, ThirdBase::Date::PARSERS, ThirdBase::Date::STRFTIME_RE, ThirdBase::Date::STRPTIME_PROC_A, ThirdBase::Date::STRPTIME_PROC_B, ThirdBase::Date::STRPTIME_PROC_C, ThirdBase::Date::STRPTIME_PROC_G, ThirdBase::Date::STRPTIME_PROC_V, ThirdBase::Date::STRPTIME_PROC_Y, ThirdBase::Date::STRPTIME_PROC_d, ThirdBase::Date::STRPTIME_PROC_g, ThirdBase::Date::STRPTIME_PROC_j, ThirdBase::Date::STRPTIME_PROC_m, ThirdBase::Date::STRPTIME_PROC_u, ThirdBase::Date::STRPTIME_PROC_y, ThirdBase::Date::UNIXEPOCH
Instance Attribute Summary collapse
-
#not_parsed ⇒ Object
readonly
Which parts of this datetime were guessed instead of being parsed from the input.
-
#offset ⇒ Object
(also: #utc_offset)
readonly
This datetime’s offset from UTC, in seconds.
Class Method Summary collapse
-
.civil(year, mon, day, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given year, month, day of month, hour, minute, second, microsecond and offset.
-
.commercial(cwyear, cweek, cwday = 5, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given commercial week year, commercial week, commercial week day, hour, minute second, microsecond, and offset.
- .hour_with_meridian(hour, meridian) ⇒ Object
-
.jd(jd, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given julian date, hour, minute, second, microsecond, and offset.
-
.jd_fract(jd, fract = 0.0, offset = 0) ⇒ Object
Create a new DateTime with the given julian day, fraction of the day (0.5 is Noon), and offset.
-
.now ⇒ Object
Create a new DateTime with the current date and time.
-
.ordinal(year, yday, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given year, day of year, hour, minute, second, microsecond, and offset.
Instance Method Summary collapse
-
#+(d) ⇒ Object
Return a new datetune with the given number of days added to this datetime.
-
#-(d) ⇒ Object
Return a new datetune with the given number of days subtracted from this datetime.
-
#<=>(datetime) ⇒ Object
Compares two datetimes.
-
#==(datetime) ⇒ Object
(also: #eql?)
Two DateTimes are equal only if their dates and time components are the same, not counting the offset.
-
#fract ⇒ Object
Returns the fraction of the day for this datetime (Noon is 0.5).
-
#hour ⇒ Object
Returns the hour of this datetime.
-
#initialize(opts) ⇒ DateTime
constructor
Called by DateTime.new!, should be a hash with the following possible keys:.
-
#min ⇒ Object
Returns the minute of this datetime.
-
#sec ⇒ Object
Returns the second of this datetime.
-
#usec ⇒ Object
Returns the microsecond of this datetime.
-
#zone ⇒ Object
Return the offset as a time zone string (+/-HHMM).
Methods inherited from Date
#<<, #===, #>>, add_parser, add_parser_type, #cwday, #cweek, #cwyear, #day, #downto, #hash, #inspect, #jd, #leap?, #mon, new, new!, parse, reset_parsers!, #step, #strftime, strptime, #succ, #to_s, today, #upto, use_parsers, #wday, #yday, #year
Constructor Details
#initialize(opts) ⇒ DateTime
Called by DateTime.new!, should be a hash with the following possible keys:
-
:civil, :commericial, :jd, :ordinal : See ThirdBase::Date#initialize
-
:fract : The fraction of the day (0.5 is Noon)
-
:offset : offset from UTC, in seconds.
-
:parts : an array with 4 elements, hour, minute, second, and microsecond
Raises an ArgumentError if an invalid date is used. DateTime objects are immutable once created.
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/third_base/datetime.rb', line 235 def initialize(opts) @not_parsed = opts[:not_parsed] || [] @offset = opts[:offset] raise(ArgumentError, 'invalid datetime') unless @offset.is_a?(Integer) and @offset <= 43200 and @offset >= -43200 if opts[:parts] @hour, @min, @sec, @usec = opts[:parts] raise(ArgumentError, 'invalid datetime') unless @hour.is_a?(Integer) and @min.is_a?(Integer) and @sec.is_a?(Integer) and @usec.is_a?(Integer) elsif opts[:fract] @fract = opts[:fract] raise(ArgumentError, 'invalid datetime') unless @fract.is_a?(Float) and @fract < 1.0 and @fract >= 0.0 else raise(ArgumentError, 'invalid datetime') end super(opts) end |
Instance Attribute Details
#not_parsed ⇒ Object (readonly)
Which parts of this datetime were guessed instead of being parsed from the input.
225 226 227 |
# File 'lib/third_base/datetime.rb', line 225 def not_parsed @not_parsed end |
#offset ⇒ Object (readonly) Also known as: utc_offset
This datetime’s offset from UTC, in seconds.
221 222 223 |
# File 'lib/third_base/datetime.rb', line 221 def offset @offset end |
Class Method Details
.civil(year, mon, day, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given year, month, day of month, hour, minute, second, microsecond and offset.
66 67 68 |
# File 'lib/third_base/datetime.rb', line 66 def self.civil(year, mon, day, hour=0, min=0, sec=0, usec=0, offset=0) new!(:civil=>[year, mon, day], :parts=>[hour, min, sec, usec], :offset=>offset) end |
.commercial(cwyear, cweek, cwday = 5, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given commercial week year, commercial week, commercial week day, hour, minute second, microsecond, and offset.
72 73 74 |
# File 'lib/third_base/datetime.rb', line 72 def self.commercial(cwyear, cweek, cwday=5, hour=0, min=0, sec=0, usec=0, offset=0) new!(:commercial=>[cwyear, cweek, cwday], :parts=>[hour, min, sec, usec], :offset=>offset) end |
.hour_with_meridian(hour, meridian) ⇒ Object
161 162 163 164 165 166 167 168 |
# File 'lib/third_base/datetime.rb', line 161 def self.hour_with_meridian(hour, meridian) raise(ArgumentError, 'invalid date') unless hour and hour >= 1 and hour <= 12 if meridian == :am hour == 12 ? 0 : hour else hour < 12 ? hour + 12 : hour end end |
.jd(jd, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given julian date, hour, minute, second, microsecond, and offset.
77 78 79 |
# File 'lib/third_base/datetime.rb', line 77 def self.jd(jd, hour=0, min=0, sec=0, usec=0, offset=0) new!(:jd=>jd, :parts=>[hour, min, sec, usec], :offset=>offset) end |
.jd_fract(jd, fract = 0.0, offset = 0) ⇒ Object
Create a new DateTime with the given julian day, fraction of the day (0.5 is Noon), and offset.
82 83 84 |
# File 'lib/third_base/datetime.rb', line 82 def self.jd_fract(jd, fract=0.0, offset=0) new!(:jd=>jd, :fract=>fract, :offset=>offset) end |
.now ⇒ Object
Create a new DateTime with the current date and time.
87 88 89 90 |
# File 'lib/third_base/datetime.rb', line 87 def self.now t = Time.now new!(:civil=>[t.year, t.mon, t.day], :parts=>[t.hour, t.min, t.sec, t.usec], :offset=>t.utc_offset) end |
.ordinal(year, yday, hour = 0, min = 0, sec = 0, usec = 0, offset = 0) ⇒ Object
Create a new DateTime with the given year, day of year, hour, minute, second, microsecond, and offset.
93 94 95 |
# File 'lib/third_base/datetime.rb', line 93 def self.ordinal(year, yday, hour=0, min=0, sec=0, usec=0, offset=0) new!(:ordinal=>[year, yday], :parts=>[hour, min, sec, usec], :offset=>offset) end |
Instance Method Details
#+(d) ⇒ Object
Return a new datetune with the given number of days added to this datetime. If d is a Float adds a fractional date, with possible loss of precision. If d is an integer, the returned date has the same time components as the current date. In both cases, the offset for the new date is the same as for this date.
255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/third_base/datetime.rb', line 255 def +(d) case d when Float d, f = d.to_f.divmod(1) f = fract + f m, f = f.divmod(1) self.class.jd_fract(jd+d+m, f, @offset) when Integer new_jd(jd+d) else raise(TypeError, "d must be a Float or Integer") end end |
#-(d) ⇒ Object
Return a new datetune with the given number of days subtracted from this datetime. If d is a DateTime, returns the difference between the two datetimes as a Float, considering both datetimes date, time, and offest.
272 273 274 275 276 277 278 279 280 281 |
# File 'lib/third_base/datetime.rb', line 272 def -(d) case d when self.class (jd - d.jd) + (fract - d.fract) + (@offset - d.offset)/86400.0 when Integer, Float self + -d else raise TypeError, "d should be #{self.class}, Float, or Integer" end end |
#<=>(datetime) ⇒ Object
Compares two datetimes. If the given datetime is an Integer, returns 1 unless this datetime’s time components are all 0, in which case it returns 0. If the given datetime is a Float, calculates this date’s julian date plus the date fraction and compares it to the given datetime, and returns 0 only if the two are very close together. This code does not take into account time offsets.
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/third_base/datetime.rb', line 288 def <=>(datetime) case datetime when Integer if ((d = (jd <=> datetime)) == 0) (hour == 0 and min == 0 and sec == 0 and usec == 0) ? 0 : 1 else d end when Float diff = jd+fract - datetime if diff.abs <= 1.15740740740741e-011 0 else diff > 0.0 ? 1 : -1 end when self.class ((d = super) == 0) && ((d = (hour <=> datetime.hour)) == 0) && ((d = (min <=> datetime.min)) == 0) && ((d = (sec <=> datetime.sec)) == 0) && ((d = (usec <=> datetime.usec)) == 0) d else raise TypeError, "d should be #{self.class}, Float, or Integer" end end |
#==(datetime) ⇒ Object Also known as: eql?
Two DateTimes are equal only if their dates and time components are the same, not counting the offset.
312 313 314 315 |
# File 'lib/third_base/datetime.rb', line 312 def ==(datetime) return false unless DateTime === datetime super and hour == datetime.hour and min == datetime.min and sec == datetime.sec and usec == datetime.usec end |
#fract ⇒ Object
Returns the fraction of the day for this datetime (Noon is 0.5)
319 320 321 |
# File 'lib/third_base/datetime.rb', line 319 def fract @fract ||= (@hour*3600+@min*60+@sec+@usec/1000000.0)/86400.0 end |
#hour ⇒ Object
Returns the hour of this datetime.
324 325 326 |
# File 'lib/third_base/datetime.rb', line 324 def hour @hour ||= time_parts[0] end |
#min ⇒ Object
Returns the minute of this datetime.
329 330 331 |
# File 'lib/third_base/datetime.rb', line 329 def min @min ||= time_parts[1] end |
#sec ⇒ Object
Returns the second of this datetime.
334 335 336 |
# File 'lib/third_base/datetime.rb', line 334 def sec @sec ||= time_parts[2] end |
#usec ⇒ Object
Returns the microsecond of this datetime.
339 340 341 |
# File 'lib/third_base/datetime.rb', line 339 def usec @usec ||= time_parts[3] end |
#zone ⇒ Object
Return the offset as a time zone string (+/-HHMM).
344 345 346 |
# File 'lib/third_base/datetime.rb', line 344 def zone strftime('%z') end |