calculate difference in time in days, hours and minutes - ruby-on-rails-3

UPDATE: I am updating the question to reflect the full solution. Using the time_diff gem Brett mentioned below, the following code worked.
code:
cur_time = Time.now.strftime('%Y-%m-%d %H:%M')
Time.diff(Time.parse('2011-08-12 09:00'), Time.parse(cur_time))
Thanks, Brett.

Without using a external gem, you can easily get differences between dates using a method like this:
def release(time)
delta = time - Time.now
%w[days hours minutes].collect do |step|
seconds = 1.send(step)
(delta / seconds).to_i.tap do
delta %= seconds
end
end
end
release(("2011-08-12 09:00:00").to_time)
# => [7, 17, 37]
which will return an array of days, hours and minutes and can be easily extended to include years, month and seconds as well:
def release(time)
delta = time - Time.now
%w[years months days hours minutes seconds].collect do |step|
seconds = 1.send(step)
(delta / seconds).to_i.tap do
delta %= seconds
end
end
end
release(("2011-08-12 09:00:00").to_time)
# => [0, 0, 7, 17, 38, 13]

I've used time_diff to achieve this sort of thing easily before, you may want to check it out.

Related

Basic DateTime Algebra

How do i go about writing some basic algebra math in vb.net?
Example:
I need to schedule a process to run 60 days before start date of an object.
When my process runs I do:
Now(UTC) - StarDate(UTC) = days diff
If days diff less than 60, i run my process immediately.
If its over 60 days, i need to schedule my process to run again in 60 days.
So this leaves me with:
X - [daysDiff] = 60
I know how to solve this on paper but not in vb.net code.
Example:
X - 107 = 60
add 107 to each side, i have my # of days to add (107)
How do i accomplish this in VB.net?
If you want to know when to run it: if it's over 60 days, then subtract 60 from that value, that will tell you when when to check again.... so if you do the initial check and it comes back 61 days different, it's over 60, so you subtract 60, leaving 1. So now you know you need to schedule it in 1 day. If you do the initial check and it comes out 107, you subtract 60 and the result is 47... so you know in 47 days, you need to run it again as that will be 60 days out. It's two simple steps.

Label rows by most time spent in a time interval

I have a data set with actions that have a start and end time. I'd like to label each row part of day (morning, noon, evening, night). Since some actions might start at one part and end in the other, I'd like to consider where most of the time was spent.
Say that morning is 6am-11am and noon is 11am-2am and I have an action between 10:30am to 1pm it should be labeled as noon.
One approach I though was to create a column for each part of day and calculate the number of seconds spent in each part (per row) then use idxmax to find the part of day. But then how do I calculate the time overlap between (start, stop) to the part of day?
df = pd.DataFrame([[0, 4],
[2, 5.2],
[0.2, 6],
[3, 4.1]], columns=['start', 'end'])
periods = {'morning': (0, 3),
'afternoon': (3, 6)}
for name, (start, stop) in periods.items():
df['i_start'] = start
df['i_end'] = stop
overlap = df[['end', 'i_end']].min(axis=1) - df[['start', 'i_start']].max(axis=1)
df.loc[overlap >= 0, name] = overlap[overlap >= 0]
result = df[list(periods)].idxmax(axis=1)
... should do the job (as long as you don't have actions spanning from one day to the next).

How to register every day local notification at certain time?

How can I realize everyday local notifications in my app? So at first run I need to register first local notification at 14:00 and then everyday at 14:00 notification should appear.
User can change this time in app's settings.
How to do this mechanism?
You need to handle the notifcations on your end, but to make a timer that countsdown to a certain time every day, you would need to do something like this:
local targetDate = os.time{ year=2014, month=11, day=8, hour=0, sec=0 } -- Get the date that you want to count down to, in seconds
local text = false
local function enterFrame(event)
if text then text:removeSelf() end -- Everyframe, remove the old text object
local timeRemaining = (targetDate-os.time()) -- Take the difference between the target time and the current time
local days = timeRemaining / 86400 -- get the number of days left by dividing the remaining seconds by the number of seconds in a day
local hours = days%1 * 24 -- get the number of hours left by multiplying the remainder by the number hours in a day
local minutes = hours%1 * 60 -- get the number of minutes by multiplying the remainder by the number of minutes in an hour
local seconds = math.floor( minutes%1 * 60 + 0.5) -- multiply the remainder one more time by the number of seconds in a minute, and round to the nearest second.
-- make a new text object to display all the info
text = display.newText( "Will be available in "..math.floor(days).." days "..math.floor(hours).." hrs "..math.floor(minutes).." mins "..seconds.." secs ", 25, 140)
end
Runtime:addEventListener( "enterFrame", enterFrame )
You can repurpose your code to work with your project, but you need to use OS time and do certain calculations to each variable in order to get the time. Good luck.

how to calculate time difference in rails

I have a field that is a timestamp. I want to calculate the time difference between that timestamp and the current time and show the time as something humanly readable like
2 days remaining #don't show hours when > 1 day is remaining
once less than 1 day is remaining I'll have a javascript countdown ticker.
I've built the dotiw library to do exactly this: http://github.com/radar/dotiw.
This is based off the distance_of_time_in_words method in Rails which is not quite accurate enough, and so I've made it more accurate with dotiw.
Try this:
if end_date < Time.now # ended already
return 'Ended'
elsif end_date > (Time.now + 1.day) # more than 1 day away
diff_in_days = ((end_date - Time.now).to_i / 1.day)
days_string = diff_in_days.to_s
days_string += (diff_in_days > 1) ? ' Days' : ' Day'
return days_string
else # ending today
diff_in_HMS = Time.at(end_date - Time.now).gmtime.strftime('%R:%S')
return diff_in_HMS
end
It prints "X Days" if end_date is > 1 day away, HH:MM:SS if ending today, and "Ended" if end_date was in the past.

Rails number of weeks in month

How can I in rails calculate the number of weeks in a given month?
Thanks
i dont know exactly what you want... But maybe you want something like this:
(Time::days_in_month(05,2010).to_f / 7)
#> 4.42857142857143
I needed to know how many weeks including partial weeks there were in a month. Think of it like rows in a calendar. How many rows do you need? You have to consider the number of days and also what day the month starts on. October 2011 actually has 6 unique weeks for example.
This is my answer (#date is the current date):
#week_count = (0.5 + (#date.at_end_of_month.day + #date.at_beginning_of_month.wday).to_f / 7.0).round
You can use the following methods:
WEEK_NUMBER_FORMAT = '%W'
# Returns the first day of month.
# If invoked without any arguments, this would return the
# first day of current month
def first_day_of_month(date_time=Time.now)
date_time.beginning_of_month
end
# Returns the last day of month.
# If invoked without any arguments, this would return the
# last day of current month
def last_day_of_month(date_time=Time.now)
date_time.end_of_month
end
# Returns the week number in the year in which the specified date_time lies.
# If invoked without any arguments, this would return the
# the week number in the current year
def week_number(date_time=Time.now)
date_time.strftime(WEEK_NUMBER_FORMAT).to_i
end
# Returns the number of weeks in the month in which the specified date_time lies.
# If invoked without any arguments, this would return the
# the number of weeks in the current month
def weeks_in_month(date_time=Time.now)
week_number(last_day_of_month(date_time)) - week_number(first_day_of_month(date_time)) + 1
end
Usage: weeks_in_month(date_time)
Hope it helps:
Thanks,
Jignesh
def number_of_weeks_in_month
4
end
Use the gem week_of_month
d = Date.new(2012,1,1)
d.total_weeks
=> 5
def number_of_weeks_month(start_of_month, count, end_of_month)
if start_date > end_of_month
return count
else
number_of_weeks_month(start_date.end_of_week + 1, count + 1, end_of_month)
end
end
get number of weeks for month like this
number_of_weeks_month(Date.parse("2017-11-01"),0,Date.parse("2017-11-30"))
this return 4
Date.today.end_of_month.day/7
=> 4