Get Time from Datetime Variable in Ruby

Get time from DateTime Variable in Ruby

Try DateTime#strftime.

DateTime.now.strftime("%H:%M")
# => "12:17"

Rails: Get the time from a datetime

strftime will do it.

t = Time.now
t.strftime("%I:%M%p")

All other attributes here:

http://www.wetware.co.nz/blog/2009/07/rails-date-formats-strftime/

Ruby parse DateTime with variable

In your third call, you use the literal string "datetime" rather than the value of your datetime variable. You can use string interpolation to use the variable's value:

DateTime.parse("#{datetime} 9pm")

In this case, the "9pm" is ignored since it doesn't make sense added to the end of an existing date but this is why the initial attempt wasn't working. Interpolation is generally a solution for using a variable's value rather than its name.

If your goal is to change the time of an existing date, use the change method:

datetime.change(hour:21)

Convert to/from DateTime and Time in Ruby

You'll need two slightly different conversions.

To convert from Time to DateTime you can amend the Time class as follows:

require 'date'
class Time
def to_datetime
# Convert seconds + microseconds into a fractional number of seconds
seconds = sec + Rational(usec, 10**6)

# Convert a UTC offset measured in minutes to one measured in a
# fraction of a day.
offset = Rational(utc_offset, 60 * 60 * 24)
DateTime.new(year, month, day, hour, min, seconds, offset)
end
end

Similar adjustments to Date will let you convert DateTime to Time .

class Date
def to_gm_time
to_time(new_offset, :gm)
end

def to_local_time
to_time(new_offset(DateTime.now.offset-offset), :local)
end

private
def to_time(dest, method)
#Convert a fraction of a day to a number of microseconds
usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i
Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min,
dest.sec, usec)
end
end

Note that you have to choose between local time and GM/UTC time.

Both the above code snippets are taken from O'Reilly's Ruby Cookbook. Their code reuse policy permits this.

Where Ruby get date, time from?

https://ruby-doc.org/core-2.2.0/Time.html#method-c-new

Unless given a time during initialization of a Time instance, Ruby uses the type from the system it is running on.

If you want the current time on a user's device in a Rails project, you'll need to capture it with Javascript and pass it back to your Rails application.

How to check if variable is Date or Time or DateTime in Ruby?

Another option:

def is_datetime(d)
d.methods.include? :strftime
end

Or alternatively:

if d.respond_to?(:strftime)
# d is a Date or DateTime object
end

How do I get the current Date/time in DD/MM/YYYY HH:MM format?

The formatting can be done like this (I assumed you meant HH:MM instead of HH:SS, but it's easy to change):

Time.now.strftime("%d/%m/%Y %H:%M")
#=> "14/09/2011 14:09"

Updated for the shifting:

d = DateTime.now
d.strftime("%d/%m/%Y %H:%M")
#=> "11/06/2017 18:11"
d.next_month.strftime("%d/%m/%Y %H:%M")
#=> "11/07/2017 18:11"

You need to require 'date' for this btw.

Ruby on Rails parsing time from datetime, not as string

Is there a specific reason you want a Time object?

Just so we're clear, the Time class in Ruby isn't just "DateTime without the date." As "What's the difference between DateTime and Time in Ruby?" explains, "Time is a wrapper around POSIX-standard time_t, or seconds since January 1, 1970." Like DateTime, a Time object still has year, month, and day, so you don't really gain anything by using Time instead. There's not really a way to represent just hour and minute using either Time or DateTime.

The best you could do with Time, I think, would be this:

date_time = DateTime.now
seconds = date_time.hour * 60 * 60 + date_time.minute * 60

time = Time.at(seconds)
# => 1970-01-01 09:58

...but then you still have to call time.hour and time.min to get at the hour and minute.

If you're just looking for a lightweight data structure to represent an hour and minute pair, though, you might as well just roll your own:

HourAndMinute = Struct.new(:hour, :minute) do
def self.from_datetime(date_time)
new(date_time.hour, date_time.minute)
end
end

hm = HourAndMinute.from_datetime(DateTime.now)
# => #<struct HourAndMinute hour=15, minute=58>
hm.to_h
# => { :hour => 15, :minute => 58 }
hm.to_a
# => [ 15, 58 ]

Edit re:

I have a variable that stores an appointment -- this variable is a DateTime object. I have two table fields that store the start and end times of a location. I need to check if the time scheduled for that appointment lies between the start and end times.

Ah, it seems you had a bit of a XY problem. This makes a lot more sense now.

Absent any more information, I'm going to assume your "fields that store the start and end times of a location" are MySQL TIME columns called start_time and end_time. Given MySQL TIME columns, Rails casts the values to Time objects with the date component set to 1/1/2000. So if your database has the values start_time = '09:00' and end_time = '17:00', Rails will give you Time objects like this:

start_time = Time.new(2000, 1, 1, 9, 0) # => 2000-01-01 09:00:00 ...
end_time = Time.new(2000, 1, 1, 17, 0) # => 2000-01-01 17:00:00 ...

Now you say your appointment time is a DateTime, so let's call it appointment_datetime and suppose it's at 10:30am tomorrow:

appointment_datetime = DateTime.new(2014, 11, 18, 10, 30) # => 2014-11-18 10:30:00 ...

So now to rephrase your question: How do we tell if the time part of appointment_datetime is between the time part of start_time and end_time. The answer is, we need to either change the date part of start_time and end_time to match the date part of appointment_datetime, or the other way around. Since it's easier to change one thing than two, let's do it the other way around and change appointment_datetime to match start_time and end_time (and, since those two are Time objects, we'll create a Time object):

appointment_time = DateTime.new(2000, 1, 1, appointment_datetime.hour, appointment_datetime.minute)
# => 2000-01-01 10:30:00 ...

Now we can compare them directly:

if appointment_time >= start_time && appointment_time <= end_time
puts "Appointment time is good!"
end

# Or, more succinctly:
if (start_time..end_time).cover?(appointment_time)
puts "Appointment time is good!"
end

You would, of course, want to wrap all of this up in a method, perhaps in your Location model (which, again, I'm assuming has start_time and end_time attributes):

class Location < ActiveRecord::Base
# ...

def appointment_time_good?(appointment_datetime)
appointment_time = DateTime.new(2000, 1, 1,
appointment_datetime.hour, appointment_datetime.minute)

(start_time..end_time).cover?(appointment_time)
end
end

location = Location.find(12) # => #<Location id: 12, ...>
location.appointment_time_good?(appointment_time) # => true

I hope that's helpful!

P.S. Another way to implement this would be to ditch the date/time objects entirely and do a straight numeric comparison:

def appointment_time_good?(appointment_datetime)
appointment_hour_min = [ appointment_datetime.hour, appointment_datetime.minute ]

appointment_hour_min >= [ start_time.hour, start_time.min ]
&& appointment_hour_min <= [ end_time.hour, end_time.min ]
end


Related Topics



Leave a reply



Submit