Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-07

New functions for time zone

9 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

LacaK

Hi *,
I noticed, that there was just added new functions for supporting TZ in rev. 21865 and 21866
Now function GetLocalTimeOffset: Integer returns offset *in minutes* and later in functions LocalTimeToUniversal and UniversalTimeToLocal are used commands to transform it to TDateTime using EncodeTime. (f.e. EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0))

My idea is change function GetLocalTimeOffset: TDateTime to return TDateTime (offset in fraction of days - native FPC datetime format) i.e. current implementation + "Result := Result / MinsPerDay" I think, that it will be useful, because in real applications we will need on each usage transform minutes to use it in Datetime calculations. (LocalDateTime := UTCDateTime - GetLocalTimeOffset;)

Then functions LocalTimeToUniversal and UniversalTimeToLocal will be
simple addition or subtraction like:
function UniversalTimeToLocal(UT: TDateTime; TZOffset : TDateTime):
TDateTime;
begin
   Result := UT - TZOffset;
end;

What do you think? It will simplify all.

TIA
-Laco.

Reply by email

Mark Morgan Lloyd
to LacaK
LacaK wrote 22 lines
Hi *, I noticed, that there was just added new functions for supporting TZ in rev. 21865 and 21866 Now function GetLocalTimeOffset: Integer returns offset *in minutes* and later in functions LocalTimeToUniversal and UniversalTimeToLocal are used commands to transform it to TDateTime using EncodeTime. (f.e. EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)) My idea is change function GetLocalTimeOffset: TDateTime to return TDateTime (offset in fraction of days - native FPC datetime format) i.e. current implementation + "Result := Result / MinsPerDay" I think, that it will be useful, because in real applications we will need on each usage transform minutes to use it in Datetime calculations. (LocalDateTime := UTCDateTime - GetLocalTimeOffset;) Then functions LocalTimeToUniversal and UniversalTimeToLocal will be simple addition or subtraction like: function UniversalTimeToLocal(UT: TDateTime; TZOffset : TDateTime): TDateTime; begin Result := UT - TZOffset; end;

Are there already cases where a TDateTime is used as an interval rather than for its original purpose? If not then I'd suggest that a new type is in order, taking a leaf from the book of at least some SQL implementations which have distinct timestamp and interval types.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Michael Van Canneyt
to LacaK: I noticed, that there was just added new functions for supporting TZ in rev. 21865 and…
LacaK wrote 24 lines
Hi *, I noticed, that there was just added new functions for supporting TZ in rev. 21865 and 21866 Now function GetLocalTimeOffset: Integer returns offset *in minutes* and later in functions LocalTimeToUniversal and UniversalTimeToLocal are used commands to transform it to TDateTime using EncodeTime. (f.e. EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)) My idea is change function GetLocalTimeOffset: TDateTime to return TDateTime (offset in fraction of days - native FPC datetime format) i.e. current implementation + "Result := Result / MinsPerDay" I think, that it will be useful, because in real applications we will need on each usage transform minutes to use it in Datetime calculations. (LocalDateTime := UTCDateTime - GetLocalTimeOffset;) Then functions LocalTimeToUniversal and UniversalTimeToLocal will be simple addition or subtraction like: function UniversalTimeToLocal(UT: TDateTime; TZOffset : TDateTime): TDateTime; begin Result := UT - TZOffset; end; What do you think? It will simplify all.

There are 2 sides to this medal. The function returns a number of timezones; This is usually expressed as a number of hours and minutes (the OS returns it so). The result is in 'natural' units.

Returning it as a timestamp - while useful by itself - seems rather odd.

I'm also not quite sure what should be returned for negative values of the timezone info. 'today 23:00' or "Yesterday 23:00"

I think it should remain as it is, but if you want, we can create an extra function 'LocalTimeOffset' in DateUtils that returns the same thing as a TDateTime. This new function can then be used in conversion routines.

Michael.

Reply by email

José Mejuto
to Michael Van Canneyt

Hello FPC,

Wednesday, July 11, 2012, 3:09:41 PM, you wrote:

MVC> There are 2 sides to this medal. The function returns a number of timezones; MVC> This is usually expressed as a number of hours and minutes (the OS returns MVC> it so). The result is in 'natural' units.
MVC> Returning it as a timestamp - while useful by itself - seems rather odd.

Returning it as a timestamp is nonsense, instead return a double representing the day fraction, so 2 hours = 2 / 86400.

MVC> I'm also not quite sure what should be returned for MVC> negative values of the timezone info.
MVC> 'today 23:00' or "Yesterday 23:00"
MVC> I think it should remain as it is, but if you want, we can create an extra MVC> function 'LocalTimeOffset' in DateUtils that returns the same thing as a MVC> TDateTime. This new function can then be used in conversion routines.

Anyway the functions are nonsense as they accept a parameter for date to be converted, and as noted in the bug report the functions must only work over Now or NowUTC (or alike). IMHO is quite dangerous to keep this functions as they are now in the base units, as the names suggest that they will correctly convert any time UTC to a local time or viceversa, so at least rename the function "GetLocalTimeOffset" to "GetCurrentLocalTimeOffset" to note the "current" verb.

In the other hand this functions are not for local<->universal time conversions, they displace times, calculate offsets and apply them, in fact one function changing the sign of the offset will give the same result as the other function.

As usual, this is just my opinion only...

Best regards, José

Reply by email

Michael Van Canneyt
to José Mejuto
José Mejuto wrote 21 lines
Hello FPC, Wednesday, July 11, 2012, 3:09:41 PM, you wrote: MVC> There are 2 sides to this medal. The function returns a number of timezones; MVC> This is usually expressed as a number of hours and minutes (the OS returns MVC> it so). The result is in 'natural' units. MVC> Returning it as a timestamp - while useful by itself - seems rather odd. Returning it as a timestamp is nonsense, instead return a double representing the day fraction, so 2 hours = 2 / 86400. MVC> I'm also not quite sure what should be returned for MVC> negative values of the timezone info. MVC> 'today 23:00' or "Yesterday 23:00" MVC> I think it should remain as it is, but if you want, we can create an extra MVC> function 'LocalTimeOffset' in DateUtils that returns the same thing as a MVC> TDateTime. This new function can then be used in conversion routines. Anyway the functions are nonsense as they accept a parameter for date to be converted.

Not if they have the TZOffset parameter as well.

Without this information they are indeed nonsense. That is why I added the parameter.

If someone does not supply it, the current one will be taken;
it is simply meant for current time operations.

The behaviour will be documented, and there will be a remark about the TZ info being time dependent. If someone doesn't know what he is doing, that's his problem.

Michael.

Reply by email

José Mejuto
to Michael Van Canneyt

Hello FPC,

you wrote
> Anyway the functions are nonsense as they accept a parameter for date > to be converted.

MVC> Not if they have the TZOffset parameter as well. MVC> Without this information they are indeed nonsense. MVC> That is why I added the parameter.

Well, I undertand it, I was only trying to note that this code:

A:=Now;
B:=GetLocalTimeOffSet;
C:=LocalTimeToUniversal(A,B);

Will not return correct result in some mini-mili-microseconds slices two times a year, and as more time passes between the assignements of A and B (using a time field in databases, it could be days, years, months...) the chances of a wrong conversion will raise a lot.

MVC> If someone does not supply it, the current one will be taken; MVC> it is simply meant for current time operations. MVC> The behaviour will be documented, and there will be a MVC> remark about the TZ info being time dependent. MVC> If someone doesn't know what he is doing, that's his problem.

Sure :) I had bitten that stone in the past ;)

Best regards, José

Reply by email

Michael Van Canneyt
to José Mejuto
José Mejuto wrote 20 lines
Hello FPC, Wednesday, July 11, 2012, 4:38:19 PM, you wrote: >> Anyway the functions are nonsense as they accept a parameter for date >> to be converted. MVC> Not if they have the TZOffset parameter as well. MVC> Without this information they are indeed nonsense. MVC> That is why I added the parameter. Well, I undertand it, I was only trying to note that this code: A:=Now; B:=GetLocalTimeOffSet; C:=LocalTimeToUniversal(A,B); Will not return correct result in some mini-mili-microseconds slices two times a year, and as more time passes between the assignements of A and B (using a time field in databases, it could be days, years, months...) the chances of a wrong conversion will raise a lot.

This is correct, but unavoidable without a huge implementation like TZPascal...

Even 'Now' itself is not 100% correct, since lots of computations are still done after the time was gotten from the OS...

Michael.

Reply by email

José Mejuto
to Michael Van Canneyt

Hello FPC,

you wrote 7 lines
> A:=Now; > B:=GetLocalTimeOffSet; > C:=LocalTimeToUniversal(A,B); > Will not return correct result in some mini-mili-microseconds slices > two times a year, and as more time passes between the assignements of > A and B (using a time field in databases, it could be days, years, > months...) the chances of a wrong conversion will raise a lot.

MVC> This is correct, but unavoidable without a huge MVC> implementation like TZPascal...

That's completly overkill.

MVC> Even 'Now' itself is not 100% correct, since lots of computations are still MVC> done after the time was gotten from the OS...

I think thew word here is "precise", now is not 100% precise, but it is correct as it can describe a given moment in time, you know, the most precise clock is the stopped one, it returns a 100% accurate time 2 times each day :)

Best regards, José

Reply by email

LacaK
to Michael Van Canneyt: There are 2 sides to this medal. The function returns a number of timezones; This is…

Michael Van Canneyt wrote / napísal(a):

Show quoted text 34 lines
On Wed, 11 Jul 2012, LacaK wrote: > Hi *, > I noticed, that there was just added new functions for supporting TZ > in rev. 21865 and 21866 > Now function GetLocalTimeOffset: Integer returns offset *in minutes* > and later in functions LocalTimeToUniversal and UniversalTimeToLocal > are used commands to transform it to TDateTime using EncodeTime. > (f.e. EncodeTime(TZOffset div 60, TZOffset mod 60, 0, 0)) > > My idea is change function GetLocalTimeOffset: TDateTime to return > TDateTime (offset in fraction of days - native FPC datetime format) > i.e. current implementation + "Result := Result / MinsPerDay" > I think, that it will be useful, because in real applications we will > need on each usage transform minutes to use it in Datetime calculations. > (LocalDateTime := UTCDateTime - GetLocalTimeOffset;) > > Then functions LocalTimeToUniversal and UniversalTimeToLocal will be > simple addition or subtraction like: > function UniversalTimeToLocal(UT: TDateTime; TZOffset : TDateTime): > TDateTime; > begin > Result := UT - TZOffset; > end; > > What do you think? It will simplify all. There are 2 sides to this medal. The function returns a number of timezones; This is usually expressed as a number of hours and minutes (the OS returns it so). The result is in 'natural' units.

AFAIK f.e. GetTimeZoneInformation under Windows return bias in minutes

Returning it as a timestamp - while useful by itself - seems rather odd.

May be, that I expressed it wrong

My proposal is like:

Windows:
     function GetLocalTimeOffset: double;   <--
591
592            var
593              TZInfo: TTimeZoneInformation;
594
595            begin
596               case GetTimeZoneInformation(TZInfo) of
597                 TIME_ZONE_ID_UNKNOWN:
598                   Result := TZInfo.Bias;
599                 TIME_ZONE_ID_STANDARD:
600                   Result := TZInfo.Bias + TZInfo.StandardBias;
601                 TIME_ZONE_ID_DAYLIGHT:
602                   Result := TZInfo.Bias + TZInfo.DaylightBias;
603                 else
604                   Result := 0;
605               end;
+                 Result := Result / MinsPerDay;
606            end;
Unix:
                function GetLocalTimeOffset: double;   <--
1405
1406            begin
+                  Result := -Tzseconds / SecsPerDay;
1408            end;
dateutil.inc:
function UniversalTimeToLocal(UT: TDateTime; TZOffset : double): TDateTime;
2467
2468            begin
                    Result := UT - TZOffset;
2476            end;
Function LocalTimeToUniversal(LT: TDateTime;TZOffset: double): TDateTime;
2485
2486            begin
                   Result := LT + TZOffset;
2494            end;

if TZOffset will be "day fraction" then we can simplyfy above mentioned functions, or am I wrong ?
Thanks
-Laco.

Reply by email