LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-21-2007, 10:17 PM   #1
lmcilwain
Member
 
Registered: Dec 2003
Location: Maryland
Distribution: Fedora, Ubuntu, Centos, FreeBSD
Posts: 390

Rep: Reputation: 31
Comparing dates with ruby


Can anyone tell me how I can compare two dates in an array? I have about 12,000 records that I need to compare to see if any of the times have overlapped by a specified time range.

Example:

If I have a list of dates that are like the following:
1/3/06 12:25
1/3/06 13:06

I want to be able to specify if they have overlapped by specifying a specific time range, be it 5 minutes or 1 minute or an hour.

Is there a way to do this? Right now I have just parsed the code to get it into a time/date format.

Code:
require 'parsedate'
dates_array = []
new_date_array = []

p 'Insert dates into the array'
date_input = gets.chomp

while (date_input !="")
  dates_array[dates_array.length]=date_input
  date_input=gets.chomp
end

p dates_array.index(dates_array.last)
p ''


dates_array.each do |date|
p ParseDate.parsedate(date)
end

p ''
p 'End'
 
Old 02-22-2007, 04:40 PM   #2
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 43
The most efficient way to do it (that I can think of off the top of my head) is to maintain a queue of times which overlapped with the previously-read time. The head of this queue is the furthest-away time you have to check for overlap with the time you read next. This assumes that you're reading the times in order, or that you've read them all in and sorted them. In other words, if time(n) didn't overlap with time(m), it won't overlap with time(m+1). After you've decided the times which overlap with the one you just read in, you push that new one onto the queue.

Here's some code:
Code:
require 'parsedate'

times = ["1/3/06 12:25", "1/3/06 13:06", "1/3/06 13:07"]
queue = []

times.each do | time |
    time = ParseDate.parsedate(time)
    time = Time.local(*time)
    while not queue.empty? and (time - queue.first).abs > 300
        queue.shift
    end
    if not queue.empty? then
        puts time.to_s + ' overlaps with ' + queue.first.to_s +
                ' by ' + (time - queue.first).abs.to_s
    else
        puts time.to_s + ' does not overlap with any other time.'
    end
    queue.push time
end
When two times overlap, I print out the earliest overlapped time and the amount of overlap. The magical 300 number in the while loop is the maximal amount of time you accept as overlap in seconds -- in this version, time entries less than five minutes apart are considered overlapping.
 
Old 02-22-2007, 08:57 PM   #3
lmcilwain
Member
 
Registered: Dec 2003
Location: Maryland
Distribution: Fedora, Ubuntu, Centos, FreeBSD
Posts: 390

Original Poster
Rep: Reputation: 31
Thanks Taylor, I will work on it some more..
 
Old 02-28-2007, 02:36 PM   #4
lmcilwain
Member
 
Registered: Dec 2003
Location: Maryland
Distribution: Fedora, Ubuntu, Centos, FreeBSD
Posts: 390

Original Poster
Rep: Reputation: 31
It looks like this might not be such a good idea. I am dealing with a years worth of records so we are talking something in the several thousands. Its probably better if I can find a way to show an overall date and time and how many other records overlap with that date. This makes it so that I don't have to show as many records.

example:
Date: 2/28/2007 Time: 13:00:00 Number of calls: 2
Date: 2/28/2007 Time: 15:00:00 Number of calls: 7

and so on
 
Old 03-10-2007, 06:36 AM   #5
dannystaple
Member
 
Registered: Apr 2006
Location: London, Uk
Distribution: Ubuntu on Desktop
Posts: 121

Rep: Reputation: 15
Just a thought, but might it be simpler to convert the time/dates into "seconds since epoch" format, and then just compare them as integers (which is pretty quick).

If you are building an array, you can perform the conversion as the items go into the array. I use something similar in a C project with a list of timed events.

Danny
 
Old 03-10-2007, 02:29 PM   #6
lmcilwain
Member
 
Registered: Dec 2003
Location: Maryland
Distribution: Fedora, Ubuntu, Centos, FreeBSD
Posts: 390

Original Poster
Rep: Reputation: 31
With a little help from one of my database developers(who went to ruby training), I was able to get this the way I wanted. Here's the code we put together.

Code:
#!/usr/bin/ruby -w

require 'FileUtils'
require 'time'
input_array=[]
attendee_array=[]
time_array=[]
count_array=[]
attendee_count_array=[]

# Read in dates file
File.open("overalldates.txt","r") do |ofile|
  while(line = ofile.gets )
    input_array << line.split(",")
  end
end

# Read in attendees file
File.open("attendees.txt","r") do |alist|
  while(line2 = alist.gets)
    attendee_array << line2.to_i
  end
end

time=''
input_array.each_index do |each_time_string|

# Create Time array from the input array
time_array.push(Time.local(input_array[each_time_string][0],input_array[each_time_string][1],input_array[each_time_string][2],input_array[each_time_string][3],input_array[each_time_string][4],input_array[each_time_string][5]))
end

time_array.each_index do |each_time_element|
  count = 0
  attendee_count = attendee_array[each_time_element]
  time_array.each_index do |each_inner_time_element|
    if each_time_element != each_inner_time_element && time_array[each_time_element] < time_array[each_inner_time_element]
      if (time_array[each_time_element]+60*60 <= time_array[each_inner_time_element])  == false
        count+=1
        attendee_count+=attendee_array[each_inner_time_element]
      end   
    end
  end
  count_array.push(count)
  attendee_count_array.push(attendee_count)
end
# 
time_array.each_index do |array_elem|
  File.open "outputfile.txt", 'a' do |file|
    file.write "#{time_array[array_elem]}, #{count_array[array_elem]}, #{attendee_count_array[array_elem]}"+"\r"
  end
end

p "File Complete"
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
PHP v Ruby/Ruby on Rails Neko_D Linux - General 4 02-08-2007 11:56 PM
[Ruby] Tar'ing or Zip'ing with ruby script lmcilwain Programming 2 01-19-2007 06:56 PM
f-spot dates viniosity Linux - Software 1 08-07-2005 07:43 PM
Subtracting dates chrisk5527 Linux - General 6 06-10-2004 02:57 PM
File dates. vexer Programming 5 04-28-2004 12:14 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration