require'rational'unlessRUBY_VERSION>='1.9.2'require'active_support/core_ext/object/acts_like'require'active_support/core_ext/time/zones'classDateTimeclass<<self# DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zonedeflocal_offset::Time.local(2007).utc_offset.to_r/86400enddefcurrent::Time.zone_default?::Time.zone.now.to_datetime:::Time.now.to_datetimeendend# Tells whether the DateTime object's datetime lies in the pastdefpast?self<::DateTime.currentend# Tells whether the DateTime object's datetime lies in the futuredeffuture?self>::DateTime.currentend# Seconds since midnight: DateTime.now.seconds_since_midnightdefseconds_since_midnightsec+(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# (hour, minute, sec) 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.defchange(options)::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[:offset]||offset,options[: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>.defadvance(options)d=to_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)*3600seconds_to_advance==0?datetime_advanced_by_date:datetime_advanced_by_date.since(seconds_to_advance)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!defago(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!defsince(seconds)self+Rational(seconds.round,86400)endalias:in:since# Returns a new DateTime representing the start of the day (0:00)defbeginning_of_daychange(:hour=>0)endalias:midnight:beginning_of_dayalias:at_midnight:beginning_of_dayalias:at_beginning_of_day:beginning_of_day# Returns a new DateTime representing the end of the day (23:59:59)defend_of_daychange(:hour=>23,:min=>59,:sec=>59)end# Adjusts DateTime to UTC by adding its offset value; offset is set to 0## Example:## 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 +0000defutcnew_offset(0)endalias_method:getutc,:utc# Returns true if offset == 0defutc?offset==0end# Returns the offset value in secondsdefutc_offset(offset*86400).to_iend# Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTimedefcompare_with_coercion(other)other=other.comparable_timeifother.respond_to?(:comparable_time)other=other.to_datetimeunlessother.acts_like?(:date)compare_without_coercion(other)endalias_method:compare_without_coercion,:<=>alias_method:<=>,:compare_with_coercionend