I have a problem with passing date from Angular to Rails. In my project i use datetimepicker directive (https://github.com/dalelotts/angular-bootstrap-datetimepicker) which is using moment js. So when i pick the date it looks like "Wed Aug 05 2015 11:55:00 GMT+0300 (EEST)". Then this date is passing to rails api and rails converts it in "2015-08-05T08:55:00.000Z". So i simply need that the time received by rails was 11:55:00 not 08:55:00.
You do need to realize that Wed Aug 05 2015 11:55:00 GMT+0300 is equal to 2015-08-05T08:55:00.000Z and that the later date is a translation to UTC of the first one.
To change the timezone in which Active Record saves in the database, you can use
# application.rb
config config.time_zone = 'Eastern Time (US & Canada)'
config.active_record.default_timezone = :local
Warning! You really should think twice, even thrice, before saving times in the database in a non-UTC format.
Here's how you can find all available timezones
rake:time:all
More information: https://stackoverflow.com/a/32229086/4304188
Related
I am trying to set the ActiveRecord's time zone from UTC to current time zone. This is what I ended up
Application.rb
module application
class Application < Rails::Application
config.load_defaults 5.2
config.time_zone = 'Tokyo'.freeze
config.active_record.default_timezone = :local
end
end
I have turned off the server and restarted and made an object then when I checked the object's created_at it seems the ActiveRecords still records the data based on UTC time not Tokyo time.
Any solutions guys?
It always records the data of DateTime as UTC in Database and it will be converted according to config.time_zone if you call object.created_at
Let's say, It stored 2018-09-17 04:41:00 or Fri, 17 Sep 2018 04:41:00 UTC +00:00 in the database.
If your config the timezone as Tokyo then the result is Fri, 17 Sep 2018 13:41:00 JST +09:00
Additionally, you can use .in_time_zone method to convert the DateTime based on that zone. Here's .in_time_zone
I want to parse a string to a Time object in Rails. This string is in another timezone than the default app timezone. So now, when I parse the string I first have to store the current/default time zone, change the time zone, parse the string and change the time zone back to default. That's 4 lines of code to to one thing:
current_timezone = Time.zone
Time.zone = "Target time zone"
Time.zone.parse("Tue Nov 23 23:29:57 2010")
Time.zone = current_timezone
Is there a way to tell Rails inside the parse command which time zone to use?
Time.in_zone allows you to do this a little more idiomatically.
# Acting with the rails default timezone
Time.use_zone("America/New_York") do
# Acting with the target timezone
Time.zone.parse("Tue Nov 23 23:29:57 2010") #=> Tue, 23 Nov 2010 23:29:57 EST -05:00
end
# Acting with the rails default timezone
I'm having a frustrating issue that I can't seem to narrow down. I have searched many similar articles but they are not close enough to my issue to resolve. I am trying to pull a time from the database and display it in more than one time zone. My Rails app is using UTC as default. Here is what I'm doing:
On the create action I take the string of time which will be saved in the time column in my DB:
params[:schedule][:start] = "09:00"
Time.zone = "Central Time (US & Canada)"
#schedule.start = Time.zone.parse(params[:schedule][:start])
The above formats the time as it is supposed to:
2016-04-12 09:00:00 -0500
This is saved in the DB as:
2000-01-01 14:00:00
This has no time offset which is fine since I know it's in UTC. The problem happens when I go to display the time:
#schedule.start.in_time_zone("Central Time (US & Canada)")
This returns:
Sat, 01 Jan 2000 08:00:00 CST -06:00
Now, since this is a time column, I don't care about the date. I plan on formatting the value to only show the time. However, it is showing CST when it is currently CDT.
I can't figure out why this is happening. As I said I am not setting the Time Zone anywhere in my application.rb or anywhere else and I only set the Time zone on the create action which should be fine when moving to a new action.
Any help on clarifying this would be awesome!
This seems to be because when the time is stored it is stored with the date in the year 2000-01-01 which seems to be why it is using CST. How can I ignore the date when converting it to a particular timezone or will I need to change the column type to DateTime to get this to work properly?
It is showing CST simply because the time is read from the database including the stored date, i.e. it's read as 09:00 of Jan 1st 2000.
I guess you'd have to parse the time upon reading the attribute back. You can use a helper method in your model, for example:
# schedule model
def start_in_zone(zone)
self.start.strftime("%H:%M").in_time_zone(zone)
end
This will take only the hours and minutes part of the stored time and parse it in the given time zone with the date set to today. See this example:
"Sat, 01 Jan 2000 08:00:00".to_time.
strftime("%H:%M").
in_time_zone("Central Time (US & Canada)")
# => Tue, 12 Apr 2016 08:00:00 CDT -05:00
The fact that it matters whether it's CST or CDT means you do, on some level, care about the date. While I'm not familiar with the exact rules of Daylight Savings in that region, I do know that Jan 1 is the middle of winter and will definitely not be on Daylight Savings time.
Add the relevant date into your #schedule before putting it into a time zone, and it should fix the problem.
I am working on a rail4 app. Where I want to store dates in all mysql tables in UTC. However I store user's timezone in a specific table, called users. When user logs in, I get user's timezone form user table and save in session.
I am able to save date in all tables in UTC as default value of config.time_zone is UTC for activerecords and activemodels. But while displaying I want to show dates in user's timezone. As well as, when any user inputs a date/time in any html form, then I want to save it in the equivalent UTC format.
What is the best way to achieve this?
Rails, activerecord and MySQL will save all the timestamp fields in UTC. Without you having to do anything.
In your application.rb file where the configuration of the Application is done, you define the default time zone if you want the display of timestamps to take place on time zone different from UTC.
Hence
config.time_zone = 'Central Time (US & Canada)'
will display the timestamp fields (without you having to do anything special in other piece of code) using the Central Time.
When you want each of your users to have timestamps displayed in different time zone you can store the time zone in a column along side the user data. The column can be called time_zone and can contain the string of the user preferred time zone.
But, you have to tell the timestamp object to display itself to the specific timezone. This is done with the help of the method in_time_zone(timezone) that DateTime object responds to.
Example (when the default time zone is UTC):
1.9.3-p194 :004 > d = DateTime.new(2012, 9, 1, 6, 30, 0)
=> Sat, 01 Sep 2012 06:30:00 +0000
1.9.3-p194 :005 > d.in_time_zone("Central Time (US & Canada)")
=> Sat, 01 Sep 2012 01:30:00 CDT -05:00
Or you can change the time zone globally for the request at hand on a before or around filter. There is a documentation on internet if you do a google on that.
Read also this one: http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html
for various alternatives to approach the problem.
You could store the time in UTC, and store the timezone separately. Timezones are commonly stored as a UTC-offset in seconds (seconds are the SI unit of time).
Then you can display it like so:
utime = Time.now.utc.to_i # this value can be any format that Time.at can understand. In this example I'll use a unix timestamp in UTC. Chances are any time format you store in your DB will work.
=> 1375944780
time = Time.at(utime) # parses the time value (by default, the local timezone is set, e.g. UTC+08:00)
=> 2013-08-08 14:53:00 +0800
time_in_brisbane = time.in_time_zone(ActiveSupport::TimeZone[36000]) # sets the timezone, in this case to UTC+10:00 (see http://stackoverflow.com/a/942865/72176)
=> Thu, 08 Aug 2013 16:53:00 EST +10:00
time_brisbane.strftime("%d %b %Y, %l:%M %p %z") # format with strftime however you like!
=> "08 Aug 2013, 4:53 PM +1000"
i've got a Course model, which has a datetime attribute. If I look at it from the database i get one time, and if i look at it from the object i get a different date & time.
>> Course.last.attribute_for_inspect :datetime
=> "\"2012-01-04 01:00:00\""
>> Course.last.datetime
=> Tue, 03 Jan 2012 19:00:00 CST -06:00
Does anyone know why this value is different, and what I can do to fix it? The time from Course.last.datetime is correct, but my queries on the course table aren't working correctly due to the mix-up.
From the fine manual:
attribute_for_inspect(attr_name)
Returns an #inspect-like string for the value of the attribute attr_name.
[...]
Date and Time attributes are returned in the :db format.
So, when attribute_for_inspect is used for a datetime, it will return the string that the database uses for that value. Rails stores times in the database in UTC and any sensible database will use ISO 8601 for formatting timestamps on the way in and out.
2012-01-04 01:00:00 is the UTC timestamp in ISO 8601 format. When Rails returns a datetime, it converts it to an ActiveSupport::TimeWithZone instance and includes a timezone adjustment based on the timezone that you have configured in your application.rb. You're using the CST timezone and that's six hours behind UTC; subtracting six hours from 01:00 gives you 19:00 and you lose a day from crossing midnight. The human friendly format, Tue, 03 Jan 2012 19:00:00 CST -06:00, is just how ActiveSupport::TimeWithZone represents itself when inspected and the console uses x.inspect to display x.
As far as fixing your queries goes, just use t.utc before sending in a time t and you should be good.
Configuring your Rails App Timezone in application.rb
set config.active_record.default_timezone to :local as it is set to :utc by default in the application.rb
paste this code in your application.rb
config.active_record.default_timezone = :local #or :utc
config.time_zone = "Singapore" #your timezone