Forum: Ruby How to make an array from a date range?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Df0a460118ef876e45b13b8c1a471454?d=identicon&s=25 Marston A. (marstoni)
on 2006-04-23 13:58
What is the easiest way in Ruby to make an array our of a date range?
Something like this:

@date1 = "2006-04-01"
@date2 = "2006-04-23"

array = [@date1..@date2]

Something like that would be an easy solution as @date1 and @date2 are
going to by dynamic, but this doesn't work as they are strings.

Or would I have to manually insert the ranges one by one myself?

array = ["2006-04-01", "2006-04-02", ... , "2006-04-23"]

Thanks for any help in advanced!
9c39060182e52f2749f932ed0f3d9ff7?d=identicon&s=25 Malamute Jute (mutejute)
on 2006-04-23 14:28
im still a newbie but heres my take:

dates = []
for i in 1..23 do
	if i < 10
		format = "2006-04-0%d"
	else
		format = "2006-04-%d"
	end
	dates << sprintf(format, i)
end
A9b6a93b860020caf9d2d1d58c32478f?d=identicon&s=25 Ross Bamford (Guest)
on 2006-04-23 14:41
(Received via mailing list)
On Sun, 2006-04-23 at 20:58 +0900, Marston A. wrote:
>
> Or would I have to manually insert the ranges one by one myself?
>
> array = ["2006-04-01", "2006-04-02", ... , "2006-04-23"]
>
> Thanks for any help in advanced!
>

I don't know if this is the easiest (or best) way, but it seems to work:

require 'date'			# from stdlib
# => true

(Date.parse('2006-04-01')..Date.parse('2006-04-23')).to_a.map { |e|
e.to_s }
# => ["2006-04-01",
      "2006-04-02",
      "2006-04-03",
      "2006-04-04",
      ...,
      "2006-04-23"]


You can do a similar thing with Time to get different ranges (hours,
half-days, etc.) but it's pretty wasteful in terms of efficiency so
stick with date if you can.

a = []
# => []

(Time.parse('2006-4-23')..Time.parse('2006-4-27')).step(86400) { |t| a
<< t }
# => Sun Apr 23 00:00:00 BST 2006..Thu Apr 27 00:00:00 BST 2006

a
# => [Sun Apr 23 00:00:00 BST 2006,
#     Mon Apr 24 00:00:00 BST 2006,
#     Tue Apr 25 00:00:00 BST 2006,
#     Wed Apr 26 00:00:00 BST 2006,
#     Thu Apr 27 00:00:00 BST 2006]

a = []
# => []

(Time.parse('2006-4-23')..Time.parse('2006-4-27')).step(3600) { |t| a <<
t }
# => Sun Apr 23 00:00:00 BST 2006..Thu Apr 27 00:00:00 BST 2006

a
# => [Sun Apr 23 00:00:00 BST 2006,
#     Sun Apr 23 01:00:00 BST 2006,
#     Sun Apr 23 02:00:00 BST 2006,
#     Sun Apr 23 03:00:00 BST 2006,
#     Sun Apr 23 04:00:00 BST 2006,
#     Sun Apr 23 05:00:00 BST 2006,
#     ... 97 elements ... ]
A90204c955db033cd975f7bb0ec9600b?d=identicon&s=25 Ashley Moran (Guest)
on 2006-04-23 14:50
(Received via mailing list)
On Apr 23, 2006, at 12:58 pm, Marston A. wrote:

>
> Or would I have to manually insert the ranges one by one myself?
>
> array = ["2006-04-01", "2006-04-02", ... , "2006-04-23"]
>
> Thanks for any help in advanced!

Date can be in a range like this:

   start_date = Date.strptime("2006-04-01")
   end_date = Date.strptime("2006-04-23")

   date_range = start_date..end_date
   puts date_range.include?(Date.strptime("2006-04-10"))

   date_array = date_range.to_a
   puts date_array.join(', ')

Ashley
Df0a460118ef876e45b13b8c1a471454?d=identicon&s=25 Marston A. (marstoni)
on 2006-04-23 14:56
Thank everyone, thats exactly what I needed.
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2006-04-23 14:59
(Received via mailing list)
Hi --

On Sun, 23 Apr 2006, malamute jute wrote:

> end
I think the date library ways will scale better; but for your possible
interest, here's another way to do what you've got here:

   dates = (1..23).map {|i| sprintf("2006-04-%.2d",i) }


David

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" PDF now on sale!  http://www.manning.com/black
Paper version coming in early May!
Cd49db0b676767ea4358b1047c4cddd2?d=identicon&s=25 Robin Stocker (Guest)
on 2006-04-23 14:59
(Received via mailing list)
Ross Bamford wrote:
> (Date.parse('2006-04-01')..Date.parse('2006-04-23')).to_a.map { |e| e.to_s }

Just a small suggestion:
Leave out the to_a so it's faster and uses less memory :)
A9b6a93b860020caf9d2d1d58c32478f?d=identicon&s=25 Ross Bamford (Guest)
on 2006-04-23 15:03
(Received via mailing list)
On Sun, 2006-04-23 at 21:59 +0900, Robin Stocker wrote:
> Ross Bamford wrote:
> > (Date.parse('2006-04-01')..Date.parse('2006-04-23')).to_a.map { |e| e.to_s }
>
> Just a small suggestion:
> Leave out the to_a so it's faster and uses less memory :)

Doh... I really must find my proofreading glasses :)

Thanks,
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-23 16:50
(Received via mailing list)
On Sun, 23 Apr 2006, Marston A. wrote:

>
> Or would I have to manually insert the ranges one by one myself?
>
> array = ["2006-04-01", "2006-04-02", ... , "2006-04-23"]
>
> Thanks for any help in advanced!

are you sure that you need an array:

       harp:~ > cat a.rb
       require 'date'

       a = Date.parse "2006-04-01"
       b = Date.parse "2006-04-23"

       (a .. b).each{|date| puts date}



       harp:~ > ruby a.rb
       2006-04-01
       2006-04-02
       2006-04-03
       2006-04-04
       2006-04-05
       2006-04-06
       2006-04-07
       2006-04-08
       2006-04-09
       2006-04-10
       2006-04-11
       2006-04-12
       2006-04-13
       2006-04-14
       2006-04-15
       2006-04-16
       2006-04-17
       2006-04-18
       2006-04-19
       2006-04-20
       2006-04-21
       2006-04-22
       2006-04-23


if you do simply use

   list = (a .. b).inject([]){|accum, date| accum << date}

regards.


-a
Cd49db0b676767ea4358b1047c4cddd2?d=identicon&s=25 Robin Stocker (Guest)
on 2006-04-23 19:12
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> if you do simply use
>
>   list = (a .. b).inject([]){|accum, date| accum << date}

I'm curious, is there a special reason for the use of inject here?
Doesn't the following do the same?

   list = (a..b).to_a

> -a

Robin
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-04-24 18:42
(Received via mailing list)
On Apr 23, 2006, at 1:11 PM, Robin Stocker wrote:

>
> Robin
>

Yes, they are exactly the same. It's just that inject is a force of
nature. It consumes your Enumerables, and leaves a trail of
devastation in its wake. You can't escape it. You must accept your
fate as a slave to inject.
A9b6a93b860020caf9d2d1d58c32478f?d=identicon&s=25 Ross Bamford (Guest)
on 2006-04-24 19:42
(Received via mailing list)
On Tue, 2006-04-25 at 01:42 +0900, Logan Capaldo wrote:
> >
> >> -a
> >
> > Robin
> >
>
> Yes, they are exactly the same. It's just that inject is a force of
> nature. It consumes your Enumerables, and leaves a trail of
> devastation in its wake. You can't escape it. You must accept your
> fate as a slave to inject.

Latterly though I've found respite from my own inject addiction thanks
to a couple of quick benchmarks:

a = (0...1000)
# => 0...1000

Benchmark.bm { |x| x.report { 100.times { a.to_a } } }
      user     system      total        real
  0.060000   0.000000   0.060000 (  0.075679)
# => true

Benchmark.bm { |x| x.report { 100.times { a.inject([]) { |a,e| a << e }
} } }
      user     system      total        real
  0.300000   0.000000   0.300000 (  0.431041)
# => true
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 unknown (Guest)
on 2006-04-24 19:51
(Received via mailing list)
On Tue, 25 Apr 2006, Logan Capaldo wrote:

>>   list = (a..b).to_a
>>
>>> -a
>>
>> Robin
>>
>
> Yes, they are exactly the same. It's just that inject is a force of nature.
> It consumes your Enumerables, and leaves a trail of devastation in its wake.
> You can't escape it. You must accept your fate as a slave to inject.

well, in this case it was merely the result of posting sans coffee.  i
do that
occasionally and always regret it.  ;-)

-a
This topic is locked and can not be replied to.