0

So my rails application supports different time zones and sets the time zone at each request like so:

def set_current_time_zone
  Time.zone = current_user.time_zone
end

All of my formatting and reports site wide work except for a jQuery date time selector.

The form submits a start time in the format of 04/20/2018 5:23 AM. When I parse the time with the code below I get the following output.

# this is the value of params[:job][:start] 04/20/2018 5:23 AM

job.start = DateTime.strptime(params[:job][:start],"%m/%d/%Y %H:%M %p")

#printing job.start outputs this: 2018-04-20 00:23:00 -0500

As you'll notice the time zone has been applied to the time and is now the wrong time. How do I correct this?

Thanks in advance.

Cannon Moyer
  • 3,014
  • 3
  • 31
  • 75
  • After `Time.zone = "Hong Kong"` I tested your exact code `DateTime.strptime("04/20/2018 5:23 AM","%m/%d/%Y %H:%M %p")` getting: `2018-04-20T05:23:00+00:00`. The output does not change after changing the time zone. – iGian May 01 '18 at 19:15
  • I just tested what you explained and if I do not retrieve the value from the database and rather output the value of `DateTime.strptime("04/20/2018 5:23 AM","%m/%d/%Y %H:%M %p")` I get the desired result. However, I still am unable to save/retrieve the correct time from the database. @iGian – Cannon Moyer May 01 '18 at 19:29
  • I'm not sure I understand the actual problem. jQuery time should be the time on the user's browser right? Once it hits your server as a param, can you convert it to UTC and do what you need on server side? Also possible dupe of https://stackoverflow.com/questions/9739082/rails-jquery-datepicker-timezones – lacostenycoder May 01 '18 at 19:39
  • Yea essentially, you can ignore jQuery for the scope of this question. I mentioned it mainly to provide context. Essentially my issue is that I submit a date time to the server, parse that date time, print the parsed date time (still correct at this point), but when I actually save it into the database the time is changed. When I remove Time.zone = "Some Time Zone" the issue goes away. @lacostenycoder – Cannon Moyer May 01 '18 at 19:42
  • What class is `job` an instance of? Is it running in the web server, multi-threaded? could it be running in a Sidekiq worker or other process? – lacostenycoder May 01 '18 at 20:18
  • @CannonMoyer, I did some test. I see that Rails saves to database at the server time, so if `Time.zone` is not the same as the server, it does the calculation before save. It seems the query itself. Try from rails console, you see the time in the query already changed. Maybe you need a before_save callback to adjust the data? – iGian May 02 '18 at 05:38

2 Answers2

0

Keep in mind DateTime.strptime('04/20/2018 5:23 AM',"%m/%d/%Y %H:%M %p") will return the value in UTC =>Fri, 20 Apr 2018 05:23:00 +0000

However if you store this value say to a database field, in an active record object, it will output the timezone value to whatever value you've set to Time.zone

This may not be a complete answer but could lead you in the right direction.

lacostenycoder
  • 10,623
  • 4
  • 31
  • 48
0

Add some more details to my last comment above.

I did this in rails console, my model is Shift and has start_time: datetime.

2.1.3 :022 > time = "04/02/2018 5:23 AM"                                                          
 => "04/02/2018 5:23 AM"                                                                          
2.1.3 :023 > Time.zone = "Singapore"                                                              
 => "Singapore"                                                                                   
2.1.3 :024 > shift.start_at = time                                                                
 => "04/02/2018 5:23 AM"                                                                          
2.1.3 :025 > shift.save                                                                           
   (0.1ms)  begin transaction                                                                     
  SQL (0.5ms)  UPDATE "shifts" SET "start_at" = ?, "updated_at" = ? WHERE "shifts"."id" = 2  [["st
art_at", "2018-02-03 21:23:00.000000"], ["updated_at", "2018-05-02 05:43:38.527338"]]             
   (1.4ms)  commit transaction                                                                    
 => true                                                                                          
2.1.3 :026 > Time.zone = "Dublin"                                                                 
 => "Dublin"                                                                                      
2.1.3 :027 > shift.start_at = time                                                                
 => "04/02/2018 5:23 AM"                                                                          
2.1.3 :028 > shift.save                                                                           
   (0.2ms)  begin transaction                                                                     
  SQL (0.4ms)  UPDATE "shifts" SET "start_at" = ?, "updated_at" = ? WHERE "shifts"."id" = 2  [["st
art_at", "2018-02-04 05:23:00.000000"], ["updated_at", "2018-05-02 05:45:44.638291"]]             
   (1.4ms)  commit transaction                                                                    
 => true                      

See the data inside the SQL.

iGian
  • 11,023
  • 3
  • 21
  • 36