Finding Todays Date

Table of contents:

Finding Today s Date

Problem

You need to create an object that represents the current date and time, or a time in the future or past.

Solution

The factory method Time.now creates a Time object containing the current local time. If you want, you can then convert it to GMT time by calling Time#gmtime. The gmtime method actually modifies the underlying time object, though it doesn't follow the Ruby naming conventions for such methods (it should be called something like gmtime!).

	now = 
Time.now # => Sat Mar 18 16:58:07 EST 2006
	now.gmtime # => Sat Mar 18 21:58:07 UTC 2006

	#The original object was affected by the time zone conversion.
	now # => Sat Mar 18 21:58:07 UTC 2006

To create a DateTime object for the current local time, use the factory method DateTime.now. Convert a DateTime object to GMT by calling DateTime#new_offset with no argument. Unlike Time#gmtime, this method returns a second DateTime object instead of modifying the original in place.

	require 'date'
	now = DateTime.now
	# => #
	now.to_s # => "2006-03-18T16:58:07-0500"
	now.new_offset.to_s # => "2006-03-18T21:58:07Z"

	#The original object was not affected by the time zone conversion.
	now.to_s # => "2006-03-18T16:58:07-0500"

 

Discussion

Both Time and DateTime objects provide accessor methods for the basic ways in which the Western calendar and clock divide a moment in time. Both classes provide year, month, day, hour (in 24-hour format), min, sec, and zone accessors. Time#isdst lets you know if the underlying time of a Time object has been modified by Daylight Saving Time in its time zone. DateTime pretends Daylight Saving Time doesn't exist.

	now_time = Time.new
	now_datetime = DateTime.now
	now_time.year # => 2006
	now_ 
datetime.year # => 2006
	now_time.hour # => 18
	now_ 
datetime.hour # => 18

	now_time.zone # => "EST"
	now_ 
datetime.zone # => "-0500"
	now_time.isdst # => false

You can see that Time#zone and DateTime#zone are a little different. Time#zone returns a time zone name or abbreviation, and DateTime#zone returns a numeric offset from GMT in string form. You can call DateTime#offset to get the GMT offset as a number: a fraction of a day.

	now_datetime.offset # => Rational(-5, 24) # -5 hours

Both classes can also represent fractions of a second, accessible with Time#usec (that is, μsec or microseconds) and DateTime#sec_fraction. In the example above, the DateTime object was created after the Time object, so the numbers are different even though both objects were created within the same second.

	now_time.usec # => 247930
	# That is, 247930 microseconds
	now_datetime.sec_fraction # => Rational(62191, 21600000000)
	# That is, about 287921 microseconds

The date library provides a Date class that is like a DateTime, without the time. To create a Date object containing the current date, the best strategy is to create a DateTime object and use the result in a call to a Date factory method. DateTime is actually a subclass of Date, so you only need to do this if you want to strip time data to make sure it doesn't get used.

	class Date
	 def Date.now
	 return Date.jd(DateTime.now.jd)
	 end
	end
	puts Date.now
	# 2006-03-18

In addition to creating a time object for this very moment, you can create one from a string (see Recipe 3.2) or from another time object (see Recipe 3.5). You can also use factory methods to create a time object from its calendar and clock parts: the year, month, day, and so on.

The factory methods Time.local and Time.gm take arguments Time object for that time. For local time, use Time.local; for GMT, use Time.gm. All arguments after year are optional and default to zero.

	Time.local(1999, 12, 31, 23, 21, 5, 1044)
	# => Fri Dec 31 23:21:05 EST 1999

	Time.gm(1999, 12, 31, 23, 21, 5, 22, 1044)
	# => Fri Dec 31 23:21:05 UTC 1999

	Time.local(1991, 10, 1)
	# => Tue Oct 01 00:00:00 EDT 1991

	Time.gm(2000)
	# => Sat Jan 01 00:00:00 UTC 2000

The DateTime equivalent of Time.local is the civil factory method. It takes almost but not quite the same arguments as Time.local:

	[year, month, day, hour, minute, second, timezone_offset, date_of_calendar_reform].

The main differences from Time.local and Time.gmt are:

  • There's no separate usec argument for fractions of a second. You can represent fractions of a second by passing in a rational number for second.
  • All the arguments are optional. However, the default year is 4712 BCE, which is probably not useful to you.
  • Rather than providing different methods for different time zones, you must pass in an offset from GMT as a fraction of a day. The default is zero, which means that calling DateTime.civil with no time zone will give you a time in GMT.
	DateTime.civil(1999, 12, 31, 23, 21, Rational(51044, 100000)).to_s
	# => "1999-12-31T23:21:00Z"

	DateTime.civil(1991, 10, 1).to_s
	# => "1991-10-01T00:00:00Z"

	DateTime.civil(2000).to_s
	# => "2000-01-01T00:00:00Z"

The simplest way to get the GMT offset for your local time zone is to call offset on the result of DateTime.now. Then you can pass the offset into DateTime.civil:

	my_offset = DateTime.now.offset # => Rational(-5, 24)

	DateTime.civil(1999, 12, 31, 23, 21, Rational(51044, 100000), my_offset).to_s
	# => "1999-12-31T23:21:00-0500"

Oh, and there's the calendar-reform thing, too. Recall that Time objects can only represent dates from a limited range (on 32-bit systems, dates from the 20th and 21st centuries). DateTime objects can represent any date at all. The price of this greater range is that DateTime needs to worry about calendar reform when dealing with historical dates. If you're using old dates, you may run into a gap caused by a switch from the Julian calendar (which made every fourth year a leap year) to the more accurate Gregorian calendar (which occasionally skips leap years).

This switch happened at different times in different countries, creating differentlysized gaps as the local calendar absorbed the extra leap days caused by using the Julian reckoning for so many centuries. Dates created within a particular country's gap are invalid for that country.

By default, Ruby assumes that Date objects you create are relative to the Italian calendar, which switched to Gregorian reckoning in 1582. For American and Commonwealth users, Ruby has provided a constant Date::ENGLAND, which corresponds to the date that England and its colonies adopted the Gregorian calendar. DateTime's constructors and factory methods will accept Date::ENGLAND or Date::ITALY as an extra argument denoting when calendar reform started in that country. The calendar reform argument can also be any old Julian day, letting you handle old dates from any country:

	#In Italy, 4 Oct 1582 was immediately followed by 15 Oct 1582.
	#
	Date.new(1582, 10, 4).to_s
	# => "1582-10-04"
	Date.new(1582, 10, 5).to_s
	# ArgumentError: invalid date
	Date.new(1582, 10, 4).succ.to_s
	# => "1582-10-15"

	#In England, 2 Sep 1752 was immediately followed by 14 Sep 1752.
	#
	Date.new(1752, 9, 2, Date::ENGLAND).to_s
	# => "1752-09-02"
	Date.new(1752, 9, 3, Date::ENGLAND).to_s
	# ArgumentError: invalid date
	Date.new(1752, 9, 2, DateTime::ENGLAND).succ.to_s
	# => "1752-09-14"
	Date.new(1582, 10, 5, Date::ENGLAND).to_s
	# => "1582-10-05"

You probably won't need to use Ruby's Gregorian conversion features: it's uncommon that computer applications need to deal with old dates that are both known with precision and associated with a particular locale.

See Also

  • A list of the dates of Gregorian conversion for various countries (http://www.polysyllabic.com/GregConv.html)
  • Recipe 3.7, "Converting Between Time Zones
  • Recipe 3.8, "Checking Whether Daylight Saving Time Is in Effect"


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net