Add 30 seonds to minutes in time class in Ruby - ruby-on-rails

I used the following format in Ruby which is working fine.
Time.new.strftime("%a %d %b, %Y %H:%M") # output "Thu 05 Aug, 2021 12:29"
But I need to add additional 30 seconds to the current time. I tried with active support, but unable to figure out how to do it. Any help would be appreciated.

Given an instance of time: (Rails flavored)
t = Time.current
#=> Thu, 05 Aug 2021 10:55:12 CEST +02:00
There are several ways to add 30 seconds to it, e.g.
Ruby's Time#+ with an integer:
t + 30
#=> Thu, 05 Aug 2021 10:55:42 CEST +02:00
Ruby's Time#+ with a Rails' ActiveSupport::Duration instance from Numeric#seconds:
t + 30.seconds
#=> Thu, 05 Aug 2021 10:55:42 CEST +02:00
Rails' Time#advance which takes a hash:
t.advance(seconds: 30)
#=> Thu, 05 Aug 2021 10:55:42 CEST +02:00

%S - Second of the minute (00..59)
Time.new.strftime("%a %d %b, %Y %H:%M:%S")
# "Thu 05 Aug, 2021 10:18:50"
+ 30 seconds
(Time.new + 30.seconds).strftime("%a %d %b, %Y %H:%M:%S")
Or 0.5 min (30 sec)
(Time.new + 0.5.minutes).strftime("%a %d %b, %Y %H:%M:%S")

There is a method since for time object which can be used for this purpose
Time.new.since(30.seconds).strftime("%a %d %b, %Y %H:%M:%S")

Related

Rails/ruby transform string to UTC

I'm currently doing:
DateTime::strptime('12/11/17', "%d/%m/%Y") => Fri, 12 Nov 0017 00:00:00 +0000
But I want Mon, 11 Dec 2017 00:00:00 UTC +00:00
Thanks in advance
The following snipped should do what you are looking for (using ruby 2.3):
DateTime::strptime('12/11/17', "%m/%d/%y").strftime("%a, %d %b %Y %H:%M:%S UTC %Z")
#=> "Mon, 11 Dec 2017 00:00:00 UTC +00:00"

Rails 5: Not converting DateTime object timezone correctly

This issue has been eating away at me for a while.
I take a date time string:
[14] pry(#<EventsController>)> params[:event][:ended_at]
=> "05/31/2017 2:00 PM"
I convert it to a DateTime object:
pry(#<EventsController>)> to_datetime = DateTime.strptime(params[:event][:ended_at], "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000
If I run the in_time_zone method on the to_datetime object it outputs the wrong time for pacific timezone:
[16] pry(#<EventsController>)> to_datetime.in_time_zone("Pacific Time (US & Canada)")
=> Wed, 31 May 2017 07:00:00 PDT -07:00
It should read "2:00PM" the same as how it is entered.
If I go to google and check to see if "14:00:00 +0000" is the correct entry for PDT time it verifies as correct:
http://imgur.com/a/ZJ80F
Any clues about why it's not converting correctly?
the error comes that the ended_at is been assumed by the system configuration that in this case is '+0000' you need to include the original timezone the ended_at is.
irb(main):001:0> date = "05/31/2017 2:00 PM"
=> "05/31/2017 2:00 PM"
irb(main):002:0> to_datetime = DateTime.strptime(date, "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000
Note that this one has already set as UTC since was assumed by the system the timezone
irb(main):001:0> date = "05/31/2017 2:00 PM -0700"
=> "05/31/2017 2:00 PM -0700"
irb(main):002:0> to_datetime = DateTime.strptime(date, "%m/%d/%Y %H:%M %p %z")
=> Wed, 31 May 2017 14:00:00 -0700
irb(main):003:0> new_to_datetime = to_datetime.utc
=> Wed, 31 May 2017 21:00:00 +0000
irb(main):004:0> new_to_datetime.in_time_zone("Pacific Time (US & Canada)")
=> Wed, 31 May 2017 14:00:00 PDT -07:00
Update
#antonio's comment mention he was 1 hour off
irb(main):046:0> time = DateTime.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z").class
=> DateTime
irb(main):047:0> time = DateTime.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z")
=> Wed, 31 May 2017 14:00:00 -0800
irb(main):048:0> time.utc.class
=> Time
As you can see these are different classes and that's sign of problems what you can do is use Time instead of DateTime
irb(main):049:0> time = Time.strptime(date + " Pacific Time (US & Canada)", "%m/%d/%Y %H:%M %p %Z")
=> 2017-05-31 14:00:00 -0700
irb(main):050:0> time.class
=> Time
If we look at your first attempt:
pry(#<EventsController>)> to_datetime = DateTime.strptime(params[:event][:ended_at], "%m/%d/%Y %H:%M %p")
=> Wed, 31 May 2017 14:00:00 +0000
we see that "05/31/2017 2:00 PM" is being parsed correctly in UTC, hence the +0000 offset.
Then, if you convert that UTC time to PDT, you apply a -7 hour adjustment:
=> Wed, 31 May 2017 07:00:00 PDT -07:00
# -------------------------------^^^^^^
and the 14:00:00 becomes 07:00:00 because 14 - 7 == 7.
If you want to_datetime to be in PDT then it would be easiest to start that way by telling DateTime.strptime that the timestamp string is PDT:
no_tz = '05/31/2017 2:00 PM'
to_datetime = DateTime.strptime("#{no_tz} PDT", '%m/%d/%Y %H:%M %p %z')
# ------------------------------^^^^^^^^^^^^^^^---------------------^^
Then you'll get the 14:00:00 PDT you're looking for:
> to_datetime.iso8601
=> "2017-05-31T14:00:00-07:00"
# -------------^^------^^^^^^

1.year.from_now is also one day ahead

Today's date is 2016-09-19. I add one year to it, and I expect the result to be 2017-09-19. Instead, I get 2017-09-20. One year plus one day ahead. Is this behavior as intended?
$ rails c
2.3.1 :001 > Time.now.to_date.iso8601
=> "2016-09-19"
2.3.1 :002 > 1.year.from_now.to_date.iso8601
=> "2017-09-20"
If you want get ecactly date with time zones, you can use Time.current
1.year.from_now
#=> Wed, 20 Sep 2017 05:38:50 UTC +00:00
Time.current
#=> Tue, 20 Sep 2016 05:39:08 UTC +00:00
since or its alias from_now calculate the offset based on Time.current which is equivalent to Time.zone.now – both return a ActiveSupport::TimeWithZone instance:
Time.current #=> Mon, 19 Sep 2016 19:56:34 SST -11:00
Time.zone.now #=> Mon, 19 Sep 2016 19:56:35 SST -11:00
Time.now on the other hand returns an ordinary Time instance in your system's timezone, which can differ from the Rails timezone:
Time.now #=> 2016-09-20 08:56:36 +0200
To avoid confusion, you should always use Time.current / Time.zone.now when working within Rails. You can however pass another "base time" to since:
1.year.since(Time.now) #=> 2017-09-20 08:56:37 +0200
Or, because you are working with dates:
1.year.since(Date.today) #=> Wed, 20 Sep 2017
There is also Date.current which is equivalent to Time.zone.today:
1.year.since(Date.current) #=> Wed, 19 Sep 2017
Turns out it's a timezone thing. I'm UTC -7 hours.
Time.now returns the time in my timezone.
1.year.from_now returns the time in UTC+0, 7 hours ahead of where I am.
It's 10pm here, so it's the next day at UTC+0.

Convert facebook date into timestamp format

I get birthday from facebook in this format
"12/09/1993"
But in timestamp format is yyyy/mm/dd How I convert facebook data into this with min lines of code?
Here you can see different sort of combinations:
require 'date'
date = "01/07/2016 09:17AM"
DateTime.parse(date).strftime("%A, %b %d")
#=> Friday, Jul 01
DateTime.parse(date).strftime("%m/%d/%Y")
#=> 07/01/2016
DateTime.parse(date).strftime("%m-%e-%y %H:%M")
#=> 07- 1-16 09:17
DateTime.parse(date).strftime("%b %e")
#=> Jul 1
DateTime.parse(date).strftime("%l:%M %p")
#=> 9:17 AM
DateTime.parse(date).strftime("%B %Y")
#=> July 2016
DateTime.parse(date).strftime("%b %d, %Y")
#=> Jul 01, 2016
DateTime.parse(date).strftime("%a, %e %b %Y %H:%M:%S %z")
#=> Fri, 1 Jul 2016 09:17:00 +0200
DateTime.parse(date).strftime("%Y-%m-%dT%l:%M:%S%z")
#=> 2016-07-01T 9:17:00+0200
DateTime.parse(date).strftime("%I:%M:%S %p")
#=> 09:17:00 AM
DateTime.parse(date).strftime("%H:%M:%S")
#=> 09:17:00
DateTime.parse(date).strftime("%e %b %Y %H:%M:%S%p")
#=> 1 Jul 2016 09:17:00AM
DateTime.parse(date).strftime("%d.%m.%y")
#=> 01.07.16
DateTime.parse(date).strftime("%A, %d %b %Y %l:%M %p")
#=> Friday, 01 Jul 2016 9:17 AM
Even more combinations here: http://www.foragoodstrftime.com/
Time.parse("12/09/1993").strftime("%Y/%m/%d")
#=> "1993/09/12"
Use strftime
date = "12/09/1993".to_date # => Sun, 12 Sep 1993
date.strftime("%Y/%m/%d") # => "1993/09/12"

Include 'UTC` in datetime

One of my assertions is failing because of this slight niggle:
its(:register_token_created_at){ should eq DateTime.now.utc }
results in:
expected: Fri, 28 Mar 2014 00:06:33 +0000
got: Fri, 28 Mar 2014 00:06:33 UTC +00:00
So how should I change DateTime.now.utc for it to pass?
I'm assuming that you have your test environment with the following configuration:
yourapp/config/environments/test.rb
#config.time_zone = "whatever"
config.active_record.default_timezone = :utc
Then, you can replace:
DateTime.now.utc #Fri, 28 Mar 2014 00:54:28 +0000
With:
Time.zone.now #Fri, 28 Mar 2014 00:54:51 UTC +00:00
That works for me...
Another (ugly) solution can be:
DateTime.now.utc.strftime("%a, %m %b %Y %H:%M:%S UTC %:z") #"Fri, 03 Mar 2014 00:55:46 UTC +00:00"
And then, you can compare as strings

Resources