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
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")
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
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
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)