In my user edit view I have the following select: <%= f.time_zone_select :timezone %>
So that users can save their own timezone to tailor the dates on our app.
However we've noticed that during DST which is the case at the time of this posting the select is still showing (GMT+00:00) London instead of UTC+00:01 or BST.
Is this an option in Rails to show the correct timezone? Or is what is currently being show actually correct instead?
Related
I am re-writing this post for clarify and to show what I have so far and where exactly I am stuck.
So as you may know, the local_time gem only works when rendering the date and time attributes from the record itself, such as:
local_time(#events.start_time)
But I want to be able to render the datetime or time selects in the user's time zone, yet still save them to the database as UTC. I've been able to achieve this by hard coding it to Easter time by:
- Time.use_zone("Eastern Time (US & Canada)") do
%fieldset.border.border-dark.p-2
%legend Start Time
.input-group
= f.time_select :start_time, {ignore_date: true, minute_step: 15, prompt: true, ampm: true}, {class: "form-select form-select-lg border border-dark ms-2 me-2"}
.text-end.text-muted
= Time.zone
The above code will use Eastern Time (US & Canada) as the time zone the user sees, but at the same time is still saved to the database as UTC.
In order to make this more dynamic, I need to get the client's time zone, which according to this thread, you can obtain the client's IANA time zone by:
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
However, I need a way to post this to the events/new controller so that I can use it as a Ruby instance variable to change one line above:
- Time.use_zone(#my_zone) do
In my Events Controller I currently have:
def new
#my_zone = params[:my_zone]
#my_zone = ActiveSupport::TimeZone[TZInfo::Timezone.get('America/Vancouver').period_for_utc(Time.now.utc).utc_offset]
#event = Event.new
The second time that #my_zone is called, we are using an ActiveSupport that would convert the iANA value directly into the TZInfo value that the Time.use_zone uses, as discussed here.
Then once the controller has that value, it can plug it into Time.use_zone() method.
Getting Javascript to post to the controller is where I'm struggling. I attempted to use a similar AJAX call to this thread, such that at the bottom of my new.html.haml:
:javascript
$.post('/events/new', {my_zone: Intl.DateTimeFormat().resolvedOptions().timeZone}))
However, when I try to run that, the browser console says:
Syntax Error: Bare private name can only be used on the left hand side of an 'in' expression.
I can't figure out what's going on with that.
On the other hand, I'm actually on Rails 7 now, which I do know doesn't have UJS by default but rather uses Stimulus, Hotwire and Turbo. So, is there a way I could do the post to the controller via Stimulus, Hotwire and turbo?
Following is my query where I am fetching order wise payments on latest first basis.
I wish to fetch OrderPayment created_at here.
If I write <%= OrderPayment.last.created_at%> I get 2019-06-28 16:31:12 +053 which is a date, and I'm currently using <%= order_payment["created_at"]%> where I get 2019-06-28T11:01:12.686086 which is a string.
Why am I getting such a weird representation?
#order_payments = OrderPayment.select("order_id, json_agg(order_payments.* order by order_payments.created_at desc) as details").includes(order:).order("order_id desc").group(:order_id)
#iterating #orderpayments for listing
<% #order_payments.each do |order_detail| %>
<%details = order_detail.details%>
<%=order_payment["created_at"]%>
<%end%>
if i do <%= Time.at(DateTime.parse(order_payment["created_at"])).strftime("%d-%m-%y %I:%M %p")%> i get output like OrderPayment.last.created_at but i want to know whats the correct way to do it?
I think in your situation database and your rail environment time zones are different.
and its returning db value as it is with timezone
you should try Time.zone.parse(//your query//)
It will return time and date with current time zone.
I have a Rails app on PGSQL and there is a Date of Birth column (timestamp without time zone).
I use a "select" to get the employee data back and return that as JSON, but the DOB always comes back with a timezone, e.g. "dob":"1992-06-18T20:00:00-04:00".
I tried using to_char(emp.dob, 'YYYY-MM-DD HH24:MI:SS'), but no effect.
Any one has any ideas how to get the o/p to not contain TZ information?
Something like: 1992-06-18 20:00:00
Thanks
EDIT: Found the solution to a similar question here:
rails dates with json
Use the localization method and type the following:
<%= l emp.dob, :format => :long %>
There are several pre-defined options to show the text (:long, :short etc)
You can read more here.
I'm working with an app for a concert tour website, where all times (announcement times, on-sale start times, and event start times) are local to each particular venue's time zone. I take the user entered date/time where applicable and run a before_filter to set the appropriate time zone so that everything is stored in the database in UTC. For the 'new' form and for displaying the times in index and show actions, no problem at all. When the data is brought back out of the database and into a view, I use in_time_zone to adjust per the particular venue.
The only issue is on the edit form. The date/time select is showing the data in UTC. When I'm working on the site, I mentally adjust, but for others it's confusing. I'd like to do something along the lines of:
<%= f.datetime_select :start_datetime.in_time_zone(#event.time_zone) %>
Or, in the controller:
def edit
#performance = Performance.find(params[:id])
#event = #performance.event
#performance.start_datetime = #performance.start_datetime.in_time_zone(#event.time_zone)
end
Then simply, <%= f.datetime_select :start_datetime %>.
Unfortunately, I haven't found the right way to do this. Do you have any ideas worth giving a shot?
Thank you very much.
You may use default method of datetime_select, as following:
%br
= f.label :req_sess_start, "Session starts at"
= f.datetime_select(:req_sess_start, :start_year => 2010, :ampm => true, :default => 0.days.from_now.in_time_zone(#timezone))
Because of the default value shown, client will assume that times has to be entered in his/her local timezone, but...
this value will be actually in the timezone default to your application (as provided in application.rb, and the default is UTC).
So, you would require some server side coding to convert it to correct value.
I'm not sure if I understand what you want to do, but since you're storing the #event.time_zone, you could add
:default => start_time.in_time_zone(#event.time_zone)
to your datetime_select form field.
How about something like this:
# change PST to correct zone abbrev.
new_zone = ActiveSupport::TimeZone.new("PST")
#performance.start_datetime = #performance.start_datetime.in_time_zone(new_zone)
I just noticed this is an old post but:
If I were you, I would use a virtual attribute to represent the date time of the venue. For instance, you could add an attribute to performance called adjusted_start_time.
I have some strange behavior in my rails3 app.
When I pick a date with jquery UI datepicker. I see this in my log
Parameters: {"commit"=>"Save", "log"=> {"log_date"=>"04/20/2011"} ....blah...b}
AREL (1.0ms) INSERT INTO "logs" ("log_date") VALUES ('2011-04-19 22:00:00.000000')
I've left out the irrelevant information.
As you see Rails does not translate the date inputted correct. It changes (in this case) 20.apr to the 19.apr.
When I later call
<%= log.log_date.strftime('%d.%m.%y') %>
I get the corect date, but when I do this query
#log_times = Log.group(:log_date)
The logs are all one day earlier than they sould be.
In the console the log in this example looks like this
irb(main):017:0> Log.last
=> [#<Log id: 246, log_date: "2011-04-19 22:00:00">]
So, its save one date to early, but when I show it in the view it's correct.
Why?
Could I use a getter and setter to fix this?
Rails is built to handle timezones by default. Times stored in the database are stored in UTC and Rails is supposed to handle translating that into the configured local time automatically.
Do you have config.time_zone set in your application.rb file? Also, I'd recommend using DateTime rather than Time when possible.