How to make an array from a date range?


#1

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!


#2

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


#3

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


#4

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 … ]


#5

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 (removed_email_address@domain.invalid)
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!


#6

Ross B. 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 :slight_smile:


#7

On Sun, 2006-04-23 at 21:59 +0900, Robin S. wrote:

Ross B. 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 :slight_smile:

Doh… I really must find my proofreading glasses :slight_smile:

Thanks,


#8

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


#9

Thank everyone, thats exactly what I needed.


#10

removed_email_address@domain.invalid 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


#11

On Apr 23, 2006, at 1:11 PM, Robin S. 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.


#12

On Tue, 2006-04-25 at 01:42 +0900, Logan C. 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


#13

On Tue, 25 Apr 2006, Logan C. 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. :wink:

-a