# Time granularity

**URL:** <https://rubytalk.org/t/time-granularity/35719>\
**Category:** ruby-talk\
**Created:** [27 February 2007 17:59 UTC](https://rubytalk.org/t/time-granularity/35719 "2007-02-27T17:59:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Guest16](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Guest16](https://rubytalk.org/u/Guest16)\
**Post date:** [27 February 2007 17:59 UTC](https://rubytalk.org/t/time-granularity/35719/1 "2007-02-27T17:59:28Z")

</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|  
&nbsp;&nbsp;... #puts "date is a Sunday."  
&nbsp;&nbsp;end  
end

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Kirk\_Haines](https://avatars.discourse-cdn.com/v4/letter/k/c6cbf5/32.png) [@Kirk\_Haines](https://rubytalk.org/u/Kirk_Haines)\
**Post date:** [27 February 2007 18:15 UTC](https://rubytalk.org/t/time-granularity/35719/2 "2007-02-27T18:15:03Z")

</div>

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|  
&nbsp;&nbsp;&nbsp;# 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 Haines

> **···**
>
> On Wed, 28 Feb 2007, Peter Bailey wrote:
> 
> > 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:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [27 February 2007 19:15 UTC](https://rubytalk.org/t/time-granularity/35719/3 "2007-02-27T19:15:28Z")

</div>



---

<div class="post-metadata">

**Author:** ![Guest16](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Guest16](https://rubytalk.org/u/Guest16)\
**Post date:** [27 February 2007 19:39 UTC](https://rubytalk.org/t/time-granularity/35719/4 "2007-02-27T19:39:32Z")

</div>

This is perfect. Thanks, Kirk.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

**Author:** ![Rob\_Biedenharn1](https://avatars.discourse-cdn.com/v4/letter/r/57b2e6/32.png) [@Rob\_Biedenharn1](https://rubytalk.org/u/Rob_Biedenharn1)\
**Post date:** [27 February 2007 21:35 UTC](https://rubytalk.org/t/time-granularity/35719/5 "2007-02-27T21:35:39Z")

</div>

> > 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
> 
> 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|  
> &nbsp;&nbsp;# 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 Haines

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 Biedenharn [http://agileconsultingllc.com](http://agileconsultingllc.com)  
Rob@AgileConsultingLLC.com

> **···**
>
> On Feb 27, 2007, at 1:15 PM, khaines@enigo.com wrote:
> 
> > On Wed, 28 Feb 2007, Peter Bailey wrote:

---

<div class="post-metadata">

**Author:** ![Guest16](https://avatars.discourse-cdn.com/v4/letter/g/779978/32.png) [@Guest16](https://rubytalk.org/u/Guest16)\
**Post date:** [28 February 2007 12:48 UTC](https://rubytalk.org/t/time-granularity/35719/6 "2007-02-28T12:48:24Z")

</div>

Got it. Thanks.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
