-1

i have date format Sat, 01 Jan 2000 16:20:00 UTC +00:00 and i have just take the date time value the given form as "2000-01-01 16:20:00" and from this i have just taken the time 16:20:00 with strftime('%H:%M:%S') now i need to convert this to UTC Here is the rake file m trying to update, the main problem is the time conversion on by staging environment.

bookings = Booking.where(booking_status: 'booked')
                  .where('booking_date = ?', Date.current)
if bookings.present?
  bookings.each do |booking|
    date = booking&.booking_time&.strftime('%H:%M:%S')&.to_time&.utc

    booking.update(booking_status: 'no_show') if date < Time.current
  end
end
San
  • 165
  • 1
  • 7
  • Does `DateTime.parse(...)` handle it properly? – tadman Jan 14 '21 at 09:55
  • Does sometimes the `booking_time` of `booked books` is nil? How many booking records do you have? Do you set an index on `booking_status` and `booking_date`? Do not update the records in the loop, use `update_all` will run fasrer. – spike 王建 Jan 14 '21 at 09:57
  • Some explanation would help. It seems as if you have a `booking_date` which contains just the date and a `booking_time` which contains just the time, but somehow also has an unused date part of 2000-01-01. And now you want to create a Ruby `Time` object with the date-part from `booking_date` and the time-part from `booking_time` – is that correct? It would help to see the `bookings` database schema and some example entries. BTW: why did you split date and time in the first place? It seems to cause a bit of trouble. – Stefan Jan 14 '21 at 10:38
  • Not sure I understand the question... Surely if anything, you want to convert the time to UTC **BEFORE (!!)** removing any timezone information via `strftime('%H:%M:%S')`? And wouldn't it have made more sense to give us an example that's not already UTC to begin with? This seems like a pretty pointless question you're asking, where you want to convert a time that's already UTC, into UTC. – Tom Lord Jan 14 '21 at 11:05
  • And as mentioned above, this is a bad database design to have `booking_date` and `booking_time` as separate columns. If you want to extract the date information, then this is already available as part of the `booking_time`. – Tom Lord Jan 14 '21 at 11:07
  • 2
    When posting a question on SO it's (obviously) advisable to hang around awhile to see if readers have any questions about your statement of the problem. We see that you didn't and they did. It's now been 7+ hours since posting and you still haven't returned. Not good. – Cary Swoveland Jan 14 '21 at 17:32
  • Sorry for the late response. @tadman i tried DateTime.parse(..) but it didn't work – San Jan 14 '21 at 18:39
  • @Stefan i have a list of available booking time so i have a separate column from the booking date and booking time. The available time is same for all the following dates. – San Jan 14 '21 at 18:43
  • 1
    Please @San edit your question and add the error or misbehavior you ran into, also clarify that your issue is not that the rake task is slow – r4cc00n Jan 14 '21 at 18:49
  • edited my answer so you can parse to UTC @San – r4cc00n Jan 14 '21 at 18:59

2 Answers2

2

First I am agreed with the comments above seems like you don't really need that extra column, instead of that you could define a function within your model that returns the value when needed:

def book_status
   date = booking_time&.strftime('%H:%M:%S')&.to_time&.utc
   date < Time.current ? 'no_show' : 'booked'
end

Then to any instance of your book model, you can access his status like this: my_book.book_status.

But if you really need/want that extra column there is a way to speed up the process, the problem you have in your code is that you perform n SQL queries to update each item plus if you use the update function you are also triggering all the ActiveRecord callbacks for each instance of book, a possible workaround is to use the update_all, but take into account that if you need callbacks then you need to keep it the way you have it, in any case, this is how to do it with update_all (should speed up the process):

books_ids = Booking.where(booking_status: 'booked').
                  where('booking_date = ?', Date.current).
                  select { |book_i| book_i.booking_time&.strftime('%H:%M:%S')&.to_time&.utc < Time.current }.map(&:id)

Book.where(id: books_ids).update_all(booking_status: 'no_show')

The above code will generate 2 queries instead of n one to get the books_ids that you want to update and the second one to really update those books (without trigger callbacks), in any case, I recommend the first approach instead of this.

A third option is to do it as needed like below:

def book_status
   date = booking_time&.strftime('%H:%M:%S')&.to_time&.utc
   if date < Time.current
     self.update(booking_status: 'no_show')
     booking_status
   else
     booking_status
   end
end

if you don't want/need callbacks then use update_column instead.

EDITED:

If what you want is to parse the format this is how you can do it:

require 'time'
p Time.parse('16:20:00').utc

You can test the above snippet here.

r4cc00n
  • 1,927
  • 1
  • 8
  • 24
0

Maybe the staging area server has UTC time. check it, or post some an error log to what you got as error.

icarus
  • 85
  • 2
  • 13
  • Do you have any idea why the booking time is storing time in UTC in my db. – San Jan 15 '21 at 03:35
  • it must be configured as such. [here](https://stackoverflow.com/a/32229086/765194) is a complete clarification about it. – icarus Jan 15 '21 at 05:01