How do I create a date object from a URL? - ruby-on-rails

I have a date paramater in my URL:
http://localhost:3000/restaurants/1/restaurant_stats.pdf?date=2013-05-02
I want to use this date if the parameter exists otherwise use today's date.
if params[:date]
date = Date.new(params[:date].to_i)
else
date = Date.today
end
The above code doesnt work. It sets the date to Jan 01 of the year specified.

if params[:date]
date = Date.parse(params[:date])
else
date = Date.today
end

Related

Change datetime to current user UTC

I am trying to change datetime to users UTC.
e.g
date = anydate (2017-11-03)
time = currenttime (Time.now)
Time.zone = current_user.time_zone
Required = date + time (to current_user.timezone)
You can parse date & time in the user's time zone:
date = '2017-11-03'
time = Time.now
Time.zone = current_user.time_zone
required = Time.zone.parse(date + ' ' + time.strftime('%H:%M:%S'))
date = "2017-11-03"
user_date = date.to_datetime
zone = current_user.time_zone
user_date.in_time_zone(zone)
for example: -
"2017-11-03".to_datetime.in_time_zone("Chennai")
=> Fri, 03 Nov 2017 05:30:00 IST +05:30

Ruby difference between two dates

I need to check the difference between two date and check if there is 24 hours or more. I am having trouble in calling the to_time method of the date object. This to_time method is turning the minutes and seconds if the current date to 00:00:00.
Example:
date = Date.rfc3339('2017-08-16T17:55:49.000-03:00')
=> #<Date: 2017-08-16 ((2457982j,0s,0n),+0s,2299161j)>
date.to_time
2017-08-16 00:00:00 -0300
(( Date.today.to_time - date.to_time)/3600).round
=> 24
Date does not include Time. Use DateTime instead.
require 'date'
dt = DateTime.rfc3339('2017-08-16T17:55:49.000-03:00')
puts (Time.now - dt.to_time)/(60*60) > 24
You can do:
datetime_1 = DateTime.parse("2017-08-17T13:36:03-04:00")
datetime_2 = DateTime.parse("2017-08-16T13:33:03-04:00")
greatest_datetime = [datetime_1, datetime_2].max
smallest_datetime = [datetime_1, datetime_2].min
(greatest_datetime - 1.day) > smallest_datetime

Ruby DateTime: Get next 5:15pm (or similar)

So, given a DateTime object, and a fixed time, I want to get the next occurrence of the fixed time after the given DateTime object.
For example, given the date of 14th March, 2016, 4:00pm, and the time of 5:15pm, I want to return 14th March, 2016 5:15pm.
However, given the date of 14th March, 2016, 6:00pm, and the time of 5:15pm, I want to return 15th March, 2016, 5:15pm, since that's the next occurrence.
So far, I've written this code:
# Given fixed_time and date_time
new_time = date_time
if fixed_time.utc.strftime("%H%M%S%N") >= date_time.utc.strftime("%H%M%S%N")
new_time = DateTime.new(
date_time.year,
date_time.month,
date_time.day,
fixed_time.hour,
fixed_time.min,
fixed_time.sec
)
else
next_day = date_time.beginning_of_day + 1.day
new_time = DateTime.new(
next_day.year,
next_day.month,
next_day.day,
fixed_time.hour,
fixed_time.min,
fixed_time.sec
)
end
# Return new_time
It works, but is there a better way?
I would construct the new date time just once and add 1 day if needed:
# Given fixed_time and date_time
new_date_time = DateTime.new(
date_time.year,
date_time.month,
date_time.day,
fixed_time.hour,
fixed_time.min,
fixed_time.sec
)
# add 1 day if new date prior to the given date
new_date_time += 1.day if new_date_time < date_time
Here's a little stab at refactoring it to remove some of the redundancy:
# Given fixed_time and date_time
base_date = date_time.to_date
if fixed_time.to_time.utc.strftime("%T%N") <= date_time.to_time.utc.strftime("%T%N")
base_date = base_date.next_day
end
new_time = DateTime.new(
base_date.year,
base_date.month,
base_date.day,
fixed_time.hour,
fixed_time.min,
fixed_time.sec
)
# Return new_time
The biggest changes are that the base_date is determined before the new_time is created, so that it can be used there.
I also used the next_day method on DateTime to get the next day, and used the "%T" format specifier as a shortcut for "%H:%M:%S"
Here's a little test program that to show that it works:
require "date"
def next_schedule(fixed_time, date_time)
# Given fixed_time and date_time
base_date = date_time.to_date
if fixed_time.to_time.utc.strftime("%T%N") <= date_time.to_time.utc.strftime("%T%N")
base_date = base_date.next_day
end
new_time = DateTime.new(
base_date.year,
base_date.month,
base_date.day,
fixed_time.hour,
fixed_time.min,
fixed_time.sec
)
# Return new_time
end
StartTime = DateTime.strptime("2016-02-14 17:15:00", "%F %T")
Dates = [
"2016-03-14 16:00:00",
"2016-03-14 18:00:00"
]
Dates.each do |current_date|
scheduled = next_schedule(StartTime, DateTime.strptime(current_date, "%F %T"))
puts "Scheduled: #{scheduled.strftime('%F %T')}"
end
The output of this is:
Scheduled: 2016-03-14 17:15:00
Scheduled: 2016-03-15 17:15:00
It's using the test cases described in the question, and it gets the expected answers.

Ruby how can i get date of Monday after a given date

Given A Day i-e Monday and a Date e.g: Sat, 09 Aug 2014
how can i get the date of Monday coming immediately after given Date
Update:
def get_date_after(date, day)
return date if date.wday == day.to_date.wday
days_difference = (date - day.to_date).to_i
result = day.to_date + days_difference + (day.to_date.wday - date.wday)
result = result + 1.week if result.to_date < date
end
I was looking for something like above method, calling it would return the date of the day passed coming immediately after the date passed
get_date_after(DateTime.parse("15/09/2014").to_date, "Wednesday") #=> 17/09/2014
The chronic gem allows you to parse date expressions, e.g. Chronic.parse("next Monday"). You can add a reference date with the now option. Here's how it could be used for your method:
def get_date_after(date, day)
Chronic.parse("next #{day}", now: date)
end
In rails you can do it this way
Date.today.next_week(day = :monday)

how to iterating days

I have a code for looping days.this to make leaves. I want column signin and signout on attendance will filling automatically start at startdate and end at enddate.
exp I input :
startdate: 2012-11-08 01:30:00
enddate: 2012-11-10 01:30:00
i want output like this:
2012-11-08 01:30:00
2012-11-09 01:30:00
2012-11-010 01:30:00
for i in 0..((#leafe.enddate - #leafe.startdate).to_i)
#attendance = Attendance.new
#attendance.signin = '2012-11-08 01:30:00' #value must chang automatically
#attendance.signout = '2012-11-08 10:30:00'#value must chang automatically
#attendance.user_id = #leafe.user_id
#attendance.save
end
thanks before
If startdate is of type Date, why not just do,
#attendance.signin = #leafe.startdate+i
#attendance.signout = #leafe.startdate+i
Why you using for loop? It looks like javacode.
Use instead block with range like:
(Time.now.beginning_of_day.to_i..Time.now.to_i).step(3600) do |n|#step one hour for example
#attendance = Attendance.new
.......
#attendance.signin = #leafe.startdate
#attendance.signout = #leafe.startdate + n # u can change time interval to any what you want
end

Resources