Rails Converting from Timestamp to Formatted Time with Timezone - ruby-on-rails

I'm building an application using Rails 4. I'm reading a Unix timestamp from JSON and attempting to display it as a properly formatted time according to my timezone. I'm able to read the display the timestamp, but it is displayed in UTC instead of EST.
This is what I have in my view
<%= Time.at(DateTime.strptime(#weather['sys']['sunrise'].to_s,'%s')).strftime("%l:%M %P") %>
I have four different timestamps where I am doing this same conversion.
Is there something I can tack on to this to display the proper time zone?

You can try this:
<%= Time.at(DateTime.strptime(#weather['sys']['sunrise'].to_s,'%s')).in_time_zone("E‌​astern Time (US & Canada)").strftime("%l:%M %P") %>

Try the following:
<% time_zone = "PDT" %>
<%= Time.at(DateTime.strptime(#weather['sys']['sunrise'].to_s,'%s')).in_time_zone(time_zone).strftime("%l:%M %P") %>
Refer to ActiveSupport::TimeWithZone#in_time_zone for more info.

Related

How can I display local time for data in Rails PostgreSQL correctly

And by correctly I mean if the event is Jan. 24 at 9 am Pacific time, I want to see Jan. 24 at 9 am, not Jan. 24 at 5 pm. I'm recording events with time and date in Rails in a PostgreSQL database. Timestamp with time zone (timestampz). All is well and good as long as I keep the database and app on my computer in "US/Pacific", but when I try to use it from the Heroku server which appears to be in UTC, the times are shifted by 8 hours. I now finally get that timestampz only means that this is the datetime in UTC, but the zone isn't stored. Do I need to store the time zone of the even in another field and do the math to see the time and date correctly?
Adding config.time_zone = "America/Los_Angeles" or to "UTC" to config/application.rb gives the same results as before, i.e., this setting made no difference. And this wouldn't be the final solution because the data won't always be in US/Pacific.
Viewing in a table:
<%= stat.statdate.localtime.strftime("%a %d %b %Y") %></td> <td class="text-start"> <%= stat.statdate.localtime.strftime("%_l:%M %P") %>
which results in Thu 27 Jan 2022 9:05 am on localhost, but Thu 27 Jan 2022 5:05 pm on Heroku
And charting the value over time, both over say a year and daily. For plotting variation over a recent day. Quite tortured trying to get both table and charting to work
<% timeZone = last_record.localtime.formatted_offset(false).slice!(0, 3).to_i %>
<% begin_1_day_ago = (last_record-timeZone.hour-1.day).beginning_of_day %>
<% begin_2_day_ago = (last_record-timeZone.hour-2.day).beginning_of_day %>
<% span21 = begin_2_day_ago..begin_1_day_ago %>
<%= line_chart BP.where(statdate: span21).pluck(:statdate, :value) %>
Where line_chart is using gem "chartkick" which uses High Charts. But this doesn't work when I move the app and database to Heroku
I ended up doing it "manually." Getting the time zone extracted from the data
<% last_record = BP.order('statdate asc').last.statdate %><br> # last data point.
<% last_record_zone = BP.order('statdate asc').last.statzone %> # time zone grabbed from statdate in timestampz (so zone was added)
<% last_record_zone_in_seconds = last_record_zone*3600 %>
# Getting midnight for the day of the last record in UTC but shifted by the local time of the last record
<% last_record_midnight = last_record + last_record_zone_in_seconds - (last_record.min*60) - (last_record.sec) %>
# Setting variables used to title the graphs and set beginning and end of daily graphs (set for one week, not shown)
# The first day is a special case and not shown here
#
# For graph title
<% last_record_1_day_ago = last_record-1.day %>
<% last_record_2_day_ago = last_record-2.day %>
# For daily graph data
<% span10 = last_record_midnight-1.day..last_record_midnight-0.day %>
Haven't checked for other than localhost and current server.

Having trouble getting Rails form builder to respect a given time zone for a time_select input

I cannot get my rails input helpers to respect a given time zone. I've looked at all the existing issues on this subject and code examples. It seems like this should be simple, but I'm getting nowhere. I'm hoping someone here can quickly see the error of my ways:
I have a Pro model in Rails with a time field called "work_start_time".
# schema.rb
create_table "pros", force: true do |t|
t.time "work_start_time"
I have a very basic form for my Pro that includes some additional lines to help me debug:
Work_start_time in UTC:<br>
<%= #pro.work_start_time %><br>
Work_start_time in PST:<br>
<% Time.use_zone("Pacific Time (US & Canada)") do %>
<%= #pro.work_start_time.in_time_zone %><br>
<% end %>
Form for work_start_time using PST:<br>
<%= form_for #pro do |f| %>
<% Time.use_zone("Pacific Time (US & Canada)") do %>
<%= f.time_select :work_start_time %><br>
<% end %>
<% end %>
Now I would expect the second and third times to be the same, since they're both supposed to be displayed in PST. But the time_select fails to respect it and shows the time in UTC instead:
What am I doing wrong?? I've tried using datetime_select. I've tried providing the work_start_time as a value: argument to the select method. No dice.
This is a simplified example - normally the time zone is actually a stored current_user.time_zone and we set Time.use_zone as an around_filter in the application controller. But those are disabled for this simplified experiment.
Ruby 2.2 (same issue with 2.0)
Rails 4.1.8 (same issue with 4.2.6 and Ruby 2.2)
I haven't tried using Time.use_zone do, but you might try adding to_s to the end of your #pro.work_start_time.in_time_zone call. Alternatively you could also use Moment.js and Moment time zone and render in javascript.
I found it easier to have the front end use moment to return utc times in forms, and to convert utc times to a default time zone.

Rails Form display datetime at local timezone

I'm new to rails (just finished the Rails Tutorial) and I'm building my first solo app. The user can create 'events' at specific times. Currently the user form is in UTC. How do I set it to their local time?
I don't just want to change it after they submit, because it would be confusing for the user. When you open a new form the default time is the current time (currently UTC). I want that to be the time of their local timezone.
<%= f.label :Date_Time %><br />
<%= f.datetime_select :date %>
thanks,
Loads of ways to do this!
I'd recommend you look at the question Stepan recommended first
Server Side
If you're wanting to keep your times consistent, you may wish to use the Rails in-built timezone option:
#config/application.rb
config.time_zone = 'Eastern Time (US & Canada)'
You can see more about ActiveSupport::Timezone here
Client-Side
Client-side, you'd have to think about what you want to achieve. If you have set timezones, you may benefit from creating a TimeZone repository (either ENV variables or datatable), and allow user to select from them, like this:
#app/views/form.html.erb
<%= form_tag %>
<%= select_tag :date, options_from_collection_for_select(#timezones, "id", "name") %>
<% end %>
Alternatively, you could pass the timezone through javascript: Getting the client's timezone in JavaScript
UX
The bottom line is you need to think about what you're trying to achieve. If your users need localized times, you should use a country-select system, where they will give you their country, and you can dedicate a timezone
Speaking from experience, it's much better to store all times equally (using UTC), and then process them using user's specifications

time conversion based on country_name/country_code

I've been trying to get my head around this problem but even after doing lot of research I wasn't able to get a proper solution.
I'm trying to build a flight booking system. I've have an api which returns me the arrival and departure time of flights in UTC time. Now I want to show the departure and arrival time of the flight in the local time of that country. Is there any faster way to do this. So far I have got this thing working which seems quite heavy. I'm writing some sample code below.
<% flights.each do |flight| %>
<% time_zone_name = TZInfo::Country.get(flight.departure_country_code).zone_names.first %>
<% time_zone = TZInfo::Timezone.get('time_zone_name') %>
departure_time : <%= time_zone.utc_to_local(flight.departure_time) %>
<% end %>
This might help. You can get the user's time zone and Time#localtime will give you the time in the current time zone of the machine running the code
> time = Time.now.utc
=> 2013-11-11 14:42:49 UTC
> time.localtime
=> 2013-11-11 20:12:49 +0530

Changing the timestamp of magic columns (Rails)

I want to change the default timestamp of the magic columns of rails (created_at, modified_at) instead of 2010-09-03 14:52:46 UTC I'd like to change it to September 10, 2010 at 02:52 PM. or at least parse that way.
Now, i know that i can do this right in the view, by manipulating the variable, but isnt there a more "railish way" where i can just do this in the model, and then call it as a method?
class YourModel < ActiveRecord::Base
def my_formated_date_time
created_at.strftime("%B %d, %Y at %I:%M %p")
end
end
Or you can use the localization format. Add this to your config/locale/your_locale.yml. IMHO: This would be the most railish way.
your_locale:
time:
formats:
default: "%B %d, %Y at %I:%M %p"
Then in your view do this
<%=l #your_model.created_at %>
<!-- short for: -->
<%= I18n.localize #your_model.created_at %>
Modifying the created_at date is fine, it will stay as you set it, and you can over-ride it even at the start, but updated_at or modified_at might prove tricky. Every time you save your model this is changed. If you don't want this behavior, convention suggests switching to a different name.
If you want to adjust how dates are displayed, you need to configure the default formatter.

Resources