class DateTime
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0)
DateTime.civil_from_format :local, 2012, 12, 17
# => Sun, 01 Jan 2012 00:00:00 +0300
DateTime.civil_from_format :local, 2012
offset is zero.
Returns DateTime with local offset for given year if format is local else
def self.civil_from_format(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0) if utc_or_local.to_sym == :local offset = ::Time.local(year, month, day).utc_offset.to_r / 86400 else offset = 0 end civil(year, month, day, hour, min, sec, offset) end
def <=>(other)
Layers additional behavior on DateTime#<=> so that Time and
def <=>(other) if other.kind_of?(Infinity) super elsif other.respond_to? :to_datetime super other.to_datetime else nil end end
def acts_like_date?
def acts_like_date? true end
def acts_like_time?
def acts_like_time? true end
def advance(options)
:months, :weeks, :days, :hours,
The +options+ parameter takes a hash with any of these keys: :years,
Uses Date to provide precise Time calculations for years, months, and days.
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
def ago(seconds)
Returns a new DateTime representing the time a number of seconds ago.
def ago(seconds) since(-seconds) end
def as_json(options = nil) #:nodoc:
def as_json(options = nil) #:nodoc: if ActiveSupport.use_standard_json_time_format xmlschema else strftime('%Y/%m/%d %H:%M:%S %z') end end
def beginning_of_day
def beginning_of_day change(:hour => 0) end
def beginning_of_hour
def beginning_of_hour change(:min => 0) end
def beginning_of_minute
def beginning_of_minute change(:sec => 0) end
def change(options)
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(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0)
:min, :sec, :offset, :start.
keys: :year, :month, :day, :hour,
then sec is set to 0. The +options+ parameter takes a hash with any of these
passed, then minute and sec is set to 0. If the hour and minute is passed,
:min, :sec) reset cascadingly, so if only the hour is
according to the +options+ parameter. The time options (:hour,
Returns a new DateTime where one or more of the elements have been changed
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 + sec_fraction), options.fetch(:offset, offset), options.fetch(:start, start) ) end
def current
config.time_zone are set, otherwise returns
Returns Time.zone.now.to_datetime when Time.zone or
def current ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime end
def end_of_day
def end_of_day change(:hour => 23, :min => 59, :sec => 59) end
def end_of_hour
def end_of_hour change(:min => 59, :sec => 59) end
def end_of_minute
def end_of_minute change(:sec => 59) end
def formatted_offset(colon = true, alternate_utc_string = nil)
datetime.formatted_offset # => "-06:00"
datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24))
def formatted_offset(colon = true, alternate_utc_string = nil) utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) end
def future?
def future? self > ::DateTime.current end
def in_time_zone(zone = ::Time.zone)
Time.zone.
as an argument, and the conversion will be based on that zone instead of
You can also pass in a TimeZone instance or string that identifies a TimeZone
as the local zone instead of the operating system's time zone.
This method is similar to Time#localtime, except that it uses Time.zone
DateTime.new(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00
Time.zone = 'Hawaii' # => 'Hawaii'
Returns the simultaneous time in Time.zone.
def in_time_zone(zone = ::Time.zone) if zone ActiveSupport::TimeWithZone.new(utc? ? self : getutc, ::Time.find_zone!(zone)) else self end end
def local_offset
def local_offset ActiveSupport::Deprecation.warn 'DateTime.local_offset is deprecated. Use DateTime.civil_from_format directly.' ::Time.local(2012).utc_offset.to_r / 86400 end
def nsec
def nsec (sec_fraction * 1_000_000_000).to_i end
def offset_in_seconds
def offset_in_seconds (offset * 86400).to_i end
def past?
def past? self < ::DateTime.current end
def readable_inspect
def readable_inspect to_s(:rfc822) end
def seconds_since_midnight
def seconds_since_midnight sec + (min * 60) + (hour * 3600) end
def seconds_since_unix_epoch
def seconds_since_unix_epoch (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight end
def seconds_until_end_of_day
DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103
DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399
Returns the number of seconds until 23:59:59.
def seconds_until_end_of_day end_of_day.to_i - to_i end
def since(seconds)
instance time. Do not use this method in combination with x.months, use
Returns a new DateTime representing the time a number of seconds since the
def since(seconds) self + Rational(seconds.round, 86400) end
def to_f
def to_f seconds_since_unix_epoch.to_f end
def to_formatted_s(format = :default)
Time::DATE_FORMATS[:month_and_year] = '%B %Y'
# config/initializers/time_formats.rb
datetime argument as the value.
either a strftime string or Proc instance that takes a time or
Time::DATE_FORMATS hash. Use the format name as the hash key and
DateTime formats are shared with Time. You can add your own to the
== Adding your own datetime formats to to_formatted_s
datetime.to_formatted_s(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000"
datetime.to_formatted_s(:long_ordinal) # => "December 4th, 2007 00:00"
datetime.to_formatted_s(:long) # => "December 04, 2007 00:00"
datetime.to_formatted_s(:short) # => "04 Dec 00:00"
datetime.to_s(:number) # => "20071204000000"
datetime.to_s(:db) # => "2007-12-04 00:00:00"
datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00"
datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000
=== Examples
This method is aliased to to_s.
Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.
def to_formatted_s(format = :default) if formatter = ::Time::DATE_FORMATS[format] formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) else to_default_s end end
def to_i
def to_i seconds_since_unix_epoch.to_i end
def usec
def usec (sec_fraction * 1_000_000).to_i end
def utc
DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600
Adjusts DateTime to UTC by adding its offset value; offset is set to 0.
def utc new_offset(0) end
def utc?
def utc? offset == 0 end
def utc_offset
def utc_offset (offset * 86400).to_i end