Datetimes are being stored in MySQL as UTC.
In my app I've set: config.time_zone = 'UTC'
In my application_controller I set the users selected timezone:
around_filter :user_time_zone, :if => :current_user
def user_time_zone(&block)
Time.use_zone(current_user.time_zone, &block)
end
I can confirm this works by <%= Time.zone.now%> as it returns the user's set timezone
I then do a select query to grab the datetime field, and present it to the user as part of an array.
In my view, I have:
<%= Time.zone.parse(item[1]).strftime("%m/%d/%Y %I:%M %p") %>
which just outputs the datetime as-is (UTC), not in the user's specific time zone.
What do I need to change in order for the date and time to display correctly in the user's desired timezone?
Thanks for your time and assistance.
Edit:
Per Benjamin's suggestions, I had to modify it slightly to get it to work (was getting the same error) - Time.strptime(item[1], '%Y-%m-%d %H:%M:%S').in_time_zone(Time.zone) but 2 issues still remain.
1 - the original datetime is: 2013-07-25 22:27:50, but what is displayed is: 2013-07-25 16:27:50 -1000 my user timezone is Hawaii at -10 from UTC, but this only shows a 6 hr difference?
2 - How do I get this in a format that is easily readable by users (07/25/2013 12:27 PM)? Thanks again
Solved:
Thanks to Benjamin. I forgot to mention that I'm (stuck) using 1.8.7, so I had to work through a few minor differences between 1.8.7 and 1.9.3, but got it working with:
<%= DateTime.strptime(item[1], '%Y-%m-%d %H:%M:%S').in_time_zone(Time.zone).to_formatted_s(:long)%>
Updated: Got it into the format I wanted (06/20/2013 01:00 AM) using:
DateTime.strptime(item[1], '%Y-%m-%d %H:%M ').in_time_zone(Time.zone).strftime("%m/%d/%Y %I:%M %p")
Try this
Time.strptime(item[1], '%Y-%m-%dT%H:%M:%S%z').in_time_zone(Time.zone)
Answer to the bonus questions
Check the time zone of your db server and double check your rails data (default config / user TZ)
use to_formatted_s http://api.rubyonrails.org/classes/Time.html#method-i-to_formatted_s
Related
I know there is a method to determine if a certain time is on Daylight Savings Time (Time.now.dst?) but is there a method to give us the next date when Daylight Savings will change?
For example, Google returns Sunday, November 1 as the next Daylight Savings Time change in 2015.
Since these are dates that are based on other values, like the timezone you are working with, it requires a module like ActiveSupport/TZInfo.
require 'active_support/core_ext/time/zones'
tz = TZInfo::Timezone.get('US/Pacific')
# pick a timezone to work with
tz.current_period #returns an object of the current period
=> #<TZInfo::TimezonePeriod: #<TZInfo::TimezoneTransitionDefinition:
#<TZInfo::TimeOrDateTime: 1425808800>,#<TZInfo::TimezoneOffset: -28800,3600,PDT>>,
#<TZInfo::TimezoneTransitionDefinition: #<TZInfo::TimeOrDateTime: 1446368400>,
#<TZInfo::TimezoneOffset: -28800,0,PST>>>
tz.current_period.local_start.to_s
# => "2015-03-08T03:00:00+00:00"
tz.current_period.local_end.to_s
# => "2015-11-01T02:00:00+00:00"
One thing I haven't figured out is that since regular Ruby Core does this:
Time.now.dst?
# => true
Where is it getting this info? I found the TZInfo classes through ActiveSupport. Is Ruby just getting a boolean value from the OS?
How about this extension of the Time class:
class Time
class << self
def next_dst_change
startdate = Date.today
enddate = Date.today.end_of_year
match = Date.today.to_time.dst? ? false : true
startdate.upto(enddate).find { |date| date.to_time if date.to_time.dst? == match }
end
end
end
Now you can do Time.next_dst_change. You can apply this on your own timezone only but it solves your problem.
In my Rails App (Rails 2.3.14 and Ruby 1.8.7) I am trying to convert a datetime string into a different format to perform a search on my MySQL database but I am getting an invalid date error and I can't seem to figure out why, I've read a good few similar questions but I still can't seem to resolve the issue.
# check if filter contains a time stamp
if params[:sSearch].include?('/') and params[:sSearch].include?(':')
datetime = DateTime.strptime(params[:sSearch], "%Y-%m-%d %H:%M")
params[:sSearch] = datetime
end
Example scenario
04/11/13 16:14
should convert to
2013-11-04 16:14
I thought it might have been to do with the fact that the seconds aren't included in the front-end representation of the string as the precise datetime in the database table is 2013-11-04 16:14:52 so I included the seconds now but still getting the same error and I don't think that should matter since I am using the LIKE operand with wildcards on either side of the search term, so even without the seconds it should work.
You should use slashes in the format and replace %Y (four digit year) with %y (abbreviated two digit year) to get the desired result. Besides, the order of the date fields is reversed. The correct format would be:
"%d/%m/%y %H:%M"
I think you confused the purpose of strptime and strftime. Whereas the p in strptime stands for "parse" (make DateTime from String), the f in strftime stands for "format" (the other direction).
require 'date'
DateTime.strptime("04/11/13 16:14", "%Y-%m-%d %H:%M")
# ArgumentError: invalid date
DateTime.strptime("04/11/13 16:14", "%d/%m/%Y %H:%M")
#=> #<DateTime: 0013-11-04T16:14:00+00:00 ((1722836j,58440s,0n),+0s,2299161j)>
# Wrong! You do not want the year 0013, but 2013
DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")
#=> #<DateTime: 2004-11-13T16:14:00+00:00 ((2453323j,58440s,0n),+0s,2299161j)>
# Correct
you can later convert it to the desired format with DateTime#strftime like this:
# parse the user input to a DateTime object
datetime = DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")
# reformat it
params[:sSearch] = datetime.strftime("%Y-%m-%d %H:%M")
strptime converts the given string into a datetime object using the format given.
DateTime.strptime("04/11/13 16:14", "%m/%d/%y %H:%M").strftime("%Y-%m-%d %H:%M")
There is a problem with your template, try: DateTime.strptime("04/11/13 16:14", "%d/%m/%y %H:%M")
I am tracking user activity:
def track
UserActivityTracker.new(date: Date.today.to_s).track
end
#application.rb
config.time_zone = 'UTC'
How to be sure that days are tracked in the Pacific Time (US & Canada)
time zone.
I don't want to change time zone in application.rb
Rails will store your data in the db using UTC (which is a good thing)
i don't think changing config.time_zone on an existing app is a good idea, the UTC default is probably best
When rails pulls data from the db using ActiveRecord, it will convert datetimes based on the Time.zone settings for that request
Date.today
# => server time, rails does not convert this (utc on a typical production server, probably local on dev machine)
Time.zone.now.to_date
# => rails time, based on current Time.zone settings
You can set the current users time zone in a before_filter on ApplicationController, then when you display datetimes use the I18n helpers
I18n.localize(user_activity_tracker.date, format: :short)
# => renders the date based on config/locals/en.yml datetime:short, add your own if you wish
# => it automatically offsets from UTC (database) to the current Time.zone set on the rails request
If you need to display a time that is not the same as the current Time.zone request setting, use Time.use_zone
# Logged on user is PST timezone, but we show local time for an event in Central
# Time.zone # => PST
<% Time.use_zone('Central Time (US & Canada)') do %>
<%= I18n.l(event.start_at, format: :time_only_with_zone) %>
<% end %>
when saving data, don't bother doing a conversion, let rails save it as UTC, you can display the value in any timezone you wish using the helpers
see also:
http://railscasts.com/episodes/106-time-zones-revised
http://guides.rubyonrails.org/i18n.html
http://api.rubyonrails.org/classes/Time.html#method-c-use_zone
http://www.ruby-doc.org/core-2.0/Time.html#method-i-strftime
Replace config.time_zone this way :
config.time_zone = 'PST'
If you don't want to change all the dates, you can use Time.zone_offset
good_date = bad_date + Time.zone_offset('PST')
You can add the offset in the initialize or in a before_xxx callback.
User model has time_zone, which stores say "Pacific Time (US & Canada)".
Scenario:
1. Current_user lives in Japan timezone
2. Current_user is viewing profile of John who lives in "Pacific Time (US & Canada)"
3. On John's profile, I need to show local time at "Pacific Time (US & Canada)" as 10:01 am
What I did?
ActiveSupport::TimeZone.new(#user.time_zone).now returns something like 2011-09-21 10:01:56 UTC
Questions:
1. How to do I convert this to 10:01 am?
2. Why is it UTC?
Please help
To set TimeZone, you need to use
Time.zone= #user.time_zone
You may want to set this in :before_filter in application.rb
OTOH, you can use use_zone method with a block
Time.use_zone(#user.time_zone) do
#.... This code will run as if you were in #user.time_zone
end
You can use this
Time.zone = 'Pacific Time (US & Canada)'
to get the local time
Time.zone.now #=> Wed, 21 Sep 2011 02:25:08 PDT -07:00
to get 10:00 am/pm
Time.zone.now.strftime("%I:%M %p") #=> 02:25 AM
Try smth like this, in you User controller:
def show
#user = find(params[:id])
Time.zone = #user.time_zone
end
To change format:
Time.now.strftime("at %I:%M%p")
The ideal way to handle with time is save the data in UTC format in the back end, this will make the conversion process simple.
As Chandra Patni mentioned above, you may use those methods for conversion.
To display the time object in formatted string you may use rails strftime method, http://apidock.com/rails/ActiveSupport/TimeWithZone/strftime
I have a problem when showing a datetime object from the database. The time is correctly set in when storing the object, but when it is fetched from db and shown to user it is shown in UTC
environment.rb
config.time_zone = 'Copenhagen'
This is what is saved using Time.now or Time.zone.now
2010-07-08 13:59:50 +0200
This is what is shown to the user when using the html helper <%=h ff.date_registered %>
2010-07-08 11:59:50 UTC
Try Time.current. Time.now is returned in UTC -5 always. ActiveRecord instructs Time.current based on your config.time_zone. See this github issue for more information, https://github.com/rails/rails/issues/3128#issuecomment-2195751