Ruby how can i get date of Monday after a given date - ruby-on-rails

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)

Related

How to make working hours in ruby ​on rails?

I'm creating a chat panel with a bot. Every message sent by the bot will depend on working hours. For example, during business hours the customer sends a message to the bot and the bot will reply to the text message with the sentence: Hello, you sent a message during business hours
and for example when outside working hours the customer sends a text message to the bot and the bot will reply to the message with the sentence: Hello, you sent a message outside of working hours. Where working hours apply every Monday-Saturday at 08: 30-17: 00.
I made a configuration using an array like this:
start_on = [
"Monday, 08:30:00",
"Tuesday, 08:30:00",
"Wednesday, 08:30:00",
"Thursday, 08:30:00",
"Friday, 08:30:00",
"Saturday, 08:30:00"
]
end_on = [
"Monday, 17:00:00",
"Tuesday, 17:00:00",
"Wednesday, 17:00:00",
"Thursday, 17:00:00",
"Friday, 17:00:00",
"Saturday, 17:00:00"
]
And what I want to ask is how to set the current time current_time = (Time.now.to_time) by configuring the working hours in the array start_on and end_on using ruby ​​on rails?
This function returns true if the day is not sunday and the time is between 08:30 and 17:00
def is_working_hour?(time)
!time.sunday? && time.to_s(:time).between?('08:30','17:00')
end
is_working_hour?(Time.now)
I would personally structure the start and end times like this using wday as the day of the week (0 is sunday so 1 == monday):
times = [
{ day: 1, start: "08:30:00", end: "17:00:00" },
{ day: 2, start: "08:30:00", end: "17:00:00" },
...
]
Once you've got a structure like this (you can work it work it out from the above too of course), you can use the following to get today's times.
today = times.detect { |time| time[:day] == Time.now.wday }
Then start and end times are just:
start_time = Time.parse(today[:start])
end_time = Time.parse(today[:end])
# start_time = Time.parse("08:30:00")
# end_time = Time.parse("17:00:00")
Then it's simply a matter of seeing if the current time is inside that range:
Time.now > start && Time.now < end_time
=> true
To convert the values in DateTime, you have to strptime the weekday for Date, and the time for the Time. Then combine the resulting date and time to obtain the DateTime.
curr_index=1 #loop index if necessary
#get start datetime
arr=start_on[curr_index].split(",")
d = Date.strptime(arr[0].strip, '%A')
t = Time.strptime(arr[1].strip, ' %T')
startime = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
#get end datetime
arr=end_on[curr_index].split(",")
d = Date.strptime(arr[0].strip, '%A')
t = Time.strptime(arr[1].strip, ' %T')
endtime = DateTime.new(d.year, d.month, d.day, t.hour, t.min, t.sec, t.zone)
return (startime..endtime).cover? Time.now #check if within the range

Get the 15th and 30th day dynamically Rails

How can i dynamically get the 15th and last day of each month based on the date of which it was created? Saying created date was today, I want to get the next 15th and 30th day continuously
I tried using code this but it wont return any value
Controller
req = #request.created_at
#mid_month = req.beginning_of_month + 14
#end_month = mid_month + 15
View
<% #mid_month %>
Format of req
2017-10-24 00:52:00
ActiveSupport has some nice helpers for the Time class-
time = Time.parse(#request.created_at)
last_day = time.end_of_month.day
#mid_month = time.strftime("%Y-%m-15 %H:%M:%S")
#end_month = time.strftime("%Y-%m-#{last_day} %H:%M:%S")

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

How do I create a date object from a URL?

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

How can I find records from today, yesterday and so on with Ruby on Rails?

I want to find all records, say Posts, created today with Ruby on Rails, then all Posts created yesterday, and so on… how should I do?
Thank you,
Kevin
Try this:
#Today
Posts.find(:all, conditions: { :created_at => Date.today...Date.today + 1 })
#Yesterday
Posts.find(:all, conditions: { :created_at => Date.today - 1...Date.today })
Or this (preferable, in my opinion):
#Today
Posts.find(:all, conditions: ["DATE(created_at) = ?", Date.today] )
#Yesterday
Posts.find(:all, conditions: ["DATE(created_at) = ?", Date.today - 1] )
As a rule I store all dates on my server in UTC timezone and let the UI handle any timezone conversion.
To get the sort of query you are after to work correctly I had to massage the incoming date into a
UTC specific time range first.
require 'date'
class Post < ActiveRecord::Base
def self.created(a_date)
return Post.where(created_at: to_timerange(a_date))
end
private
def self.to_timerange(a_date)
raise ArgumentError, "expected 'a_date' to be a Date" unless a_date.is_a? Date
dts = Time.new(a_date.year, a_date.month, a_date.day, 0, 0, 0).utc
dte = dts + (24 * 60 * 60) - 1
return (dts...dte)
end
end
This then allows you to call
# today
posts = Post.created(Date.today)
# yesterday
posts = Post.created(Date.today - 1)
To query using a range I prefer the following:
yesterday = Date.yesterday
start = yesterday.beginning_of_day
#Fri, 27 Nov 2020 00:00:00 UTC +00:00
end = yesterday.end_of_day
# Fri, 27 Nov 2020 23:59:59 UTC +00:00 - the value here is one second before midnight
# meaning we should use an inclusive range using two dots:
range = start..end
Post.where(created_at: range)

Resources