Get the 15th and 30th day dynamically Rails - ruby-on-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")

Related

How to create a new JSON object in every loop iteration

I am working on a feature that given my daily work hours and the start and end date of my contract displays in a calendar my work hours. The problem is when I have 2 or more shifts on the same day. Let's say Julian has a shift from 03:00 to 04:00 and another one on the same day from 5:00 to 6:00 every Monday starting from July 17, 2019 to July 31, 2019. That means that my calendar should display these 2 shifts in July 22 and July 29. I have coded the logic to get me the correct dates. As of right now my JSON response looks like this
{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":["03:00","05:00"],"end_time":["04:00","06:00"]},{"user_":"Julian","start":"2019-07-29","day":"Monday","start_time":["03:00","05:00"],"end_time":["04:00","06:00"]}
which is being generated by the following code in my JSON builder file
json.array! event.each do |inevent|
json.id hr_schedule.id
json.user_id hr_schedule.user_id
json.start inevent.strftime('%Y-%m-%d')
day_of_week = inevent.strftime('%A')
json.day day_of_week
if day_of_week == "Monday"
json.start_time hr_schedule.monday_st
json.end_time hr_schedule.monday_end
elsif day_of_week == "Tuesday"
json.start_time hr_schedule.tuesday_st
json.end_time hr_schedule.tuesday_end
elsif day_of_week == "Wednesday"
json.start_time hr_schedule.wednesday_st
json.end_time hr_schedule.wednesday_end
elsif day_of_week == "Thursday"
json.start_time hr_schedule.thursday_st
json.end_time hr_schedule.thursday_end
elsif day_of_week == "Friday"
json.start_time hr_schedule.friday_st
json.end_time hr_schedule.friday_end
elsif day_of_week == "Saturday"
json.start_time hr_schedule.saturday_st
json.end_time hr_schedule.saturday_end
elsif day_of_week == "Sunday"
json.start_time hr_schedule.sunday_st
json.end_time hr_schedule.sunday_end
end
end
what I want to achieve is to be able to have all my events as a unique JSON object like the following
{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":"03:00","end_time":"04:00"},{"user":"Julian","start":"2019-07-22","day":"Monday","start_time":"05:00","end_time":"06:00"},
{"user":"Julian","start":"2019-07-29","day":"Monday","start_time":"03:00","end_time":"04:00"},{"user":"Julian","start":"2019-07-29","day":"Monday","start_time":"05:00","end_time":"06:00"}
I'm not sure what class json is, nor what array! is doing. But the basic way to do what you want is to use map to turn your events into an Array of Hashes. Then turn the Array into JSON with to_json.
calendar = event.map do |inevent|
json = {}
json[:id] = hr_schedule.id
json[:user] = hr_schedule.user_id
json[:start] = inevent.strftime('%Y-%m-%d')
json[:day] = inevent.strftime('%A')
case inevent.wday
when 0
json[:start_time] = hr_schedule.sunday_st
json[:end_time] = hr_schedule.sunday_end
when 1
json[:start_time] = hr_schedule.monday_st
json[:end_time] = hr_schedule.monday_end
when 2
json[:start_time] = hr_schedule.tuesday_st
json[:end_time] = hr_schedule.tuesday_end
when 3
json[:start_time] = hr_schedule.wednesday_st
json[:end_time] = hr_schedule.wednesday_end
when 4
json[:start_time] = hr_schedule.thursday_st
json[:end_time] = hr_schedule.thursday_end
when 5
json[:start_time] = hr_schedule.friday_st
json[:end_time] = hr_schedule.friday_end
when 6
json[:start_time] = hr_schedule.saturday_st
json[:end_time] = hr_schedule.saturday_end
end
json
end
puts calendar.to_json
I've simplified it a bit by using a case/when and Time#wday. strftime(%A) might change if the language of the application changes, and the day of week numbers are harder to typo.
As a side note, this event structure limits itself to only events which end before midnight. Consider instead using a full ISO8061 datetimes for start and end. In general, it's easier to work with a full datetime than separate date and time. The event day can be inferred from start.
{"user":"Julian","start":"2019-07-22T03:00","end":"2019-07-22T04:00"}
Or if the events are relative, like they happen every Monday, consider a start and a duration. And use an ISO weekday number for the day instead of a string, less parsing for the receiver to do.
{"user":"Julian","day":1,"start":"03:00","duration":"P1H"}

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

Rails Iteration by month given range of dates

I'm trying to follow this Railscast and create a morris.js line chart for my Enquiry model.
I've grouped the counts using date_trunc into months, but now I'm not quite sure at how to get the X-axis to iterate over months (e.g Jun 2012, Jul 2013) as opposed to by date as in the railscasts notes.
I've tried the range#step method here, but now the graph displays only one date (2012-07-01) without a count and nothing else. Commenting out the .step(1.month) method from the range variable and the graph works fine but the x-axis iterates by date.
class Enquiry < ActiveRecord::Base
def self.chart_data(start = 1.year.ago)
total_count = total_count_by_month(start)
start = start.to_date.beginning_of_month
today = Date.today.beginning_of_month
range = (start..today).step(1.month)
range.map do |month|
{
created_at: month,
total_enquiries: total_count[] || 0
}
end
end
def self.total_count_by_month(start)
enquiries = unscoped.where(created_at: start.beginning_of_month..Time.now)
enquiries = enquiries.group("date_trunc('month', created_at)")
enquiries = enquiries.select("date_trunc('month', created_at) as created_at, count(*) as count")
enquiries.each_with_object({}) do |enquiry, counts|
counts[enquiry.created_at.to_date] = enquiry.count
end
end
end
How do I get the chart's x-axis to iterate by months (Jun 2013, Jul 2013 ....) instead of by dates?
For anyone else facing the same problem, the solution is outlined below:
def self.chart_data(start = 1.year.ago)
total_count = total_count_by_month(start)
##############################################
start = start.to_date.beginning_of_month
today = Date.today.beginning_of_month
range = (start..today).select {|d| d.day == 1}
##############################################
range.map do |month|
{
created_at: month,
total_enquiries: total_count[] || 0
}
end
end
The chart's x-axis now iterates by month.
The solution is found here.
I'm still looking for solutions on how the chart dates might display (%b %Y) as opposed to the current format of (yyyy-mm-dd).

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