Reputation: 3345
I am working through Chris Pine's Ruby book, and I am slightly confused why my code doesn't quite work.
I have a file called birthdays.txt
which has around 10 lines of text which resembles:
Andy Rogers, 1987, 02, 03
etc.
My code as follows:
hash = {}
File.open('birthdays.txt', "r+").each_line do |line|
name, date = line.chomp.split( /, */, 2 )
hash[name] = date
end
puts 'whose birthday would you like to know?'
name = gets.chomp
puts hash[name]
puts Time.local(hash[name])
My question is, why does the last line of code, Time.local(hash[name])
produce this output?:
1987-01-01 00:00:00 +0000
instead of:
1987-02-03 00:00:00 +0000
Upvotes: 0
Views: 85
Reputation: 3345
hash = {}
File.open('birthdays.txt').each_line do |line|
line = line.chomp
name, date = line.split(',',2)
year, month, day = date.split(/, */).map {|x| x.to_i}
hash[name] = Time.local(year, month, day)
end
puts 'Whose birthday and age do you want to find out?'
name = gets.chomp
if hash[name] == nil
puts ' Ummmmmmmm, dont know that one'
else
age_secs = Time.new - hash[name]
age_in_years = (age_secs/60/60/24/365 + 1)
t = hash[name]
t.strftime("%m/%d/%y")
puts "#{name}, will be, #{age_in_years.to_i} on #{t.strftime("%m/%d/")}"
end
had to move the Time.local call earlier in the program and then bingo, cheers guys!
Upvotes: 0
Reputation: 80085
line = "Andy Rogers, 1987, 02, 03\n"
name, date = line.chomp.split( /, */, 2 ) #split (', ', 2) is less complex.
#(Skipping the hash stuff; it's fine)
p date #=> "1987, 02, 03"
# Time class can't handle one string, it wants: "1987", "02", "03"
# so:
year, month, day = date.split(', ')
p Time.local(year, month, day)
# or do it all at once (google "ruby splat operator"):
p Time.local(*date.split(', '))
Upvotes: 0
Reputation: 2192
If you look at the documentation for Time.local,
Time.local doesn't parse a string. It expects you to pass a separate parameter for year, month, and date. When you pass a string like "1987, 02, 03", it takes that to be a single parameter, the year. It then tries to coerce that string into an integer - in this case, 1982.
so, basically, you want to slice up that string into the year, month, and day. there's multiple ways to do this. Here's one (it can be made shorter, but this is the most clear way)
year, month, date = date.split(/, */).map {|x| x.to_i}
Time.local(year, month, date)
Upvotes: 2