how do I convert a timestamp in GMT to local time? I know about
GetTimeZoneInformation but I need to be able to convert any timestamp, even
if the date is some years old.
GetTimeZoneInformation seems to be useful only for the current year, or am
I missing something.
In particular I need to know the transition dates.
Or are there any functions available for this?
Thanks,
Udo
Udo, Do you want the "local time" to be relative to "here
and now" timezone or "then and there" timezone? --JohnH
>how do I convert a timestamp in GMT to local time? I know about
>GetTimeZoneInformation but I need to be able to convert any timestamp, even
>if the date is some years old.
>
>GetTimeZoneInformation seems to be useful only for the current year, or am
>I missing something.
>
>In particular I need to know the transition dates.
GTZI is only useful for the TZ rules which were current when the OS was
last updated, applied as if they were valid for the year in question.
What you ask for is near enough impossible, since it is no longer known
exactly when every change in clock stepping occurred in every location.
You sound Italian (which proves little; AIUI, the Glasgow ice-cream
trade has been Italian-run for over a century, and Mr Capone sounded
Italian too; for help on local questions, one should specify the
location); if your data is for a specific location, you may be able to
discover the history of changes there. And if your data covers a
restricted period of time, things can be easier.
Remember the possibility of Double Summer Time.
You will need to look up the transition date history for Italy (or
Chicago, or wherever), taking account of local rules, changes of border,
etc., and determine the applicable local-GMT difference for each datum.
Only if you are working at a fixed location and within the period since
the rules last changed is it likely that the normal OS functions will
help; I would recommend not using them otherwise in any way.
Note that the EU rules mean that the GMT-local difference changes at a
fixed GMT time everywhere; in America, the change ripples across the
country over a few hours, except where it does not apply.
Information and links via
<URL:http://www.merlyn.demon.co.uk/uksumtim.htm>
--
© John Stockton, Surrey, UK. j...@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.txt
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
> GTZI is only useful for the TZ rules which were current when the OS
> was last updated, applied as if they were valid for the year in
> question.
That's my problem...
> What you ask for is near enough impossible, since it is no longer
> known exactly when every change in clock stepping occurred in every
> location.
I thought this has been standardized? How comes Windows knows when to
change the clock?
> You sound Italian (which proves little; AIUI, the Glasgow ice-cream
Yes, I am Italian, but with motherlanguage being German :)
Anyway, I would like a automatic calculation, based on the system settings.
At least for Europe as this is needed for a product that may be sold in
other countries as Italy...
> trade has been Italian-run for over a century, and Mr Capone sounded
> Italian too; for help on local questions, one should specify the
> location);
I would like a location-independent solution (based on windows functions),
if that is possible :)
> if your data is for a specific location, you may be able to
> discover the history of changes there. And if your data covers a
> restricted period of time, things can be easier.
Pratically the date will be at most 1 or 2 weeks old but in theory it may
be even some months old.
Again, aren't the transition dates fixed?
>
> Remember the possibility of Double Summer Time.
Huh?
> You will need to look up the transition date history for Italy (or
> Chicago, or wherever), taking account of local rules, changes of
> border, etc., and determine the applicable local-GMT difference for
> each datum.
Then it works in Italy. What if the product is going to be used in Germany,
Austria, Swizerland, ...?
Are you telling me I need "transition tables" for each country?
>
> Only if you are working at a fixed location and within the period
> since the rules last changed is it likely that the normal OS functions
> will help; I would recommend not using them otherwise in any way.
Did the rules change at all?
> Note that the EU rules mean that the GMT-local difference changes at a
> fixed GMT time everywhere; in America, the change ripples across the
> country over a few hours, except where it does not apply.
Ok, it would help already if the translation works for each EU country.
Other countries would need a special adaption.
> Information and links via
> <URL:http://www.merlyn.demon.co.uk/uksumtim.htm>
Thanks, will check this out now.
Udo
Last year, while travelling around USA from my home location in Norway I
discovered a few items which might clarify the issue for you:
(My observations was made on a Windows 98 SE, but I suspect they
are valid for all windows versions)
The internal clock in the PC always run on the current local time.
When I moved from one timezone to another I thought it would be sufficient
to reset the timezone in the control panel, but found that I also had to
reset
the actual time.
Whenever you timestamp a file (create, modify, access) the timestamp is
set (in the directory) from the current local time.
Whenever you are presented with GMT, the "actual" internal time is converted
according to the current setting of the timezone, apparently disregarding
the
timezone setting that was in effect when the presented time was actually
registered.
Confused me a bit when I discovered these things, I had expected the system
to always operate on GMT, but that's how it is?
regards Sven
> Udo, Do you want the "local time" to be relative to "here
> and now" timezone or "then and there" timezone? --JohnH
I have a timestamp (TDateTime) in GMT format. I want to convert it to local
time, depending on the current system settings.
for example I want convert
09:23:00 29/01/1999 GMT
to
10:23:00 29/01/1999 MET (middle european time)
GetTimeZoneInformation gives me only information about the today's time
zone (which is in daylight savings time) but that is not necessarily the
same as I want (standard time in this case).
That's my problem...
Udo
> I thought this has been standardized? How comes Windows knows when to
> change the clock?
Somewhere deep inside there are informations stored about transition
dates and times for common locations. For the current location, you can
access the information calling the GetTimeZoneInformation API function.
> I would like a location-independent solution (based on windows functions),
> if that is possible :)
If what you mean is a conversion function for the current location I can
help you with a class that does this. However, it uses the Windows rules
(e. g. last sunday in March/October for Germany), and it doesn't cover
special cases such as the ones John mentioned.
If you e. g. want to convert a given UTC time into Japanese local time
on an Italian computer, things are a bit more complicated.
-Michael
But only for the current year...
>
>> I would like a location-independent solution (based on windows
>> functions), if that is possible :)
>
> If what you mean is a conversion function for the current location I
> can help you with a class that does this. However, it uses the Windows
> rules (e. g. last sunday in March/October for Germany), and it doesn't
> cover special cases such as the ones John mentioned.
That would be a great help!
Currently I'm using ESBDates from http://www.esbconsult.com.au bit is that
it simly uses the time zone information of the day.
>
> If you e. g. want to convert a given UTC time into Japanese local time
> on an Italian computer, things are a bit more complicated.
No, that is not necessary. I have a device that sends messages over the
GPRS network with a timestamp in GMT format. However it is possible that
the message is not delivered for an hour, a day, a week or more time in
case of network problems.
Whenever the message arrives to the server the timestamp (that can be some
days or some weeks old) should be displayed to the user in local time zone
(depending only on the server location).
Normally the message would arrive within some seconds but in some
situations the delay may be longer (and the year portion of the date may
change). Maybe I need to convert other timestamps as well, don't know it
now. Didn't know it is so difficult.
> > For the current location, you
> > can access the information calling the GetTimeZoneInformation API
> > function.
>
> But only for the current year...
Nope. With TIME_ZONE_INFORMATION.StandardDate and .DaylightDate, you get
the transition dates. This can be fix date like 'March 1st ervery year'
or a form like 'last Sunday in March every year'.
> That would be a great help!
I'll send it to your email address this evening.
-Michael
> Confused me a bit when I discovered these things, I had expected the
> system to always operate on GMT, but that's how it is?
I think windows "operates" in local time but knows the difference to GMT.
So, if you ask windows for the GMT time it will actually calculate it from
the local time.
I made this assumption because in the DOS world doesn't know of time zones
at all (IIRC).
Ever installed windows on two partitions on the same machine? Both of them
try to change the system clock on the transition dates. The result is that
the clock is set wrong if windows has not been configured correctly before.
(Fortunately windows asks the user to check the new system time :)
Udo
This changed with WinNT4 (I think). Previous versions used local
time, but WinNT4 keeps file date-times, etc. in GMT (a.k.a. UT)
and converts to local for display. --JohnH
Udo, That does not give me enough information to answer your
question.
Do you want the date and time that the user would have read on
his wall clock at the time that the time X was current (i.e. the
"there and then" time)?
Or do you want a time that when subtracted from your ("here
and now") date and time would give you the days and fraction
elapsed since the X time?
Maybe it would be easier to say what you want this time for.
Rgds, JohnH
>> GTZI is only useful for the TZ rules which were current when the OS
>> was last updated, applied as if they were valid for the year in
>> question.
>
>That's my problem...
>
>
>> What you ask for is near enough impossible, since it is no longer
>> known exactly when every change in clock stepping occurred in every
>> location.
>
>I thought this has been standardized? How comes Windows knows when to
>change the clock?
Bill Gates told it. Usually, he told it correctly; but my Win98 gets
the current UK transition time wrong.
>Pratically the date will be at most 1 or 2 weeks old but in theory it may
>be even some months old.
>Again, aren't the transition dates fixed?
Since the last change, and until they are changed again. Note that
Australia extended Summer Time for the Olympics; the EU *could* do the
same, though I do not expect it.
>> Remember the possibility of Double Summer Time.
During the War, the UK had Summer Time in Winter and Double Summer Time
in Summer. Remember, you did write 'converting *any* GMT time to local
time'.
But it now appears that you only need recent EU conversions.
>Did the rules change at all?
Certainly.
>> Information and links via
>> <URL:http://www.merlyn.demon.co.uk/uksumtim.htm>
>
>Thanks, will check this out now.
That will have told you what is needed.
The UK has followed EU rules since 1998; Ireland probably from 1996.
For the present EU countries, ISTM you can assume that the rules have
applied everywhere from 1998; but I don't know about the applicant
countries. The EU rules I think are valid until end 2006; but there
appears to be no intention to change them. I suggest that you make it a
condition of sale that the local time obeys EU rules, if you can ignore
outsiders.
It appears that past changes don't matter, anyway.
Now it is simple. Using the GMT year, for M = 3 & 10,
DT := EncodeDate(Year, M, 31) ; // Mar & Oct 31 days.
DoW := Day-Of-Week(DT); Delphi gives Sun=1..Sat=7, perversely.
DT := DT - (DW-1) + 1/24 ; // 01:00 GMT of last Sunday.
That gives the transition instants, in GMT.
Get the customer to agree the Winter offset (or ask Windows); 0 for UK,
1 for the Six and nearby, 2 for the Eastern Fringe. Subtract that/24
from the GMT, and subtract another 1/24 if between those dates, to get
the local time.
But check that before using it. Note that Delphi cannot represent an
hour exactly; rounding errors are possible. Your original times are,
perhaps, an exact number of minutes or seconds; and *ISTR* that
DecodeDate may truncate; if so, add a millisecond (1/86400000) to be
sure???
Alternatively, there is a simple expression on my page, valid for
present rules over 1900-2099, for the change dates.
EU Summer Time: Begin March (31 - (5*y div 4 + 4) mod 7) at 01:00 UTC
End October (31 - (5*y div 4 + 1) mod 7) at 01:00 UTC
Sure?
IMHO this function returns all you want to calculate from GMT into the local
time ...
JensG
--- cut ---
struct _TIME_ZONE_INFORMATION { // tzi
LONG Bias;
...
LONG StandardBias;
...
LONG DaylightBias;
} TIME_ZONE_INFORMATION;
Members
Bias
Specifies the current bias, in minutes, for local time translation on this
computer. The bias is the difference, in minutes, between Coordinated
Universal Time (UTC) and local time. All translations between UTC and local
time are based on the following formula:
UTC = local time + bias
StandardBias
Specifies a bias value to be used during local time translations that occur
during standard time. This member is ignored if a value for the StandardDate
member is not supplied.
This value is added to the value of the Bias member to form the bias used
during standard time. In most time zones, the value of this member is zero.
DaylightBias
Specifies a bias value to be used during local time translations that occur
during daylight time. This member is ignored if a value for the DaylightDate
member is not supplied.
This value is added to the value of the Bias member to form the bias used
during daylight time. In most time zones, the value of this member is - 60.
QuickInfo
--- cut ---
Exactly.
I want that the user does not have to deal with time zones at all.
A external device tells me "something occurred at time xxxx UTC/GMT" and I
want tell this the use but with the time being in the local time zone.
Udo
That is my problem...
Udo
You're right, I have missed this information. Of course these are goos news
:)
>> That would be a great help!
>
> I'll send it to your email address this evening.
Thanks a lot! I made a quick test application and for today it only adds 1
hour to the UTC time. Does the UTC time respect daylight savings time??
There should be 2 hours difference...
If you want to try yourself:
The code:
procedure TForm1.Panel1Click(Sender: TObject);
var
Date : TDateTime;
TZ : TTimeZone;
begin
Date := Trunc(MonthCalendar1.Date) +
Frac(DateTimePicker1.Time);
TZ := TTimeZone.Create;
try
Panel1.Caption := FormatDateTime('c "local"', TZ.UTCToLocal(Date));
gettimezoneinformation
finally
TZ.Free;
end;
end;
The form:
object Form1: TForm1
Left = 342
Top = 103
Width = 783
Height = 540
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object MonthCalendar1: TMonthCalendar
Left = 16
Top = 16
Width = 191
Height = 154
Date = 37419.494211169
TabOrder = 0
end
object DateTimePicker1: TDateTimePicker
Left = 16
Top = 176
Width = 186
Height = 21
CalAlignment = dtaLeft
Date = 37419.4944012616
Time = 37419.4944012616
DateFormat = dfShort
DateMode = dmComboBox
Kind = dtkTime
ParseInput = False
TabOrder = 1
end
object Panel1: TPanel
Left = 16
Top = 224
Width = 185
Height = 25
Caption = '(local time)'
TabOrder = 2
OnClick = Panel1Click
end
end
Udo
> Thanks a lot! I made a quick test application and for today it only adds 1
> hour to the UTC time. Does the UTC time respect daylight savings time??
Of course it does. Check your Windows time zone. For me it's currently
(GMT+01:00) Berlin, Bern, Brüssel, Rom, Stockholm, Wien
and the Daylight savings checkbox is checked.
Using your code, I get a difference of 2 hours.
BTW, you don't need to create a TTimeZone object. Just use the TimeZone
function which returns an automatically created singleton object. The
purpose is to store the transition dates per year so that there's no
need to calculate them at each call.
procedure TForm1.Button1Click(Sender: TObject);
begin
Caption := DateTimeToStr(TimeZone.UTCToLocal(Trunc(Now) + 0.5));
end;
returns '12.06.2002 14:00:00' for my current time zone.
-Michael
> > Does the UTC time respect daylight savings time??
>
> Of course it does.
Oops. Of course UTC is not touched by any daylight savings. I meant the
conversion respects daylight savings.
-Michael
I solve this problem by recording GMT *and* the local time
offset (in minutes) with each data record. Then I can correct
displays by just adding the offset to the GMT at the point of
conversion for display. As you can see from John Stockman's
post, the conversion of GMT to local for past and future times
is not simple -- and the only sense that I see for doing it is to
compare with "then and there" logs. Regards, JohnH
GetTimeZoneInformation supplies all that is needed for the current
location for the full duration of applicability of what it thinks are
the current rules there.
But if you are satisfied with EU time, then it is far easier to do all
the work oneself, as I have posted. Moreover, that way it is reliable.
Some people do not correctly configure their location in Windows.
The device that records the events knows only GMT time (a real time clock
of a microprocessor) so this won't work for me :(
Udo
> Of course it does. Check your Windows time zone. For me it's currently
>
> (GMT+01:00) Berlin, Bern, Brüssel, Rom, Stockholm, Wien
I'm in the same time zone. For what I know we currently are 2 hours ahead
respect to GMT (1 hour for the time zone + 1 hour because os daylight
savings time.
> and the Daylight savings checkbox is checked.
>
> Using your code, I get a difference of 2 hours.
You are right, must have made a mistake last time.
So, I'd say, problem solved. Thanks Michael! :)
> BTW, you don't need to create a TTimeZone object. Just use the
Thanks for the information and have a nice day :)
Udo
Is this true also for the last 10 years? I don't think so ... for example
the daylight saving "disable" moth date has changed a few years ago in our
country. And the dates aren't the same each year, since (for example) 21.03.
is not a saturday each year.
Bad luck that ...
JensG
Udo, Please be aware that Microsoft uses "UTC" in there
documentation where "GMT", "UT2", or something similar
should be used. UTC is time made up of constant length
seconds with an extra second added or removed every now
and then to account for the rotation of the earth. I.E. There
will be minutes with 61 or 59 seconds. GMT and UT2 adjust
the length of the seconds to match the rotation time of the
earth. Regards, JohnH
Well, as you don't say what country that is, the information is not very
usable - you are posting, however, from +0200, so perhaps you are in
Scandinavia. In which case, according to current rules, your Spring
change date cannot be 21.03; it is the last Sunday of March, Mar 25-31.
But read more carefully what I wrote: "for the full duration ... current
rules". GTZI does not give the dates; it gives information from which
the dates can be determined. See, for example, my <URL:http://www.merly
n.demon.co.uk/programs/tz-check.pas>, which reports that information.
From what you say, the current GTZI result for your country will work
from a few years ago until the rule next changes.
For GTZI information, see its page, and the linked TZI one, in
Win32.hlp.
This newsgroup is, I know, widely read in Europe; can anyone there
authoritatively give the year in which their country (or others) started
using the Last Sunday in Mar/Oct rule, and the year in which their
country started using a "pan-European" rather than National rule?
--
© John Stockton, Surrey, UK. j...@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP <URL:http://www.merlyn.demon.co.uk/programs/> - 00index.txt.
Do not Mail News to me. Before a reply, quote with ">" or "> " (SoRFC1036)
a) Germany, you got only 5 of 10 points: its not scandinavia. ;-)
b) the date was only intended to serve as example
> But read more carefully what I wrote: "for the full duration ... current
> rules". GTZI does not give the dates; it gives information from which
> the dates can be determined. See, for example, my <URL:http://www.merly
Ahhh, I see. Thanks.
JensG
> This newsgroup is, I know, widely read in Europe; can anyone there
> authoritatively give the year in which their country (or others) started
> using the Last Sunday in Mar/Oct rule, and the year in which their
> country started using a "pan-European" rather than National rule?
In Germany the March/October rule was introduced in 1996 (it was
March/September before since 1981), see also
http://www.ptb.de/en/org/4/43/432/lega.htm and follow the links given
there.
-Michael