[ruby]Get file, parse text and create date object - ruby

I have a raw .txt file formatted as such:
01.01.2017;New Year
16.04.2017;Easter
25.12.2017;Christmas
(Sidenote: dates are formatted as dd.mm.yyyy)
I'm trying to read this file, slice the text per line and make a hash out of it, with the key being the date, and its value the name of the corresponding public holiday.
I've already gotten so far:
holidays = Hash[*File.read('holidays.txt').split(/;|\n/)]
This results in the dates being set as strings, not date objects.
Any ideas as to how I could then transform these strings to Date (or DateTime) objects?
P.S.: I'm only using Ruby, so no Rails helpers...

Something like this
holidays = File.read('holidays.txt').split(/\n/).map do |row|
date, holiday_name = row.split(';')
date = Date.parse(date, '%d.%m.%Y')
[date, holiday_name]
end.to_h
=> {
#<Date: 2017-01-01 ((2457755j,0s,0n),+0s,2299161j)> => "New Year",
#<Date: 2017-04-16 ((2457860j,0s,0n),+0s,2299161j)> => "Easter",
#<Date: 2017-12-25 ((2458113j,0s,0n),+0s,2299161j)> => "Christmas"
}

Related

Ruby - How many days?

I need to calculate how many days lived on earth based on three parameters : day, month and year.
I don't know how to convert the input onto a date; and then how to convert the date onto number of days.
This is my code for the moment...
require 'date'
def age_in_days(day, month, year)
lived = (day+"-"+month+"-"+year).to_s
date_lived Date.parse(lived)
return (Date.today - date_lived).to_i
end
You can create a Date object directly with:
Date.new(year, month, day)
There's no need to convert it to a string and parse. Parsing could also be dangerous. Is 1982-04-02 the 4th of February or 2nd of April?
You cannot add a number and string like this, BTW. Should 1 + '2' be '12' or 3? Ruby cannot decide for you so you need to explicitly convert integers to string.
day.to_s + "-" + month.to_s + "-" + year.to_s
or simply
[day, month, year].join('-')
But you don't need it anyway:
require 'date'
def age_in_days(day, month, year)
birthdate = Date.new(year, month, day)
(Date.today - birthdate).to_i
end

Converting epoch time to date in logstash using ruby filter

I have a field name "timestamp" in my configuration. It holds an array of data in epoch time (miliseconds). I want to use Ruby filter to convert each epoch time in the array and convert into Date format consumable by Kibana. I am trying to convert each date field and store in a new field as an array. I am getting syntax errors. Can anyone help me out ? I am new to Ruby.
ruby {
code => {'
event.get("timestamp").each do |x| {
event["timestamp1"] = Time.at(x)
}
'}
}
I don't know about logstash, but the Ruby code you include within quotes is invalid. Try this:
ruby {
code => {'
event.get("timestamp").each { |x| event["timestamp1"] = Time.at(x) }
'}
}
If you intend your timestamp key to increment, then you need to include an index:
ruby {
code => {'
event.get("timestamp").each_with_index { |x, i| event["timestamp#{i}"] = Time.at(x) }
'}
}
//This will take an timestamp array with values in milliseconds from epoch time and create a new field with parsed time. This code is part of ruby filter Note : This does not convert into Date field format
code => '
timestamps = Array.new
event.get("timestamp").each_with_index { |x, i|
timestamps.push(Time.at(x.to_i / 1000)) }
event.set( "timestamp1" , timestamps)
'

How do I iterate through each date between two defined dates in ruby?

I have two dates, the begins_at (datetime) and the ends_at (datetime). I now simply want to iterate through every date between these two (including the ends_ and begins_at dates).
begins_at = Date.strptime("12/10/2014", "%m/%d/%Y")
ends_at = Date.strptime("12/20/2014", "%m/%d/%Y")
//iterate through all dates in this range kind of like this:
range = DateRange(begins-at,ends-at)
range.DateTime.each do |date|
....
end
Does anyone have an idea how I could achieve this?
You should use Range:
(begins_at..ends_at).each do |date|
# ...
end

How to change date from "mm-dd-yy" to "yy-mm-dd"?

date = "21-12-2013"
in a db table, I have a date column with "20131221", and I need to compare the date. Is the format wrong? How can I change the format form dd-mm-yy to yy-mm-dd?
Using regular expression (String#sub):
date = "21-12-2013"
date.sub(/(\d+)-(\d+)-(\d+)/, '\3-\2-\1')
# => "2013-12-21"
Using DateTime::strptime and DateTime#strftime:
require 'date'
DateTime.strptime(date, '%d-%m-%Y').strftime('%Y-%m-%d')
# => "2013-12-21"

Date comparison in Rails 3.2

Stage:
I have this model:
Promo(id: integer, start_date: datetime, end_date: datetime)
I want to know which current promotions.
May be our query should be like:
SELECT * FROM promos WHERE now BETWEEN start_date AND end_date;
Question:
How should I make it in Ruby?
Which is the correct way?
Thank you.
Rails is intelligent. If you retrieve a date/time, it will converted to DateTime object.
On contrary, passing DateTime object to the where clause (for Rails 3.x), it will correctly build the where clause.
String passed to where clause will be passed to the SQL where clause. If you pass an array,
second and later elements will be replaced with '?' character in the first element.
So, for your case:
Promo.where(["? between start_date and end_date", DateTime.now])
works. I verified on my Rails model(Position) which happen to have start_date and end_date, and works correctly:
[1] pry(main)> Position.where(["? between start_date and end_date", DateTime.now]).count
=> 2914
It's on Rails 3.2.8 with PostgreSQL.
Yes, you can use comparison operators to compare dates e.g.:
irb(main):018:0> yesterday = Date.new(2009,6,13)
=> #<Date: 4909991/2,0,2299161>
irb(main):019:0> Date.today > yesterday
=> true
But are you trying to compare a date to a datetime?
If that's the case, you'll want to convert the datetime to a date then do the comparison.
or
Date.parse('2010-11-01') < Date.today
will return true if '2010-11-01' has already passed
I hope this helps.
Haven't tested this, but try something like:
currentTime = Time.now()
Promo.find(
:all,
:conditions => ['start_date < ? AND end_date > ?', currentTime, currentTime]
)
You might need to use the Date class if the Time class doesn't work

Resources