Difference between 2 timestamps(String) in hours in Rails - ruby-on-rails

I have one time in a hash as
"Time": "2022-11-08T22:59:00Z"
and also i would be taking the current time in the same format using
Time.now.utc.iso8601
I want to compare these 2 times(Time-CurrentTime) to get their difference in hours. I cant quite figure out how to do that as i am new to ruby and rails. Please help me out.
ruby 2.7.5p203
Rails 4.2.11
I tried parsing them using strftime() but maybe i was doing it wrong. Please suggest.

It's better to compare Time object not strings. You can parse a time string using this method Time.parse. The difference will be in seconds that's why you need to divide the result by 3600
your_hash = { "Time": "2022-11-08T22:59:00Z" }
(Time.now.utc - Time.parse(your_hash[:"Time"])) / 3600

Related

How to create time property that is always 24 hours behind current time?

I am creating a time object, which I use to gather all info from the past 24 hours, I have no issue creating the object displaying the current time. But I am unsure as to how to set it exactly 24 hours in the past, without having the timezone attached.
def set_time
#past_time = Time.now.to_s(:db) - 1.days
end
Expected Output Format :
"2021-11-29 09:15:17"
Result:
undefined method `-' for "2021-11-29 10:19:46":String
You are subtracting the time from the string object as you converted Time.now into the string using to_s.
Instead of you can do this
(Time.new - 1.days).to_s(:db)
Note: You will get multiple ways to accomplish these rails. You can improve the code readability and understanding of code by doing this.
Example:
DateTime.now.days_ago(1)
The easiest I can think of would be:
24.hours.ago.to_s(:db)
Note that the returned time would default to UTC in this case.
You can use DateTime#advance from ActiveSupport:
Time.current.advance(hours: -24)
# or
Time.current.advance(days: -1)
Note that in timezones that use DST a day is not always 24 hours so the two are not actually equivilent. You can also use the methods that ActiveSupport::Duration monkeypatches onto Integer:
24.hours.ago
1.day.ago
This always uses your default timezone though.

Rails timestamps, See how much time passed since last time

In my app I want to print out the duration of time I spent from I made the model until I updated it.
So if I have the value
:created_at set to 2016-04-13 14:00:49 UTC
and
:updated_at set to 2016-04-13 15:05:49 UTC
I want to print out that it took 1hour and 5minutes. (or just 01.05).
How do I do this?
I'm not sure why this was downvoted, though a little googling would probably have gotten you to the right answer fairly quickly.
What you're looking for is called time_ago_in_words
Here is the doc http://apidock.com/rails/ActionView/Helpers/DateHelper/time_ago_in_words
And usage is:
time_ago_in_words #object.created_at
time_ago_in_words #object.updated_at
If you want to use it the console to play with it, make sure you preface it with helper so it's loaded into console
e.g.
helper.time_ago_in_words #object.created_at
update
For checking between 2 dates, not just one date from right now, then you can use distance_of_time_in_words
distance_of_time_in_words(#object.created_at, #object.updated_at)
That gives words like
12 days ago
If you're ONLY looking for hours, and nothing else then you can use basic subtraction and division
#object.updated_at.to_i - #object.created_at.to_i) / 60 / 60
You can try this
diff =#object.updated_at.to_time.to_i - #object.created_at.to_time.to_i
hour = "#{diff / 3600}:#{(diff % 3600) / 60}"

strange behavior on datetime

I have the following record on my data base:
"availability_date" : ISODate("2014-09-29T15:45:00.000Z")
and I trying to get the differences between two datetime like this:
#minutes = (((#date_time.to_time) - (Time.now))/60).round
but the #date_time have the following value and I don't understand why???
"2014-09-29 17:45:00 +0200"
could someone help me please.
Thanks in advance
I don't think there is any problem, The datetime in #date_time is the same as in your database. The +0200 at the end means that it is written in a different timezone, here GMT +2, I guess. It is probably the time zone that your computer uses.
What is the result you expect ? Can you give an example ? And be sure to read the answer to In Ruby on Rails, what's the difference between DateTime, Timestamp, Time and Date?
Good luck.
Try to convert them to integer using to_i m this give you the number of seconds in unix time, the n it's probably more easy to do a calculation

Rails. How to store time of day (for schedule)?

I'm writing an app that keeps track of school classes.
I need to store the schedule. For example: Monday-Friday from 8:am-11am.
I was thinking about using a simple string column but I'm going to need to make time calculations later.
For example, I need to store a representation of 8am, such as start_at:8am end_at:11am
So how should I store the time? What datatype should I use? Should I store start time and number of seconds or minutes and then calculate from there? or is there an easier way?
I use MySQL for production and SQLite for development.
I made an app recently that had to tackle this problem. I decided to store open_at and closed_at in seconds from midnight in a simple business hour model. ActiveSupport includes this handy helper for finding out the time in seconds since midnight:
Time.now.seconds_since_midnight
This way I can do a simple query to find out if a venue is open:
BusinessHour.where("open_at > ? and close_at < ?", Time.now.seconds_since_midnight, Time.now.seconds_since_midnight)
Any tips for making this better would be appreciated =)
If you're using Postgresql you can use a time column type which is just the time of day and no date. You can then query
Event.where("start_time > '10:00:00' and end_time < '12:00:00'")
Maybe MySQL has something similar
Check out the gem 'tod' for Rails 4 or Time_of_Day for Rails 3. They both solve the problem of storing time in a database while using an an Active Record model.
SQL has a time data type but Ruby does not. Active Record addresses this difference by representing time attributes using Ruby’s Time class on the canonical date 2000-01-01. All Time attributes are arbitrarily assigned the same dates. While the attributes can be compared with one another without an issue, (the dates are the same), errors arise when you attempt to compare them with other Time instances. Simply using Time.parse on a string like ”10:05” adds today’s date to the output.
Lailson Bandeira created a created solution for this problem, the Time_of_Day gem for Rails 3. Unfortunately the gem is no longer maintained. Use Jack Christensen’s ‘tod’ gem instead. It works like a charm.
This ruby gem converts time of day to seconds since midnight and back. The seconds value is stored in the database and can be used for calculations and validations.
Define the time of day attributes:
class BusinessHour < ActiveRecord::Base
time_of_day_attr :opening, :closing
end
Converts time of day to seconds since midnight when a string was set:
business_hour = BusinessHour.new(opening: '9:00', closing: '17:00')
business_hour.opening
=> 32400
business_hour.closing
=> 61200
To convert back to time of day:
TimeOfDayAttr.l(business_hour.opening)
=> '9:00'
TimeOfDayAttr.l(business_hour.closing)
=> '17:00'
You could also omit minutes at full hour:
TimeOfDayAttr.l(business_hour.opening, omit_minutes_at_full_hour: true)
=> '9'
I would store the starting hour and the duration within the database, using two integer columns.
By retrieving both values, you could convert the starting hour as in (assuming that you know the day already:
# assuming date is the date of the day, datetime will hold the start time
datetime = date.change({:hour => your_stored_hour_value , :min => 0 , :sec => 0 })
# calculating the end time
end_time = datetime + your_stored_duration.seconds
Otherwise, hava a look at Chronic. The gem makes handling time a little bit easier. Note that the changemethod is part of rails, and not available in plain Ruby.
The documentation on DateTime for plain Ruby can be found here.
Also, whatever you do, don't start storing your dates/time in 12-hour format, you can use I18nin Rails to convert the time:
I18n.l Time.now, :format => "%I.%m %p", :locale => :"en"
I18n.l Time.now + 12.hours, :format => "%I.%m %p", :locale => :"en"
You can also get from this notation, that you can store you duration in hours, if you want, you can then convert them rather easily by:
your_stored_value.hours
if stored as an integer, that is.
Suggestion:
Don’t worry about a specific datatype for that. A simple solution would be:
In the database, add an integer type column for start_time and another for end_time. Each will store the number of minutes since midnight.
Ex: 8:30am would be stored as 510 (8*60+30)
In the form, create a select field (dropdown) that displays all available times in time format:Ex.: 10am, 10:30am and so on.
But the actual field values that get saved in the database are their integer equivalents:
Ex: 600, 630 and so on (following the example above)
I assume you are using some kind of database for this. If you are using MySQL or Postgresql, you can use the datetime column type, which Ruby/Rails will automatically convert to/from a Time object when reading/writing to the database. I'm not sure if sqlite has something similar, but I imagine it probably does.
From the SQLite 3 website,
"SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions."
You can then manipulate the values using the Date and Time functions outlined here.

Calculating how many 'Midnights' is one date past another in PHP?

I have a start/end times for a calculation I'm trying to do and am having a problem seeing if the end time is before 12AM the day after the start time. Also, I need to calculate how many days past the start time it is.
What I have: Start Date, End Date
What I need:
- How many 'Midnights' is the End Date past the Start Date?
Has anyone done anything like this?
This uses PHP 5.3, if you have an earlier version you may need to use unix timestamps to figure out the difference. The number of midnights should be the number of days difference assuming both start and end times have the same time. So setting both to be midnight of their current day setTime(0,0), should make the calculation correct.
Using the DateTime objects.
$start = new DateTime('2011-03-07 12:23:45');
$end = new DateTime('2011-03-08 1:23:45');
$start->setTime(0,0);
$end->setTime(0,0);
$midnights = $start->diff($end)->days;
Without using the setTime() calls, this would result in 0, because there is less than 24 hours between start and end. With the setTime() this results in 1 because now the difference is exactly 24 hours.
The diff() function was introduced in 5.3 along with the DateInterval class. In 5.2 you can still use the DateTime class but will have to work out the total days using the Unix timestamp.
$midnights = ($end->format('U') - $start->format('U')) / 86400
You can wrap that in an abs() function to the order of start/end does not matter.
Note: These functions may need to be tested for cases that involve DST.
A comment in the php date documentation uses round after dividing by 86400 (number of seconds in a day), to counter any issues that could be involved with DST.
An alternative approach with DateTimes would be to create them in the UTC.
$utcTimezone = new DateTimeZone('UTC');
$start = new DateTime('2011-03-07 12:23:45', $utcTimezone);
$end = new DateTime('2011-03-08 1:23:45', $utcTimezone);

Resources