Finding the Day of the Week

May 20, 2007 · Filed Under Date and Time, Ruby 

Problem

You want to find the day of the week for a certain date.

Solution

Use the wday method (supported by both Time and DateTime) to find the day of the week as a number between 0 and 6. Sunday is day zero.

The following code yields to a code block the date of every Sunday between two dates. It uses wday to find the first Sunday following the start date (keeping in mind that the first date may itself be a Sunday). Then it adds seven days at a time to get subsequent Sundays:

	def every_sunday(d1, d2)
	  # You can use 1.day instead of 60*60*24 if you're using Rails.
	  one_day = d1.is_a?(Time) ? 60*60*24 : 1
	  sunday = d1 + ((7-d1.wday) % 7) * one_day
	  while sunday < d2
	    yield sunday
	    sunday += one_day * 7
	  end
	end

	def print_every_sunday(d1, d2)
	  every_sunday(d1, d2) { |sunday| puts sunday.strftime("%x")}
	end

	print_every_sunday(Time.local(2006, 1, 1), Time.local(2006, 2, 4))
	# 01/01/06
	# 01/08/06
	# 01/15/06
	# 01/22/06
	# 01/29/06

Discussion

The most commonly used parts of a time are its calendar and clock readings: year, day, hour, and so on. Time and DateTime let you access these, but they also give you access to a few other aspects of a time: the Julian day of the year (yday), and, more usefully, the day of the week (wday).

The every_sunday method will accept either two Time objects or two DateTime objects. The only difference is the number you need to add to an object to increment it by one day. If you’re only going to be using one kind of object, you can simplify the code a little.

To get the day of the week as an English string, use the strftime directives %A and %a:

	t = Time.local(2006, 1, 1)
	t.strftime("%A %A %A!")     # => "Sunday Sunday Sunday!"
	t.strftime("%a %a %a!")      # => "Sun Sun Sun!"

You can find the day of the week and the day of the year, but Ruby has no built-in method for finding the week of the year (there is a method to find the commercial week of the year; see Recipe 3.11). If you need such a method, it’s not hard to create one using the day of the year and the day of the week. This code defines a week method in a module, which it mixes in to both Date and Time:

	require 'date'
	module Week
	 def week
	    (yday + 7 - wday) / 7
	  end
	end

	class Date
	  include Week
	end

	class Time
	  include Week
	end

	saturday = DateTime.new(2005, 1, 1)
	saturday.week                              # => 0
(saturday+1).week                # => 1 #Sunday, January 2
(saturday-1).week                # => 52 #Friday, December 31

Comments

Leave a Reply

You must be logged in to post a comment.