Josh
Josh

Reputation: 3265

Getting local time for future events based off UTC

I'm working on a script that will look up an event on a community Google Calendar (using Eastern Time Zone) and successfully convert it to the local user's timezone. Because it is a community Google Calendar, I cannot set the time to display as UTC, which would theoretically make this that much easier. Here is a step-by-step process that I am attempting to create:

  1. Get the event time as it stands (Eastern time) from Google Calendar. This is done quite easily using the API and json format.
  2. Get the Eastern timezone offset based on the event time using Google Maps API. Again, this is easily done.
  3. Convert the Event time from Eastern to UTC, which I believe is done by adding the offset to the Event time.
  4. Calculate the local timezone/UTC timezone difference based on the future date.
  5. Return the local time for the event by adding step 4's result to the UTC event's time.

However, no matter what I do, it seems to not work the way I want it. Here is the code as it stands:

local function get_local_time(dateTime)
    local xyear, xmonth, xday = string.match(dateTime, "(%d+)%-(%d+)%-(%d+)") -- Date format is displayed as yyyy-mm-dd
    local xhour, xmin = string.match(dateTime, "%a(%d+):(%d+)") -- Time format is displayed as Thh:mm

    local event_time = os.time({year = xyear, month = xmonth, day = xday, hour = xhour or 23, min = xmin or 59, sec = 0}) -- Gets epoch time for event time

    async_ok, async = pcall (require, "async") -- Asynchronous lookup functions
    if not json then json = require 'json' end

    tzpage = "https://maps.googleapis.com/maps/api/timezone/json?location=28.4158,-81.2989&timestamp=" .. event_time .. "&key=" .. key -- Gets offset data for Eastern Time Zone

    if async_ok then
        tzrpage = async.request(tzpage, "HTTPS")
    end

    retval, page, status, headers, full_status = tzrpage:join()
    tzrpage = nil

    if status == 200 then
        tzopage = json.decode(page)
    end

    local eastern_offset = tzopage.rawOffset+tzopage.dstOffset -- Adds the offset information together (includes Daylight Savings)

    local utc_event_time = event_time+eastern_offset -- Sets UTC's time for the event

    local utctime, localtime = os.date("!*t", utc_event_time), os.date("*t", utc_event_time) -- Sets table data for events based on UTC's time of the event
    localtime.isdst = false
    local localoffset = os.difftime(os.time(utctime), os.time(localtime)) -- Sets the time difference between UTC and local time at the time of the event UTC

    return os.date("%A, %B %d %Y at %I:%M%p", (utc_event_time-localoffset)) -- Should return local time of the event
end

But when I do something like the following:

print(get_local_time("2015-10-31T01:15:00"))

it returns

Friday, October 30 2015 at 02:15PM

when it should be returning

Friday, October 30 2015 at 10:15PM

as I'm Pacific time.

If I change

return os.date("%A, %B %d %Y at %I:%M%p", (utc_event_time-localoffset))

to

return os.date("%A, %B %d %Y at %I:%M%p", (utc_event_time+localoffset))

I get

Saturday, October 31 2015 at 04:15AM

Which again, is incorrect.

Where am I going wrong with this script? As a side note, the async is a client dependency, but it's essentially http.request.

Upvotes: 2

Views: 566

Answers (1)

Michael - sqlbot
Michael - sqlbot

Reputation: 179194

Convert the Event time from Eastern to UTC, which I believe is done by adding the offset to the Event time.

Subtracting.

The offset shown in a timestamp is a signed number. It's already been "added" to UTC to generate the local time, so the inverse operation would be to subtract it. With -0400 being negative, you'd need to subtract negative 4 hours to convert back to UTC.

Upvotes: 3

Related Questions