# Time granularity

**URL:** <https://www.ruby-forum.com/t/time-granularity/87031>\
**Category:** Ruby\
**Created:** [February 27, 2007, 6:59pm UTC](https://www.ruby-forum.com/t/time-granularity/87031 "2007-02-27T18:59:26Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [February 27, 2007, 6:59pm UTC](https://www.ruby-forum.com/t/time-granularity/87031/1 "2007-02-27T18:59:26Z")

</div>

Hello,  
I need to create some time variables for our company’s accounting budget  
calendar. We have 13 budget periods in a year. The first one ends on the  
last Sunday of January of whatever year it is. Once I find that day,  
then I can simply add 28 days to it, consecutively, to get the remaining  
budget fences. Anyway, I’m basically just starting with the 31st of  
January and working back until I find the last Sunday of the month. I’ve  
tried a string of if/elsif statements and I get close, but, it seems to  
me I could do it with less code. If I create a range between that last  
day of the month and all 7 days prior to it, that last Sunday should be  
in there somewhere. When I try to work with ranges, though, and ask for  
any results, it returns results for literally every second of every day  
in that range! So, can anyone help me to ask Ruby to just give me days  
back and not any subdivisions of those days?

t1 = Time.mktime(2007,1,24)  
t2 = Time.mktime(2007,1,31)  
dates = t1 … t2  
dates.each for |date|  
… #puts “date is a Sunday.”  
end  
end

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [February 27, 2007, 7:16pm UTC](https://www.ruby-forum.com/t/time-granularity/87031/2 "2007-02-27T19:16:00Z")

</div>

On Wed, 28 Feb 2007, Peter B. wrote:

> dates.each for |date|  
> … #puts “date is a Sunday.”  
> end  
> end

Do it with Date instead of Time.

require ‘date’  
t1 = Date.new(2007,1,24)  
t2 = Date.new(2007,1,31)  
dates = t1 … t2  
dates.each do |date|

# your date stuff here

end

Time uses seconds to represents a point in time. Time is fast, because  
it’s really just a thin layer between Ruby and the underlying C  
libraries.

Date and DateTime use days for their unit, represented by rational  
numbers  
(instances of the Rational class). They are a lot slower than Time  
objects, but have some flexibility that Time doesn’t, and the use of  
Days  
for their unit means they work well for your application.

If you want to convert a Date into a Time, do this:

Time.local(date.year,date.month,date.day)

Kirk H.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [February 27, 2007, 8:39pm UTC](https://www.ruby-forum.com/t/time-granularity/87031/3 "2007-02-27T20:39:30Z")

</div>

This is perfect. Thanks, Kirk.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [February 28, 2007, 1:48pm UTC](https://www.ruby-forum.com/t/time-granularity/87031/4 "2007-02-28T13:48:21Z")

</div>

Got it. Thanks.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [February 27, 2007, 10:36pm UTC](https://www.ruby-forum.com/t/time-granularity/87031/5 "2007-02-27T22:36:40Z")

</div>

On Feb 27, 2007, at 1:15 PM, removed\_email\_address@domain.invalid wrote:

> > in that range! So, can anyone help me to ask Ruby to just give me
> 
> If you want to convert a Date into a Time, do this:
> 
> Time.local(date.year,date.month,date.day)
> 
> Kirk H.

Don’t even deal with the range:

> > jan31 = Date.new(2007,1,31)  
> > =\> #\<Date: 4908263/2,0,2299161\>  
> > jan31.strftime “%D, %A”  
> > =\> “01/31/07, Wednesday”  
> > (jan31 - jan31.wday).strftime “%D, %A”  
> > =\> “01/28/07, Sunday”

Date#wday is the number of the weekday: 0=\>Sunday, 6=\>Saturday

> > (1999…2007).each do |year|  
> > ?\> jan31 = Date.new(year,1,31)  
> > puts (jan31 - jan31.wday).strftime(“%D, %A”)  
> > end; nil  
> > 01/31/99, Sunday  
> > 01/30/00, Sunday  
> > 01/28/01, Sunday  
> > 01/27/02, Sunday  
> > 01/26/03, Sunday  
> > 01/25/04, Sunday  
> > 01/30/05, Sunday  
> > 01/29/06, Sunday  
> > 01/28/07, Sunday

Then start adding!

> > jan31 = Date.new(2007,1,31)  
> > =\> #\<Date: 4908263/2,0,2299161\>  
> > next\_jan31 = Date.new(2008,1,31)  
> > =\> #\<Date: 4908993/2,0,2299161\>  
> > ((jan31-jan31.wday)…(next\_jan31-next\_jan31.wday)).step(28) do |  
> > day|  
> > ?\> puts day.strftime(“%D, %A”)  
> > end;nil  
> > 01/28/07, Sunday  
> > 02/25/07, Sunday  
> > 03/25/07, Sunday  
> > 04/22/07, Sunday  
> > 05/20/07, Sunday  
> > 06/17/07, Sunday  
> > 07/15/07, Sunday  
> > 08/12/07, Sunday  
> > 09/09/07, Sunday  
> > 10/07/07, Sunday  
> > 11/04/07, Sunday  
> > 12/02/07, Sunday  
> > 12/30/07, Sunday

-Rob

Rob B. [http://agileconsultingllc.com](http://agileconsultingllc.com)  
removed\_email\_address@domain.invalid
