1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
require 'active_support/deprecation'
class DateTime
class << self
# *DEPRECATED*: Use +DateTime.civil_from_format+ directly.
def local_offset
ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.', caller
::Time.local(2012).utc_offset.to_r / 86400
end
# Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or
# <tt>config.time_zone</tt> are set, otherwise returns
# <tt>Time.now.to_datetime</tt>.
def current
::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
end
end
# Tells whether the DateTime object's datetime lies in the past.
def past?
self < ::DateTime.current
end
# Tells whether the DateTime object's datetime lies in the future.
def future?
self > ::DateTime.current
end
# Seconds since midnight: DateTime.now.seconds_since_midnight.
def seconds_since_midnight
sec + (min * 60) + (hour * 3600)
end
# Returns a new DateTime where one or more of the elements have been changed
# according to the +options+ parameter. The time options (<tt>:hour</tt>,
# <tt>:minute</tt>, <tt>:sec</tt>) reset cascadingly, so if only the hour is
# passed, then minute and sec is set to 0. If the hour and minute is passed,
# then sec is set to 0. The +options+ parameter takes a hash with any of these
# keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>, <tt>:hour</tt>,
# <tt>:min</tt>, <tt>:sec</tt>, <tt>:offset</tt>, <tt>:start</tt>.
#
# DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0)
# DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0)
def change(options)
::DateTime.civil(
options.fetch(:year, year),
options.fetch(:month, month),
options.fetch(:day, day),
options.fetch(:hour, hour),
options.fetch(:min, options[:hour] ? 0 : min),
options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec),
options.fetch(:offset, offset),
options.fetch(:start, start)
)
end
# Uses Date to provide precise Time calculations for years, months, and days.
# The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
# <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
# <tt>:minutes</tt>, <tt>:seconds</tt>.
def advance(options)
d = to_date.advance(options)
datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
seconds_to_advance = \
options.fetch(:seconds, 0) +
options.fetch(:minutes, 0) * 60 +
options.fetch(:hours, 0) * 3600
if seconds_to_advance.zero?
datetime_advanced_by_date
else
datetime_advanced_by_date.since seconds_to_advance
end
end
# Returns a new DateTime representing the time a number of seconds ago.
# Do not use this method in combination with x.months, use months_ago instead!
def ago(seconds)
since(-seconds)
end
# Returns a new DateTime representing the time a number of seconds since the
# instance time. Do not use this method in combination with x.months, use
# months_since instead!
def since(seconds)
self + Rational(seconds.round, 86400)
end
alias :in :since
# Returns a new DateTime representing the start of the day (0:00).
def beginning_of_day
change(:hour => 0)
end
alias :midnight :beginning_of_day
alias :at_midnight :beginning_of_day
alias :at_beginning_of_day :beginning_of_day
# Returns a new DateTime representing the end of the day (23:59:59).
def end_of_day
change(:hour => 23, :min => 59, :sec => 59)
end
# Returns a new DateTime representing the start of the hour (hh:00:00).
def beginning_of_hour
change(:min => 0)
end
alias :at_beginning_of_hour :beginning_of_hour
# Returns a new DateTime representing the end of the hour (hh:59:59).
def end_of_hour
change(:min => 59, :sec => 59)
end
# Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
#
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
# DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 +0000
def utc
new_offset(0)
end
alias_method :getutc, :utc
# Returns +true+ if <tt>offset == 0</tt>.
def utc?
offset == 0
end
# Returns the offset value in seconds.
def utc_offset
(offset * 86400).to_i
end
# Layers additional behavior on DateTime#<=> so that Time and
# ActiveSupport::TimeWithZone instances can be compared with a DateTime.
def <=>(other)
super other.to_datetime
end
end
|