Discussion:
GMT offset
(too old to reply)
Peter
2008-04-03 18:13:52 UTC
Permalink
I'm in GMT + 1 (+ 1 for saving daylight) and I'm having trouble getting this
number from the system somehow.
Which functions should I use and how to end up with the same data as can be
seen here:
http://www.timeanddate.com/worldclock/city.html?n=48

Basically I would like to get the number +2 because that's the difference
right now (because of daylight saving time)
But it should also work when there's no daylight saving time, e.g. in winter
I should get +1 on my system.

What function(s) (and how) do I use to get this information ?
Remy Lebeau (TeamB)
2008-04-03 20:19:28 UTC
Permalink
Post by Peter
I'm in GMT + 1 (+ 1 for saving daylight) and I'm having trouble
getting this number from the system somehow.
Which functions should I use
The Win32 API provides a GetTimeZoneInformation() function for that.


Gambit
Peter
2008-04-03 20:30:10 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Peter
I'm in GMT + 1 (+ 1 for saving daylight) and I'm having trouble
getting this number from the system somehow.
Which functions should I use
The Win32 API provides a GetTimeZoneInformation() function for that.
Got it, yet I get a negative value, which I think is strange ?
However, I'll multiply it with -1 then.
Remy Lebeau (TeamB)
2008-04-03 21:46:00 UTC
Permalink
Post by Peter
Got it, yet I get a negative value, which I think is strange ?
Please show your actual code. Are you checking the return value to know how
to interpret the information?


Gambit
Peter
2008-04-04 14:20:13 UTC
Permalink
Post by Remy Lebeau (TeamB)
Please show your actual code. Are you checking the return value to know
how to interpret the information?
PS. GMTOffset is a BYTE value containing a 15 minute-interval value that I
use in my code !!

E.g. I'm in zone GMT + 1 ( + 1 for daylight) so I'm in GMT+2
That makes that variable GMTOffset must be + 8

Following code does this yet I had to reverse the negative value which I
thought was strange.
Let me know what you think.

<snip>

TIME_ZONE_INFORMATION TIME_ZONE_INFO ;

// Not sure if this is needed but making sure all bytes are null inside the
structure
memset((void*)&TIME_ZONE_INFO, 0, sizeof(TIME_ZONE_INFORMATION)) ;

if ( GetTimeZoneInformation(&TIME_ZONE_INFO) != TIME_ZONE_ID_UNKNOWN )
{
GMTOffset = (BYTE)(((TIME_ZONE_INFO.Bias + TIME_ZONE_INFO.DaylightBias)
/ 15) * -1) ;
}
else GMTOffset = 0 ;

</snip>
Duane Hebert
2008-04-04 16:09:56 UTC
Permalink
Post by Peter
Post by Remy Lebeau (TeamB)
Please show your actual code. Are you checking the return value to know
how to interpret the information?
PS. GMTOffset is a BYTE value containing a 15 minute-interval value that I
use in my code !!
E.g. I'm in zone GMT + 1 ( + 1 for daylight) so I'm in GMT+2
That makes that variable GMTOffset must be + 8
Following code does this yet I had to reverse the negative value which I
thought was strange.
Let me know what you think.
<snip>
TIME_ZONE_INFORMATION TIME_ZONE_INFO ;
// Not sure if this is needed but making sure all bytes are null inside
the structure
memset((void*)&TIME_ZONE_INFO, 0, sizeof(TIME_ZONE_INFORMATION)) ;
if ( GetTimeZoneInformation(&TIME_ZONE_INFO) != TIME_ZONE_ID_UNKNOWN )
{
GMTOffset = (BYTE)(((TIME_ZONE_INFO.Bias + TIME_ZONE_INFO.DaylightBias)
/ 15) * -1) ;
}
else GMTOffset = 0 ;
</snip>
Aren't .bias and .DaylightBias both unsigned longs?
What's a BYTE? I would have thought unsigned char but since it's
giving you a negative value...

Anyway, does this link help?
http://www.codeproject.com/KB/cpp/cppchangetimezone.aspx?display=PrintAll
Remy Lebeau (TeamB)
2008-04-04 18:00:23 UTC
Permalink
Post by Duane Hebert
Aren't .bias and .DaylightBias both unsigned longs?
No, they are both signed longs.
Post by Duane Hebert
What's a BYTE?
unsigned char
Post by Duane Hebert
I would have thought unsigned char but since it's giving you a negative
value...
A BYTE cannot hold a negative value. However, if he is interpretting the
value as a signed value, then anything with the high-order bit set (0x80 and
higher) will be negative. In this case, a signed -8 is the same binary
value as an unsigned 248 (0xF8).


Gambit
Duane Hebert
2008-04-05 12:48:16 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Duane Hebert
I would have thought unsigned char but since it's giving you a negative
value...
A BYTE cannot hold a negative value. However, if he is interpretting the
value as a signed value, then anything with the high-order bit set (0x80
and higher) will be negative. In this case, a signed -8 is the same
binary value as an unsigned 248 (0xF8).
But it looks like he's interpreting it as a BYTE with the
cast. That's what I didn't understand.
Peter
2008-04-05 14:35:05 UTC
Permalink
Post by Duane Hebert
Post by Remy Lebeau (TeamB)
A BYTE cannot hold a negative value. However, if he is interpretting the
value as a signed value, then anything with the high-order bit set (0x80
and higher) will be negative. In this case, a signed -8 is the same
binary value as an unsigned 248 (0xF8).
But it looks like he's interpreting it as a BYTE with the
cast. That's what I didn't understand.
The cast does the conversion, it doesn't simply throw away the Most
Significant Bytes of the signed long.

Remy Lebeau (TeamB)
2008-04-04 17:23:04 UTC
Permalink
Post by Peter
Following code does this yet I had to reverse the negative value
which I thought was strange.
Try this. I have been using this kind of logic for years without any
problem:

int GetGMTOffset()
{
int TZOffset;
TIME_ZONE_INFORMATION TimeZoneInformation;

switch( GetTimeZoneInformation(&TimeZoneInformation) )
{
case TIME_ZONE_ID_UNKNOWN:
case TIME_ZONE_ID_STANDARD:
TZOffset = TimeZoneInformation.Bias;
break;

case TIME_ZONE_ID_DAYLIGHT:
TZOffset = TimeZoneInformation.Bias;
if( TimeZoneInformation.DaylightDate.wMonth != 0 )
TZOffset += TimeZoneInformation.DaylightBias;
break;

case 0xFFFFFFFF:
TZOffset = 0;
break;
}

if( TZOffset != 0 )
TZOffset /= 60; // TZOffset is in minutes. Change to Hours.

return TZOffset;
}


Gambit
Peter
2008-04-04 20:08:31 UTC
Permalink
Post by Remy Lebeau (TeamB)
Try this. I have been using this kind of logic for years without any
int GetGMTOffset()
{
int TZOffset;
TIME_ZONE_INFORMATION TimeZoneInformation;
switch( GetTimeZoneInformation(&TimeZoneInformation) )
{
TZOffset = TimeZoneInformation.Bias;
break;
TZOffset = TimeZoneInformation.Bias;
if( TimeZoneInformation.DaylightDate.wMonth != 0 )
TZOffset += TimeZoneInformation.DaylightBias;
break;
TZOffset = 0;
break;
}
if( TZOffset != 0 )
TZOffset /= 60; // TZOffset is in minutes. Change to Hours.
return TZOffset;
}
Thanks. I get the exact same data. In my case a negative value -2 despite
the expected +2
I suppose it's just reverse logic and multiplying by -1 will do the trick.
Can somebody in the GMT -x zone test this and see if (s)he gets a positive
value instead of a negative value ?

As a sanity test I checked my system's settings again and yup, it's set ok.

I hope you don't mind me pointing out a flaw in your function Gambit ?
For certain zones you will get an incorrect value. E.g Adelaide (to give an
example):
http://www.timeanddate.com/worldclock/city.html?n=5
You will get a value half an hour off.
Remy Lebeau (TeamB)
2008-04-04 21:12:01 UTC
Permalink
Post by Peter
Thanks. I get the exact same data. In my case a negative value -2
despite the expected +2
Did you validate that the values inside the TIME_ZONE_INFORMATION structure
were accurate to begin with? Did you verify that your machine's Regional
settings are set up correctly?
Post by Peter
I suppose it's just reverse logic and multiplying by -1 will
do the trick.
I would not recommend doing that. That is not the correct way to handle
time zones.
Post by Peter
Can somebody in the GMT -x zone test this and see if (s)he
gets a positive value instead of a negative value ?
I am in a negative zone (-8). The code I gave you returns 7 right now,
though. I have never had that problem before. Like I said, I have been
using this code for years and none of my company's customers has ever
complained about it.

Looking into it, apparently positive numbers are returned for time zones
west of GMT, and negative numbers for time zones east of GMT. I guess the
code will have to take that into account more.
Post by Peter
I hope you don't mind me pointing out a flaw in your function Gambit ?
How would you propose fixing it?


Gambit
Peter
2008-04-04 22:47:07 UTC
Permalink
Post by Remy Lebeau (TeamB)
Post by Peter
Thanks. I get the exact same data. In my case a negative value -2
despite the expected +2
Did you validate that the values inside the TIME_ZONE_INFORMATION
structure were accurate to begin with? Did you verify that your machine's
Regional settings are set up correctly?
Yes all that is set fine and I did a sanity check before I sent last reply
as well.
Post by Remy Lebeau (TeamB)
Post by Peter
I suppose it's just reverse logic and multiplying by -1 will
do the trick.
I would not recommend doing that. That is not the correct way to handle
time zones.
Well, your test seems to show the same logic, so it *is* the correct way to
handle it if you want to show the GMT offset.
Post by Remy Lebeau (TeamB)
Post by Peter
Can somebody in the GMT -x zone test this and see if (s)he
gets a positive value instead of a negative value ?
I am in a negative zone (-8). The code I gave you returns 7 right now,
though. I have never had that problem before. Like I said, I have been
using this code for years and none of my company's customers has ever
complained about it.
-7 makes sense because of Daylight Saving time, see SF as example:
http://www.timeanddate.com/worldclock/city.html?n=224
I say MINUS 7 as the times -1 logic needs to be applied.
Post by Remy Lebeau (TeamB)
Looking into it, apparently positive numbers are returned for time zones
west of GMT, and negative numbers for time zones east of GMT. I guess the
code will have to take that into account more.
Exactly, reverse logic.
Post by Remy Lebeau (TeamB)
Post by Peter
I hope you don't mind me pointing out a flaw in your function Gambit ?
How would you propose fixing it?
Well there are regions in this world that have an offset no evenly devidable
by one hour, so you'll need to pass the minutes as retrieved from the
function, or what I do, the amount in quarters of an hour, rather than hours
and take that in account when showing (or using) the GMT offset.
When you use 15 minute intervals you cover everything as well.
E.g. see this x hours + 45 minute offset example:
http://www.timeanddate.com/worldclock/city.html?n=117
Continue reading on narkive:
Loading...