Class: TimeCrisis::DateTime
- Inherits:
-
Date
show all
- Extended by:
- NthWeekday::ClassMethods
- Defined in:
- lib/time_crisis/datetime.rb,
lib/time_crisis/to_json.rb,
lib/time_crisis/support/ext/date_time/zones.rb,
lib/time_crisis/support/ext/date_time/acts_like.rb,
lib/time_crisis/support/ext/date_time/conversions.rb,
lib/time_crisis/support/ext/date_time/calculations.rb
Overview
TimeCrisis’s DateTime class, which builds on the Date class and adds a time component of hours, minutes, seconds, microseconds, and an offset from UTC. Taken from ThirdBase by Jeremy Evans.
Constant Summary
collapse
- TIME_ZONE_SECOND_OFFSETS =
{
'UTC'=>0, 'Z'=>0, 'UT'=>0, 'GMT'=>0,
'EST'=>-18000, 'EDT'=>-14400, 'CST'=>-21600, 'CDT'=>-18000, 'MST'=>-25200, 'MDT'=>-21600, 'PST'=>-28800, 'PDT'=>-25200,
'A'=>3600, 'B'=>7200, 'C'=>10800, 'D'=>14400, 'E'=>18000, 'F'=>21600, 'G'=>25200, 'H'=>28800, 'I'=>32400, 'K'=>36000, 'L'=>39600, 'M'=>43200,
'N'=>-3600, 'O'=>-7200, 'P'=>-10800, 'Q'=>-14400, 'R'=>-18000, 'S'=>-21600, 'T'=>-25200, 'U'=>-28800, 'V'=>-32400, 'W'=>-36000, 'X'=>-39600, 'Y'=>-43200}
- PARSER_LIST =
[]
- DEFAULT_PARSER_LIST =
[:time, :iso, :us, :num]
- DEFAULT_PARSERS =
{}
- TIME_ZONE_RE_STRING =
"(#{TIME_ZONE_SECOND_OFFSETS.keys.sort.join('|')}|[+-](?:\\d\\d:?(?:\\d\\d)?))"
- TIME_RE_STRING =
"(?:[T ]?([\\d ]?\\d):(\\d\\d)(?::(\\d\\d(\\.\\d+)?))?([ap]m?)? ?#{TIME_ZONE_RE_STRING}?)?"
- 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 {|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)
}
- STRPTIME_PROC_z =
proc {|h,x| h[:offset] = convert_parsed_offset(x)}
Constants inherited
from Date
TimeCrisis::Date::ABBR_DAYNAMES, TimeCrisis::Date::ABBR_DAYNAME_RE_PATTERN, TimeCrisis::Date::ABBR_MONTHNAMES, TimeCrisis::Date::ABBR_MONTHNAME_RE_PATTERN, TimeCrisis::Date::CUMMULATIVE_MONTH_DAYS, TimeCrisis::Date::DATE_FORMATS, TimeCrisis::Date::DAYNAMES, TimeCrisis::Date::DAYS_IN_MONTH, TimeCrisis::Date::DAY_NUM_MAP, TimeCrisis::Date::FULL_DAYNAME_RE_PATTERN, TimeCrisis::Date::FULL_MONTHNAME_RE_PATTERN, TimeCrisis::Date::LEAP_CUMMULATIVE_MONTH_DAYS, TimeCrisis::Date::LEAP_DAYS_IN_MONTH, TimeCrisis::Date::MONTHNAMES, TimeCrisis::Date::MONTHNAME_RE_PATTERN, TimeCrisis::Date::MONTH_NUM_MAP, TimeCrisis::Date::PARSERS, TimeCrisis::Date::STRFTIME_RE, TimeCrisis::Date::STRPTIME_PROC_A, TimeCrisis::Date::STRPTIME_PROC_B, TimeCrisis::Date::STRPTIME_PROC_C, TimeCrisis::Date::STRPTIME_PROC_G, TimeCrisis::Date::STRPTIME_PROC_V, TimeCrisis::Date::STRPTIME_PROC_Y, TimeCrisis::Date::STRPTIME_PROC_d, TimeCrisis::Date::STRPTIME_PROC_g, TimeCrisis::Date::STRPTIME_PROC_j, TimeCrisis::Date::STRPTIME_PROC_m, TimeCrisis::Date::STRPTIME_PROC_u, TimeCrisis::Date::STRPTIME_PROC_y, TimeCrisis::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.
-
.current ⇒ Object
-
.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.
-
.local_offset ⇒ Object
-
.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
nth_weekday
Methods inherited from Date
#<<, #===, #>>, add_parser, add_parser_type, #beginning_of_month, #beginning_of_quarter, #beginning_of_week, #beginning_of_year, #cwday, #cweek, #cwyear, #day, #days_in_month, #downto, #end_of_month, #end_of_quarter, #end_of_week, #end_of_year, #hash, #jd, #last_month, #last_year, #leap?, #minus_with_duration, #mon, #months_ago, #months_since, new, new!, #next_month, #next_week, #next_year, parse, #plus_with_duration, reset_parsers!, #step, #strftime, strptime, #succ, today, #today?, tomorrow, #tomorrow, #upto, use_parsers, #wday, #yday, #year, #years_ago, #years_since, yesterday, #yesterday
#range
#april, #august, #december, #february, #january, #july, #june, #march, #may, #month_range, #november, #october, #september
#beginning_of_meteorological_autumn, #beginning_of_meteorological_spring, #beginning_of_meteorological_summer, #beginning_of_meteorological_winter
Constructor Details
#initialize(opts) ⇒ DateTime
Called by DateTime.new!, should be a hash with the following possible keys:
-
:civil, :commericial, :jd, :ordinal : See TimeCrisis::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.
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
# File 'lib/time_crisis/datetime.rb', line 267
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
Which parts of this datetime were guessed instead of being parsed from the input.
257
258
259
|
# File 'lib/time_crisis/datetime.rb', line 257
def not_parsed
@not_parsed
end
|
#offset ⇒ Object
Also known as:
utc_offset
This datetime’s offset from UTC, in seconds.
243
244
245
|
# File 'lib/time_crisis/datetime.rb', line 243
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.
72
73
74
|
# File 'lib/time_crisis/datetime.rb', line 72
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.
78
79
80
|
# File 'lib/time_crisis/datetime.rb', line 78
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
166
167
168
169
170
171
172
173
|
# File 'lib/time_crisis/datetime.rb', line 166
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.
83
84
85
|
# File 'lib/time_crisis/datetime.rb', line 83
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.
88
89
90
|
# File 'lib/time_crisis/datetime.rb', line 88
def self.jd_fract(jd, fract=0.0, offset=0)
new!(:jd=>jd, :fract=>fract, :offset=>offset)
end
|
.local_offset ⇒ Object
6
7
8
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 6
def local_offset
::TimeCrisis::Time.local(2007).utc_offset
end
|
Create a new DateTime with the current date and time.
93
94
95
96
|
# File 'lib/time_crisis/datetime.rb', line 93
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.
99
100
101
|
# File 'lib/time_crisis/datetime.rb', line 99
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
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.
287
288
289
290
291
292
293
294
295
296
297
298
299
|
# File 'lib/time_crisis/datetime.rb', line 287
def +(d)
case
when d.is_a?(Integer)
new_jd(jd+d)
when d.respond_to?(:to_f)
d, f = d.to_f.divmod(1)
f = fract + f
m, f = f.divmod(1)
self.class.jd_fract(jd+d+m, f, @offset)
else
raise TypeError, "d must be an Integer or respond to :to_f"
end
end
|
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.
304
305
306
307
308
309
310
311
312
313
314
315
|
# File 'lib/time_crisis/datetime.rb', line 304
def -(d)
case
when d.is_a?(::TimeCrisis::DateTime)
(jd - d.jd) + (fract - d.fract) + (@offset - d.offset)/86400.0
when d.is_a?(Integer)
self + -d
when d.respond_to?(:to_f)
self + -(d.to_f)
else
raise TypeError, "d should be a TimeCrisis::DateTime, Integer, or respond to :to_f"
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.
346
347
348
349
|
# File 'lib/time_crisis/datetime.rb', line 346
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
|
#acts_like_date? ⇒ Boolean
5
6
7
|
# File 'lib/time_crisis/support/ext/date_time/acts_like.rb', line 5
def acts_like_date?
true
end
|
#acts_like_time? ⇒ Boolean
9
10
11
|
# File 'lib/time_crisis/support/ext/date_time/acts_like.rb', line 9
def acts_like_time?
true
end
|
#advance(options) ⇒ Object
40
41
42
43
44
45
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 40
def advance(options)
d = to_tc_date.advance(options)
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date.since(seconds_to_advance)
end
|
#ago(seconds) ⇒ Object
47
48
49
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 47
def ago(seconds)
since(-seconds)
end
|
#beginning_of_day ⇒ Object
Also known as:
midnight, at_midnight, at_beginning_of_day
56
57
58
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 56
def beginning_of_day
change(:hour => 0)
end
|
#change(options = {}) ⇒ Object
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 27
def change(options={})
::TimeCrisis::DateTime.civil(
options[:year] || year,
options[:month] || month,
options[:day] || day,
options[:hour] || hour,
options[:min] || (options[:hour] ? 0 : min),
options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec),
options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : usec),
options[:offset] || offset
)
end
|
#compare_with_coercion(other) ⇒ Object
Also known as:
<=>
80
81
82
83
84
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 80
def compare_with_coercion(other)
other = other.comparable_time if other.respond_to?(:comparable_time)
other = other.to_tc_datetime unless other.acts_like?(:date)
compare_without_coercion(other)
end
|
#end_of_day ⇒ Object
63
64
65
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 63
def end_of_day
change(:hour => 23, :min => 59, :sec => 59)
end
|
13
14
15
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 13
def formatted_offset(colon = true, alternate_utc_string = nil)
utc? && alternate_utc_string || TimeCrisis::TimeZone.seconds_to_utc_offset(utc_offset, colon)
end
|
Returns the fraction of the day for this datetime (Noon is 0.5)
353
354
355
|
# File 'lib/time_crisis/datetime.rb', line 353
def fract
@fract ||= (@hour*3600+@min*60+@sec+@usec/1000000.0)/86400.0
end
|
#future? ⇒ Boolean
19
20
21
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 19
def future?
self > ::TimeCrisis::DateTime.current
end
|
Returns the hour of this datetime.
358
359
360
|
# File 'lib/time_crisis/datetime.rb', line 358
def hour
@hour ||= time_parts[0]
end
|
#in_time_zone(zone = ::TimeCrisis::Time.zone) ⇒ Object
Returns the minute of this datetime.
363
364
365
|
# File 'lib/time_crisis/datetime.rb', line 363
def min
@min ||= time_parts[1]
end
|
#new_offset(of) ⇒ Object
compatibility method for TZInfo
247
248
249
250
251
252
253
254
|
# File 'lib/time_crisis/datetime.rb', line 247
def new_offset(of)
if of.is_a?(Rational)
of = (1 + of) if of < 0
of = of * 86400
end
self.class.new!(:jd=>jd, :parts=>[hour, min, sec, usec], :offset=>of.to_i)
end
|
#past? ⇒ Boolean
15
16
17
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 15
def past?
self < ::TimeCrisis::DateTime.current
end
|
#readable_inspect ⇒ Object
Also known as:
inspect
17
18
19
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 17
def readable_inspect
"#<TimeCrisis::DateTime #{self.to_s(:rfc822)}>"
end
|
Returns the second of this datetime.
368
369
370
|
# File 'lib/time_crisis/datetime.rb', line 368
def sec
@sec ||= time_parts[2]
end
|
#seconds_since_midnight ⇒ Object
23
24
25
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 23
def seconds_since_midnight
sec + (min * 60) + (hour * 3600)
end
|
#since(seconds) ⇒ Object
Also known as:
in
51
52
53
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 51
def since(seconds)
self + Rational(seconds.round, 86400).to_f
end
|
23
24
25
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 23
def to_date
::Date.civil(year, month, day)
end
|
#to_datetime ⇒ Object
35
36
37
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 35
def to_datetime
::DateTime.civil(year, month, day, hour, min, second, Rational(offset, 86400))
end
|
51
52
53
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 51
def to_f
seconds_since_unix_epoch.to_f
end
|
3
4
5
6
7
8
9
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 3
def to_formatted_s(format = :default)
if formatter = ::TimeCrisis::Time::DATE_FORMATS[format]
formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
else
to_default_s
end
end
|
55
56
57
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 55
def to_i
seconds_since_unix_epoch.to_i
end
|
#to_json(options = nil) ⇒ Object
9
10
11
|
# File 'lib/time_crisis/to_json.rb', line 9
def to_json(options = nil)
xmlschema.inspect
end
|
#to_tc_date ⇒ Object
27
28
29
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 27
def to_tc_date
::TimeCrisis::Date.civil(year, month, day)
end
|
#to_tc_datetime ⇒ Object
31
32
33
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 31
def to_tc_datetime
self
end
|
#to_tc_time ⇒ Object
43
44
45
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 43
def to_tc_time
::TimeCrisis::Time.at(self.to_f)
end
|
39
40
41
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 39
def to_time
::Time.at(self.to_f)
end
|
Returns the microsecond of this datetime.
373
374
375
|
# File 'lib/time_crisis/datetime.rb', line 373
def usec
@usec ||= time_parts[3]
end
|
#utc ⇒ Object
Also known as:
getutc
67
68
69
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 67
def utc
new_offset(0)
end
|
#utc? ⇒ Boolean
72
73
74
|
# File 'lib/time_crisis/support/ext/date_time/calculations.rb', line 72
def utc?
offset == 0
end
|
#xmlschema ⇒ Object
47
48
49
|
# File 'lib/time_crisis/support/ext/date_time/conversions.rb', line 47
def xmlschema
strftime("%Y-%m-%dT%H:%M:%S%Z")
end
|
Return the offset as a time zone string (+/-HHMM).
378
379
380
|
# File 'lib/time_crisis/datetime.rb', line 378
def zone
strftime('%Z')
end
|