Class: RiCal::FastDateTime
- Includes:
- Comparable
- Defined in:
- lib/ri_cal/fast_date_time.rb
Overview
FastDateTime mimics the Ruby Standard library DateTime class but avoids the use of Rational Instead of using a Rational for the utc offset, FastDateTime uses an integer seconds value
Constant Summary collapse
- SECONDS_IN_A_DAY =
60*60*24
Instance Attribute Summary collapse
-
#date ⇒ Object
Returns the value of attribute date.
-
#hour ⇒ Object
Returns the value of attribute hour.
-
#min ⇒ Object
Returns the value of attribute min.
-
#offset ⇒ Object
(also: #utc_offset_seconds)
Returns the value of attribute offset.
-
#sec ⇒ Object
Returns the value of attribute sec.
-
#secs_since_bod ⇒ Object
Returns the value of attribute secs_since_bod.
Class Method Summary collapse
- .from_date(date) ⇒ Object
- .from_date_at_end_of_day(date) ⇒ Object
- .from_date_time(date_time) ⇒ Object
- .from_time(time) ⇒ Object
- .parse(val, just_date = false) ⇒ Object
Instance Method Summary collapse
- #<=>(other) ⇒ Object
- #==(other) ⇒ Object
- #adjust_day_delta(day_delta, new_secs_since_bod) ⇒ Object
-
#advance(options) ⇒ Object
:nodoc:.
-
#change(options) ⇒ Object
Return a new FastDateTime based on the receiver but with changes specified by the options.
- #cmp_fast_date_time_value(other) ⇒ Object
- #day ⇒ Object
-
#days_in_month ⇒ Object
def jd date.jd end.
- #hms_to_seconds(hours, minutes, seconds) ⇒ Object
- #ical_date_str ⇒ Object
- #ical_str ⇒ Object
-
#initialize(year, month, day, hour, min, sec, offset_seconds) ⇒ FastDateTime
constructor
A new instance of FastDateTime.
- #iso_weeks_in_year(wkst) ⇒ Object
- #iso_year_and_week_one_start(wkst) ⇒ Object
- #iso_year_start(wkst) ⇒ Object
- #month ⇒ Object (also: #mon)
-
#nth_wday_in_month(n, which_wday) ⇒ Object
e.g.
-
#nth_wday_in_year(n, which_wday) ⇒ Object
e.g.
- #seconds_to_hms(total_seconds) ⇒ Object
-
#start_of_week_with_wkst(wkst) ⇒ Object
Return a DateTime which is the beginning of the first day on or before the receiver with the specified wday.
- #to_datetime ⇒ Object
- #to_s ⇒ Object (also: #inspect)
-
#utc ⇒ Object
def new_offset(ofst) if ofst == offset self else advance(:seconds => offset - ofset, :offset => ofst) end end.
- #wday ⇒ Object
- #year ⇒ Object
Constructor Details
#initialize(year, month, day, hour, min, sec, offset_seconds) ⇒ FastDateTime
Returns a new instance of FastDateTime.
11 12 13 14 15 |
# File 'lib/ri_cal/fast_date_time.rb', line 11 def initialize(year, month, day, hour, min, sec, offset_seconds) @date = Date.civil(year, month, day) @secs_since_bod = hms_to_seconds(hour, min, sec) @hour, @min, @sec, @offset = hour, min, sec, offset_seconds end |
Instance Attribute Details
#date ⇒ Object
Returns the value of attribute date.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def date @date end |
#hour ⇒ Object
Returns the value of attribute hour.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def hour @hour end |
#min ⇒ Object
Returns the value of attribute min.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def min @min end |
#offset ⇒ Object Also known as: utc_offset_seconds
Returns the value of attribute offset.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def offset @offset end |
#sec ⇒ Object
Returns the value of attribute sec.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def sec @sec end |
#secs_since_bod ⇒ Object
Returns the value of attribute secs_since_bod.
5 6 7 |
# File 'lib/ri_cal/fast_date_time.rb', line 5 def secs_since_bod @secs_since_bod end |
Class Method Details
.from_date(date) ⇒ Object
41 42 43 |
# File 'lib/ri_cal/fast_date_time.rb', line 41 def self.from_date(date) new(date.year, date.month, date.day, 0, 0, 0, 0) end |
.from_date_at_end_of_day(date) ⇒ Object
45 46 47 |
# File 'lib/ri_cal/fast_date_time.rb', line 45 def self.from_date_at_end_of_day(date) new(date.year, date.month, date.day, 23, 59, 59, 0) end |
.from_date_time(date_time) ⇒ Object
33 34 35 |
# File 'lib/ri_cal/fast_date_time.rb', line 33 def self.from_date_time(date_time) new(date_time.year, date_time.month, date_time.day, date_time.hour, date_time.min, date_time.sec, (date_time.offset * SECONDS_IN_A_DAY).to_i) end |
.from_time(time) ⇒ Object
37 38 39 |
# File 'lib/ri_cal/fast_date_time.rb', line 37 def self.from_time(time) new(time.year, time.month, time.day, time.hour, time.min, time.sec, (time.utc_offset.offset * SECONDS_IN_A_DAY)) end |
.parse(val, just_date = false) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/ri_cal/fast_date_time.rb', line 17 def self.parse(val, just_date = false) if match_data = /\A(\d{4})(\d{2})(\d{2})(?:T(\d{2})(\d{2})(\d{2})(?:(Z)|(?:(-|\+)(\d{2})(\d{2})))?)?\z/.match(val.strip) year, month, day, hour, minute, second, utc, tzsign, tzhour, tzminute = *match_data[1..-1] if just_date hour, minute, second, timezone = 0 elsif hour timezone = utc ? 0 : tzsign ? (tzsign == '-' ? -1 : 1) * (tzhour.to_i * 60 + tzminute.to_i) * 60 : 0 end new(year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i, timezone.to_i) elsif just_date from_date_time(::DateTime.parse(::DateTime.parse(val).strftime("%Y%m%d"))) else from_date_time(::DateTime.parse(val)) end end |
Instance Method Details
#<=>(other) ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/ri_cal/fast_date_time.rb', line 85 def <=> (other) if FastDateTime === other [date, secs_since_bod] <=> [other.date, other.secs_since_bod] else [year, month, day, hour, min, sec] <=> [other.year, other.month, other.day, other.hour, other.min, other.sec] end end |
#==(other) ⇒ Object
81 82 83 |
# File 'lib/ri_cal/fast_date_time.rb', line 81 def ==(other) [date, secs_since_bod, offset] == [other.date, other.secs_since_bod, other.offset] end |
#adjust_day_delta(day_delta, new_secs_since_bod) ⇒ Object
149 150 151 152 153 154 155 156 157 158 |
# File 'lib/ri_cal/fast_date_time.rb', line 149 def adjust_day_delta(day_delta, new_secs_since_bod) if new_secs_since_bod == 0 [day_delta, new_secs_since_bod] elsif new_secs_since_bod > 0 [day_delta + (new_secs_since_bod / SECONDS_IN_A_DAY), new_secs_since_bod % SECONDS_IN_A_DAY] else [day_delta - (1 + new_secs_since_bod.abs / SECONDS_IN_A_DAY), SECONDS_IN_A_DAY - (new_secs_since_bod.abs % SECONDS_IN_A_DAY)] end end |
#advance(options) ⇒ Object
:nodoc:
161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/ri_cal/fast_date_time.rb', line 161 def advance() # :nodoc: new_date = @date new_offset = [:offset] || offset month_delta = ([:years] || 0) * 12 + ([:months] || 0) day_delta = ([:weeks] || 0) * 7 + ([:days] || 0) sec_delta = hms_to_seconds(([:hours] || 0), ([:minutes] || 0), ([:seconds] || 0)) day_delta, new_secs_since_bod = *adjust_day_delta(day_delta, secs_since_bod + sec_delta) new_hour, new_min, new_sec = *seconds_to_hms(new_secs_since_bod) new_date = new_date >> month_delta unless month_delta == 0 new_date += day_delta unless day_delta == 0 FastDateTime.new(new_date.year, new_date.month, new_date.day, new_hour, new_min, new_sec, new_offset) end |
#change(options) ⇒ Object
Return a new FastDateTime based on the receiver but with changes specified by the options
108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ri_cal/fast_date_time.rb', line 108 def change() FastDateTime.new( [:year] || year, [:month] || month, [:day] || day, [:hour] || hour, [:min] || ([:hour] ? 0 : min), [:sec] || (([:hour] || [:min]) ? 0 : sec), [:offset] || offset ) end |
#cmp_fast_date_time_value(other) ⇒ Object
240 241 242 |
# File 'lib/ri_cal/fast_date_time.rb', line 240 def cmp_fast_date_time_value(other) other <=> self end |
#day ⇒ Object
69 70 71 |
# File 'lib/ri_cal/fast_date_time.rb', line 69 def day @date.day end |
#days_in_month ⇒ Object
def jd
date.jd
end
101 102 103 |
# File 'lib/ri_cal/fast_date_time.rb', line 101 def days_in_month date.days_in_month end |
#hms_to_seconds(hours, minutes, seconds) ⇒ Object
136 137 138 |
# File 'lib/ri_cal/fast_date_time.rb', line 136 def hms_to_seconds(hours, minutes, seconds) seconds + 60 *(minutes + (60 * hours)) end |
#ical_date_str ⇒ Object
55 56 57 |
# File 'lib/ri_cal/fast_date_time.rb', line 55 def ical_date_str "%04d%02d%02d" % [year, month, day] end |
#ical_str ⇒ Object
51 52 53 |
# File 'lib/ri_cal/fast_date_time.rb', line 51 def ical_str "%04d%02d%02dT%02d%02d%02d" % [year, month, day, hour, min, sec] end |
#iso_weeks_in_year(wkst) ⇒ Object
228 229 230 |
# File 'lib/ri_cal/fast_date_time.rb', line 228 def iso_weeks_in_year(wkst) @date.iso_weeks_in_year(wkst) end |
#iso_year_and_week_one_start(wkst) ⇒ Object
236 237 238 |
# File 'lib/ri_cal/fast_date_time.rb', line 236 def iso_year_and_week_one_start(wkst) @date.iso_year_and_week_one_start(wkst) end |
#iso_year_start(wkst) ⇒ Object
232 233 234 |
# File 'lib/ri_cal/fast_date_time.rb', line 232 def iso_year_start(wkst) @date.iso_year_start(wkst) end |
#month ⇒ Object Also known as: mon
63 64 65 |
# File 'lib/ri_cal/fast_date_time.rb', line 63 def month @date.month end |
#nth_wday_in_month(n, which_wday) ⇒ Object
e.g. to obtain the 3nd Tuesday of the receivers month use
time.nth_wday_in_month(2, 2)
183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/ri_cal/fast_date_time.rb', line 183 def nth_wday_in_month(n, which_wday) first_of_month = change(:day => 1) first_in_month = first_of_month.advance(:days => (which_wday - first_of_month.wday)) first_in_month = first_in_month.advance(:days => 7) if first_in_month.month != first_of_month.month if n > 0 first_in_month.advance(:days => (7*(n - 1))) else possible = first_in_month.advance(:days => 21) possible = possible.advance(:days => 7) while possible.month == first_in_month.month last_in_month = possible.advance(:days => - 7) (last_in_month.advance(:days => - (7*(n.abs - 1)))) end end |
#nth_wday_in_year(n, which_wday) ⇒ Object
e.g. to obtain the 2nd Monday of the receivers year use
time.nth_wday_in_year(2, 1)
206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/ri_cal/fast_date_time.rb', line 206 def nth_wday_in_year(n, which_wday) if n > 0 first_of_year = change(:month => 1, :day => 1) first_in_year = first_of_year.advance(:days => (which_wday - first_of_year.wday + 7) % 7) first_in_year.advance(:days => (7*(n - 1))) else december25 = change(:month => 12, :day => 25) last_in_year = december25.advance(:days => (which_wday - december25.wday + 7) % 7) last_in_year.advance(:days => (7 * (n + 1))) end end |
#seconds_to_hms(total_seconds) ⇒ Object
140 141 142 143 144 145 146 147 |
# File 'lib/ri_cal/fast_date_time.rb', line 140 def seconds_to_hms(total_seconds) sign = total_seconds <=> 0 remaining = total_seconds.abs seconds = sign * (remaining % 60) remaining = remaining / 60 minutes = sign * (remaining % 60) [remaining / 60, minutes, seconds] end |
#start_of_week_with_wkst(wkst) ⇒ Object
Return a DateTime which is the beginning of the first day on or before the receiver with the specified wday
221 222 223 224 225 226 |
# File 'lib/ri_cal/fast_date_time.rb', line 221 def start_of_week_with_wkst(wkst) wkst ||= 1 date = @date date -= 1 while date.wday != wkst date end |
#to_datetime ⇒ Object
77 78 79 |
# File 'lib/ri_cal/fast_date_time.rb', line 77 def to_datetime DateTime.civil(year, month, day, hour, min, sec, RiCal.RationalOffset[utc_offset_seconds]) end |
#to_s ⇒ Object Also known as: inspect
93 94 95 |
# File 'lib/ri_cal/fast_date_time.rb', line 93 def to_s "#{year}/#{month}/#{day} #{hour}:#{min}:#{sec} #{offset}" end |
#utc ⇒ Object
def new_offset(ofst)
if ofst == offset
self
else
advance(:seconds => offset - ofset, :offset => ofst)
end
end
128 129 130 131 132 133 134 |
# File 'lib/ri_cal/fast_date_time.rb', line 128 def utc if offset == 0 self else advance(:seconds => -offset, :offset => 0) end end |
#wday ⇒ Object
73 74 75 |
# File 'lib/ri_cal/fast_date_time.rb', line 73 def wday @date.wday end |
#year ⇒ Object
59 60 61 |
# File 'lib/ri_cal/fast_date_time.rb', line 59 def year @date.year end |