I wish to find the timezone offset using Lua, however I'm facing what looks odd behaviour, so I must be missing something.
I'm using the code:
local t1 = os.time();
local t2 = os.time( os.date( "!*t" ) );
print( t1, t2, t1 - t2 );
local t1 = os.time( os.date( "*t" ) );
local t2 = os.time( os.date( "!*t" ) );
print( t1, t2, t1 - t2 );
local t1 = os.date( "%c" );
local t2 = os.date( "!%c" );
print( t1, t2 );
local t1 = os.time( os.date( "*t", 86400 ) );
local t2 = os.time( os.date( "!*t", 86400 ) );
print( t1, t2, t1 - t2 );
local t1 = os.date( "*t" );
local t2 = os.date( "!*t" );
print( t1.hour, t1.isdst, t2.hour, t2.isdst );
print( ((t1.hour - t2.hour) * 60 + (t1.min - t2.min)) * 60 );
Which produces the output:
1496733916 1496730316 3600
1496733916 1496730316 3600
06/06/17 09:25:16 06/06/17 07:25:16
86400 82800 3600
9 true 7 false
7200
Now I'm located in UTC+2 (currently due to summer time, in winter is UTC+1, CEST) so I expected to see an offset of 7200 seconds. However the first two attempts, which should be equivalent, and they are; give me a difference of only one hour. When printing the time in human readable format it can clearly be seen that the offset between both are 2 hours. The fourth attempt is using a fixed point in time (86400 number of seconds in a day, technique from this question) the offset is also 1 hour). Finally when directly subtracting directly the hours (and minutes just in case of not whole hours offset) I get the 2 hours offset.
I suspect this is due to the daylight saving time or dst. What I'm trying to accomplish is get the time from a timestamp (already in UTC), and since os.time
is in local time I need to convert that timestamp so it matches localtime.
Or am I completely missing something?
getTimezoneOffset() returns the difference between UTC time and local time. getTimezoneOffset() returns the difference in minutes. For example, if your time zone is GMT+2, -120 will be returned.
This difference is expressed with respect to UTC and is generally shown in the format ±[hh]:[mm], ±[hh][mm], or ±[hh]. So if the time being described is two hours ahead of UTC (such as in Kigali, Rwanda [approx. 30° E]), the UTC offset would be "+02:00", "+0200", or simply "+02".
What is a "zone offset"? A zone offset is the difference in hours and minutes between a particular time zone and UTC. In ISO 8601, the particular zone offset can be indicated in a date or time value. The zone offset can be Z for UTC or it can be a value "+" or "-" from UTC.
The client's timezone offset could be detected by using the Date object's getTimezoneOffset() method. The getTimezoneOffset() method returns the time difference between UTC time and local time, that is the time offset, in minutes.
As stated in the manual, you shouldn't use the result of os.time()
directly, because it can be any value. Use os.date()
to get some meaningful information out of it.
It only has any known meaning at all in a few systems, and even then it's only defined that it's a number of seconds since some date.
That being said, the reason you're having this problem seems to be the fact that your table has an isdst
flag set. This means os.time()
will automatically subtract an hour from it, so you're back to winter time.
Your last aproach is bugged too, by the way, since it won't work in the hours before midnight, where one timestamp is already in the next day, so the difference of the hour fields doesn't work anymore.
The correct way of doing this is surprisingly easy:
local timezone = os.date('%z') -- "+0200"
local signum, hours, minutes = timezone:match '([+-])(%d%d)(%d%d)'
print(signum, hours, minutes)
local dt = (tonumber(signum..hours)*3600 + tonumber(signum..minutes)*60)
print(dt, type(dt))
Which prints:
+ 02 00
7200 number
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With