Time Difference & Time Zones

Hey all, so I’ve been racking my brain over this for some time but can’t quite seem to figure it out.  

What I need to do:  Calculate how much time in hours and minutes is left until 23:59 Eastern time (UTC-4hrs).

I’ve read Rob’s “Working with Time and Dates” tutorial, as well as came across other code, but just can’t seem to put the pieces together.  

Some time zone code I came across:

-- Compute the difference in seconds between local time and UTC. local function get\_timezone() local now = os.time() return os.difftime(now, os.time(os.date("!\*t", now))) end timezone = get\_timezone() -- Return a timezone string in ISO 8601:2000 standard form (+hhmm or -hhmm) local function get\_tzoffset(timezone) local h, m = math.modf(timezone / 3600) return string.format("%+.4d", 100 \* h + 60 \* m) end tzoffset = get\_tzoffset(timezone) --[[debugging for \_, tz in ipairs(arg) do if tz == '-' then tz = timezone else tz = 0 + tz end print(tz, get\_tzoffset(tz)) end --]] -- return the timezone offset in seconds, as it was on the time given by ts -- Eric Feliksik local function get\_timezone\_offset(ts) local utcdate = os.date("!\*t", ts) local localdate = os.date("\*t", ts) localdate.isdst = false -- this is the trick return os.difftime(os.time(localdate), os.time(utcdate)) end

And Rob’s timestamp code:

function makeTimeStamp(dateString) local pattern = "(%d+)%-(%d+)%-(%d+)%a(%d+)%:(%d+)%:([%d%.]+)([Z%p])(%d%d)%:?(%d%d)" local year, month, day, hour, minute, seconds, tzoffset, offsethour, offsetmin = dateString:match(pattern) local timestamp = os.time( {year=year, month=month, day=day, hour=hour, min=minute, sec=seconds} ) local offset = 0 if ( tzoffset ) then if ( tzoffset == "+" or tzoffset == "-" ) then -- we have a timezone! offset = offsethour \* 60 + offsetmin if ( tzoffset == "-" ) then offset = offset \* -1 end timestamp = timestamp + offset end end return timestamp end

So basically my app has a timer and every day the timer resets and shows the user the number of hours and minutes until 11:59 EDT.  The trouble I’m having is calculating the difference of time between now and a future set time (i.e. 06:59 UTC).  Any advice would be greatly appreciate

Ok I think I may have gotten it.  Can someone please check to see if this code returns the correct amount of hours & minutes until 23:59 Eastern Time (New York)?

local function timeToMidnight() local function get\_timezone() local now = os.time() return os.difftime(now, os.time(os.date("!\*t", now))) end offset = get\_timezone() local myTimeNow = os.date("\*t", os.time()) local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = false} UTCMidnight = os.date("\*t", os.time(midnight)) UTCMidnight.isdst = false UTCMidnight = os.time(UTCMidnight) currentUTC = os.date("!\*t", os.time()) currentUTCsecs = (os.time(currentUTC)) + offset NYMidnight = UTCMidnight - 14400 timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60 hoursRemaining = math.floor(timeDifference) minsRemaining = math.round((timeDifference%1)\*60) print(hoursRemaining .. " hours and " .. minsRemaining .. " mins") end

It was off by 2 hours for me.  It calculated a time that would end up at 10pm.  I tweaked on it a bit and came up with this:

[lua]

local function timeToMidnight()

    local function get_timezone()
        local now = os.time()
        return os.difftime(now, os.time(os.date("!*t", now)))
    end
    offset = get_timezone()

    local myTimeNow = os.date("*t", os.time())

    local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = true}

    UTCMidnight = os.date("*t", os.time(midnight))
    UTCMidnight.isdst = true
    UTCMidnight = os.time(UTCMidnight)

    currentUTC = os.date("!*t", os.time())

    currentUTCsecs = (os.time(currentUTC)) + offset
    NYMidnight = UTCMidnight – 14400

    timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60

    hoursRemaining = math.floor(timeDifference)
    minsRemaining = math.round((timeDifference%1)*60)

    print(hoursRemaining … " hours and " … minsRemaining … " mins")
 end

 timeToMidnight()

[/lua]

I set isdst to true in both places since we are in dst at the moment and I commented out where you were subtracting 14400.

Thanks Rob.  What exactly does this return for you then?  What is your local time zone?  For me, this is returning midnight in my time zone (Pacific). 

I see, it looks like its returning the hours/mins until midnight local time anywhere.  The problem is I need it to return hours/mins until 23:59EDT from where ever the user is. 

I see.  Yes, it would return hours/mins to 23:59 localtime. Maybe someone can come up with an answer for you faster than I can.  I’m going to have to think about it.

You should be able to find your offset and then add/subtract from -4:00 from it.

Yup, that’s where I was going in my solution.  Subtracting the -14400 from the UTC time gave NY time.  However it should have actually been -10800 because of DST.  Please try this code and tell me if it works for you:

local function timeToMidnight() local function get\_timezone() local now = os.time() return os.difftime(now, os.time(os.date("!\*t", now))) end offset = get\_timezone() local myTimeNow = os.date("\*t", os.time()) local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = true} UTCMidnight = os.date("\*t", os.time(midnight)) UTCMidnight.isdst = true UTCMidnight = os.time(UTCMidnight) print("UTCMidnight: " .. UTCMidnight) currentUTC = os.date("!\*t", os.time()) currentUTCsecs = (os.time(currentUTC)) + offset print("CurrentUTC: " .. currentUTCsecs) NYMidnight = UTCMidnight - 10800 print("NYMidnight: " .. NYMidnight) timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60 hoursRemaining = math.floor(timeDifference) minsRemaining = math.round((timeDifference%1)\*60) print(hoursRemaining .. " hours and " .. minsRemaining .. " mins") end timeToMidnight()

UTCMidnight: 1364788740
CurrentUTC: 1364748036
NYMidnight: 1364777940
8 hours and 18 mins

However, that would put me at 9pm ET.

What time zone are you in?

Eastern EDT

Can you run this for me:

local function timeToMidnight() local function get\_timezone() local now = os.time() return os.difftime(now, os.time(os.date("!\*t", now))) end offset = get\_timezone() print("Offset: " .. offset) local myTimeNow = os.date("\*t", os.time()) local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = true} UTCMidnight = os.date("\*t", os.time(midnight)) UTCMidnight.isdst = true UTCMidnight = os.time(UTCMidnight) print("UTCMidnight: " .. UTCMidnight) currentUTC = os.date("!\*t", os.time()) currentUTCsecs = (os.time(currentUTC)) + offset print("CurrentUTC: " .. currentUTCsecs) NYMidnight = UTCMidnight - 10800 print("NYMidnight: " .. NYMidnight) timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60 hoursRemaining = math.floor(timeDifference) minsRemaining = math.round((timeDifference%1)\*60) print(hoursRemaining .. " hours and " .. minsRemaining .. " mins") end timeToMidnight()

2013-03-31 15:19:32.783 Corona Simulator[5389:707] Offset: -18000
2013-03-31 15:19:32.783 Corona Simulator[5389:707] UTCMidnight: 1364788740
2013-03-31 15:19:32.784 Corona Simulator[5389:707] CurrentUTC: 1364757572
2013-03-31 15:19:32.784 Corona Simulator[5389:707] NYMidnight: 1364777940
2013-03-31 15:19:32.784 Corona Simulator[5389:707] 5 hours and 39 mins

Still 9pm ET

Ok, now I think I got it.  Please try this one:

local function timeToMidnight() local function get\_timezone\_offset(ts) local utcdate = os.date("!\*t", ts) local localdate = os.date("\*t", ts) localdate.isdst = false -- this is the trick return os.difftime(os.time(localdate), os.time(utcdate)) end local offset = get\_timezone\_offset(os.time()) local UTCNow = os.time() local UTCTable = os.date("\*t", UTCNow) local dstValue if UTCTable.isdst == true then dstValue = -14400 else dstValue = -18000 end local midnight = {year=UTCTable.year, month=UTCTable.month, day=UTCTable.day, hour=23, min=59} local timeDifference = (((os.time(midnight) - (UTCNow + dstValue)) + offset)/60)/60 hoursRemaining = math.floor(timeDifference) minsRemaining = math.round((timeDifference%1)\*60) print(hoursRemaining .. " hours and " .. minsRemaining .. " mins") end timeToMidnight()

That worked!

Cool, thanks for all your input. Maybe some one else would be able to test the above code as well? I’m interested to see the results from some one east of UTC 0.

You should be able to change your timezone on your computer.

Ok I think I may have gotten it.  Can someone please check to see if this code returns the correct amount of hours & minutes until 23:59 Eastern Time (New York)?

local function timeToMidnight() local function get\_timezone() local now = os.time() return os.difftime(now, os.time(os.date("!\*t", now))) end offset = get\_timezone() local myTimeNow = os.date("\*t", os.time()) local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = false} UTCMidnight = os.date("\*t", os.time(midnight)) UTCMidnight.isdst = false UTCMidnight = os.time(UTCMidnight) currentUTC = os.date("!\*t", os.time()) currentUTCsecs = (os.time(currentUTC)) + offset NYMidnight = UTCMidnight - 14400 timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60 hoursRemaining = math.floor(timeDifference) minsRemaining = math.round((timeDifference%1)\*60) print(hoursRemaining .. " hours and " .. minsRemaining .. " mins") end

It was off by 2 hours for me.  It calculated a time that would end up at 10pm.  I tweaked on it a bit and came up with this:

[lua]

local function timeToMidnight()

    local function get_timezone()
        local now = os.time()
        return os.difftime(now, os.time(os.date("!*t", now)))
    end
    offset = get_timezone()

    local myTimeNow = os.date("*t", os.time())

    local midnight = {year=myTimeNow.year, month=myTimeNow.month, day=myTimeNow.day, hour=23, min=59, isdst = true}

    UTCMidnight = os.date("*t", os.time(midnight))
    UTCMidnight.isdst = true
    UTCMidnight = os.time(UTCMidnight)

    currentUTC = os.date("!*t", os.time())

    currentUTCsecs = (os.time(currentUTC)) + offset
    NYMidnight = UTCMidnight – 14400

    timeDifference = ((os.difftime(NYMidnight, currentUTCsecs))/60)/60

    hoursRemaining = math.floor(timeDifference)
    minsRemaining = math.round((timeDifference%1)*60)

    print(hoursRemaining … " hours and " … minsRemaining … " mins")
 end

 timeToMidnight()

[/lua]

I set isdst to true in both places since we are in dst at the moment and I commented out where you were subtracting 14400.

Thanks Rob.  What exactly does this return for you then?  What is your local time zone?  For me, this is returning midnight in my time zone (Pacific). 

I see, it looks like its returning the hours/mins until midnight local time anywhere.  The problem is I need it to return hours/mins until 23:59EDT from where ever the user is.