Convert date time in another timezone with offset value in ruby - ruby-on-rails

I am fairly new to ruby. I have a date value say "2014-12-15T19:56:59Z" and an offset value say "-06:00". How can I convert the given date time in the timezone given by offset value.

Using Time::parse and Time#localtime:
require 'time'
t = Time.parse('2014-12-15T19:56:59Z')
#=> 2014-12-15 19:56:59 UTC
t.localtime('-06:00')
#=> 2014-12-15 13:56:59 -0600

Related

Ruby - I need to convert string into a timestamp

I need to convert a string that represents a date to a timestamp object in Ruby.
For example:
date_string = "18-Feb-2016 09:01:04"
convert to a timestamp like so
2016-02-18 14:01:04
I need to save this to a mysql database were the column is type timestamp.
I have researched this for most of the day and can not find a solution. I know you can use Time.parse but that includes timezone and DateTime.parse().to_time includes the timezone. Since it has to be a timestamp i can not use strftime method.
I need the time to be included because it will be used for calculation purposes.
Any help would be greatly appreciated.
Thank you
TL;DR
datetime = DateTime.parse("18-Feb-2016 09:01:04").to_s(:db)
returns
"2016-02-18 09:01:04"
Here's a quick explanation...
1. Convert your string to a Date object with DateTime.parse
You can use the .parse method from the Date or DateTime class in order to parse a string. The parse method will return a Date object like this:
$ DateTime.parse("18-Feb-2016 09:01:04")
$ => #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
.parse is a method provided by Ruby.
2. Format the string with DateTime.parse.to_s
Ruby on Rails gives you access to the DateTime.to_formatted_s method to change the formatting of the Date object prior to storing it in your database.
To match the format that you specified:
$ datetime = DateTime.parse("18-Feb-2016 09:01:04").to_formatted_s
Note: to_s is aliased from to_formatted_s and to_formatted_s is a method provided by Rails, not Ruby.
Use to_datetime method in Rails.
"12-10-2015".to_datetime
=> Mon, 12 Oct 2015 10:36:00 +0000
http://apidock.com/rails/String/to_datetime
Edited to add precise answer.
You can use .to_time or .to_datetime, the .to_time returns the date and time with timezone but the .to_datetime returns full date with week name but it shows +0000 as timezone, you will see the difference in both the formats, see the following example.
# used .to_time
"18-Feb-2016 09:01:04".to_time
## Output
2016-02-18 09:01:04 +0530
# used .to_datetime
"18-Feb-2016 09:01:04".to_datetime
## Output
Thu, 18 Feb 2016 09:01:04 +0000
I've interpreted the question to be that you wish to convert the string "18-Feb-2016 09:01:04" to the string "2016-02-18 14:01:04" (generalized to arbitrary date-time strings, of course).
Let:
str = "18-Feb-2016 09:01:04"
What you want is done in two steps. The first is to convert this string to a DateTime object, that is, an instance of the class DateTime. The second step is to construct the desired string from the DateTime object.
One way to create the DateTime object is to use the method DateTime::parse:
require 'date'
DateTime.parse(str)
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
That works fine for the string format you gave, but can be problematic with other formats. For example:
DateTime.parse "4-5-16 09:01:04"
#=> #<DateTime: 2004-05-16T09:01:04+00:00 ((2453142j,32464s,0n),+0s,2299161j)>
As long as you know the format that will be used, it's generally better to use DateTime#strptime with the appropriate pattern comprised of format directives:
pattern = "%d-%m-%y %H:%M:%S"
DateTime.strptime("4-5-16 09:01:04", pattern)
#=> #<DateTime: 2016-05-04T09:01:04+00:00((2457513j,32464s,0n),+0s,2299161j)>
See DateTime#strftime for the format directives.
For the problem at hand:
dt = DateTime.strptime(str, "%d-%b-%Y %H:%M:%S")
#=> #<DateTime: 2016-02-18T09:01:04+00:00 ((2457437j,32464s,0n),+0s,2299161j)>
The second step is to construct the desired string with the above-referenced strftime method:
dt.strftime("%Y-%m-%d %H:%M:%S")
#=> "2016-02-18 09:01:04"

Timezone in numeric values?

From this API, it's asking for a timezone in a negative of positive value. What does this mean and how would I produce it in Rails 4?
tz Time zone as negative of positive values. Ex: 6.5
From looking through the Ruby Time API, I can't seem to make sense of where to look exactly. Any help would be awesome!
What you need is gmt_offset method, it returns difference between GMT and selected time zone (time object) in seconds. Just divide it by 3600 and there you go
Example
t = Time.gm(2000,1,1,20,15,1) #=> 2000-01-01 20:15:01 UTC
t.gmt_offset #=> 0
l = t.getlocal #=> 2000-01-01 14:15:01 -0600
l.gmt_offset #=> -21600

Changing ActiveRecord timezone for a session

I've been trying to change the timezone for a user session using the Time.zone method. I get the correct date and time when I do Time.zone.now but when I do a select query using ActiveRecord::Base.connection.select_all, the datetime columns in the result are always in UTC. What do I need to do so that all the select queries return data in the timezone that was set using the Time.zone method, without changing the views? Please help.
It's easiest to convert the Time to the local timezone with ruby.
Time.now.in_time_zone()
use it as such.
Time.now.in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00
You can give the function a timezone string, or an UTC offset
http://apidock.com/rails/Time/in_time_zone

Rails timezone differences between Time and DateTime

I have the timezone set.
config.time_zone = 'Mountain Time (US & Canada)'
Creating a Christmas event from the console...
c = Event.new(:title => "Christmas")
using Time:
c.start = Time.new(2012,12,25)
=> 2012-12-25 00:00:00 -0700 #has correct offset
c.end = Time.new(2012,12,25).end_of_day
=> 2012-12-25 23:59:59 -0700 #same deal
using DateTime:
c.start = DateTime.new(2012,12,25)
=> Tue, 25 Dec 2012 00:00:00 +0000 # no offset
c.end = DateTime.new(2012,12,25).end_of_day
=> Tue, 25 Dec 2012 23:59:59 +0000 # same
I've carelessly been using DateTime thinking that input was assumed to be in the config.time_zone but there's no conversion when this gets saved to the db. It's stored just the same as the return values (formatted for the db).
Using Time is really no big deal but do I need to manually offset anytime I'm using DateTime and want it to be in the correct zone?
Yep. Time.new will intepret parameters as local time in the absence of a specific timezone, and DateTime.new will intepret parameters as UTC in the absence of a specific timezone. As documented. You may want to replace Time.new with Time.local for clarity throughout your code.
What you can do is use DateTime's mixins for Time to invoke Time.local(2012,12,25).to_datetime. But if the year/month/day is coming from a user/browser, then perhaps you should get the user's/browser's timezone instead of using your server's.
If you need to create a migration to fix existing data in the DB, new_date_time = Time.local(old_date_time.year, old_date_time.mon, old_date_time.mday, old_date_time.hour, old_date_time.min, old_date_time.sec).to_datetime

Strange output after date conversion in Ruby on Rails

I am getting data from an API. The date attached to each object comes in this format:
Timestamp is the date and time of an
event in UTC time. This is expressed
as a specific number of milliseconds
since the standard base "epoch" of:
January 1, 1970, 00:00:00 GMT
I am trying to convert this into a different date format in Ruby.
CODE
objects.each do |obj|
p "object"
p obj.created
p Time.at(obj.created)
end
OUTPUT
"object"
1308886130000
43446-12-14 10:33:20 +1000
"object"
1308886104000
43446-12-14 03:20:00 +1000
"object"
1308801345000
43444-04-07 03:10:00 +1000
The years are obviously incorrect. What am I doing wrong?
I am using Ruby 1.9.2 and Rails 3.0.1
The Time.at function expects time since the epoch in seconds. You're giving it milliseconds, so the calculation is way off.
Divide that timestamp by 1000.

Resources