Git Product home page Git Product logo

Comments (11)

pavkam avatar pavkam commented on September 4, 2024

Hi Jose,

Thanks for pointing out the Wiki issues. I have replaced the old references to the new ones.

Which version of the TZDB are you using? There is no floating-point math used in the current version for date manipulation.
The only conversion happens from TDateTime to Int64 and back.

The line you provided is pure Int64 math.

Can you give me a bit more details (like exact line number) and the stack trace.

P.S. The unit tests are passing on my latest version of Delphi and on FPC.
Alex.

from tzdb.

atelierw avatar atelierw commented on September 4, 2024

I am using the latest version and the project is the simplest possible. Just a form and a button to call the procedure.
It is very strange indeed, this is the stack trace.

image

I tested in Delphi 10.3.3 and there is no problem. However, the Delphi version I use for programming is XE2 and never felt similar issue. I am also curious.

from tzdb.

pavkam avatar pavkam commented on September 4, 2024

Thanks for screenshot Jose,

There are only 2 functions that deal with actual TDateTime in the code base:

  • DateTimeToPreciseTime,
  • PreciseTimeToDateTime.

Looking at the code in the function, I use a helper function YearOf that calls PreciseTimeToDateTime. All of them are inlined for performance, and that might be throwing off the debugger.

I use RAD Studio 10.3 Community Edition, so I run the code on x86 (I don't have x64 support). Since there are differences how FP operations work between x86 and x64 I wonder if that maybe the case? What platform are you running this on?

You mind removing all inline attributes on the functions in the code and try to step into that function see exactly what line fails? Also what type of FP exception are you receiving?

Thanks,
Alex.

from tzdb.

atelierw avatar atelierw commented on September 4, 2024

I have been investigating and I think the problem is specific to Delphi XE2, but may be you can produce a workaround.

The exception starts here at TZDB:
function YearOf(const APreciseTime: TPreciseTime): Word; //inline;
begin
Result := {$IFDEF DELPHI}System.{$ENDIF}DateUtils.YearOf(PreciseTimeToDateTime(APreciseTime));
end;

when it calls System.DateUtils.YearOf:
function YearOf(const AValue: TDateTime): Word;
var
LMonth, LDay: Word;
begin
DecodeDate(AValue, Result, LMonth, LDay);
end;

which calls:
procedure DecodeDate(const DateTime: TDateTime; var Year, Month, Day: Word);
var
Dummy: Word;
begin
DecodeDateFully(DateTime, Year, Month, Day, Dummy);
end;

which calls:
function DecodeDateFully(const DateTime: TDateTime; var Year, Month, Day, DOW: Word): Boolean;
const
D1 = 365;
D4 = D1 * 4 + 1;
D100 = D4 * 25 - 1;
D400 = D100 * 4 + 1;
var
Y, M, D, I: Word;
T: Integer;
DayTable: PDayTable;
begin
T := DateTimeToTimeStamp(DateTime).Date;
....
end;

which calls:
function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp;
{$IFDEF PUREPASCAL}
var
LTemp, LTemp2: Int64;
begin
LTemp := Round(DateTime * FMSecsPerDay);
LTemp2 := (LTemp div IMSecsPerDay);
Result.Date := DateDelta + LTemp2;
Result.Time := Abs(LTemp) mod IMSecsPerDay;
end;
{$ELSE !PUREPASCAL}
{$IFDEF X86ASM}
asm
PUSH EBX
{$IFDEF PIC}
PUSH EAX
CALL GetGOT
MOV EBX,EAX
POP EAX
{$ELSE !PIC}
XOR EBX,EBX
{$ENDIF !PIC}
MOV ECX,EAX
FLD DateTime
FMUL [EBX].FMSecsPerDay
SUB ESP,8
FISTP QWORD PTR [ESP]
FWAIT
POP EAX
POP EDX
OR EDX,EDX
JNS @@1
NEG EDX
NEG EAX
SBB EDX,0
DIV [EBX].IMSecsPerDay
NEG EAX
JMP @@2
@@1: DIV [EBX].IMSecsPerDay
@@2: ADD EAX,DateDelta
MOV [ECX].TTimeStamp.Time,EDX
MOV [ECX].TTimeStamp.Date,EAX
// #281569 [vk]
PUSH EAX
CALL ValidateTimeStampDate
POP EAX
//
POP EBX
end;
{$ENDIF X86ASM}
{$ENDIF !PUREPASCAL}

So, the exception is here:
// #281569 [vk]
procedure ValidateTimeStampDate(const TimeStampDate: Integer);
begin
if (TimeStampDate <= 0) then
raise EInvalidOp.Create(SInvalidOp);
end;
because TimeStampDate is not valid.

I hope this will help.

This part:
// #281569 [vk]
PUSH EAX
CALL ValidateTimeStampDate
POP EAX
//
has been removed in later Delphi versions, probably for a reason.

from tzdb.

pavkam avatar pavkam commented on September 4, 2024

You are correct, in XE2 that function uses ValidateTimeStampDate. In my version it does not.

As a test, can you replace the value of CNullDateTime constant to 0 and try again?

from tzdb.

atelierw avatar atelierw commented on September 4, 2024

That works, no exceptions anymore.

I have just another question:
Why is Asia/Tokyo showing: 04-Nov-20 8:02:13 AM
When it is: 05-Nov-20 2:02:13 AM

That is, they are at GMT+9 now.

from tzdb.

pavkam avatar pavkam commented on September 4, 2024

Hi Jose:

var
  LTimeZone: TBundledTimeZone;
  LResult: TDateTime;
begin
  LTimeZone := TBundledTimeZone.Create('Asia/Tokyo');
  LResult := LTimeZone.ToLocalTime(EncodeDateTime(2020, 11, 04, 17, 0, 0, 000));

  CheckEquals(0, CompareDateTime(EncodeDateTime(2020, 11, 05, 2, 0, 0, 000), LResult));
end;

Works as expected. If I flip ToLocalTime with ToUniversalTime then I get your result. You'd be converting local time in Tokyo to UTC which is 9 hours behind.

I am still looking at an appropriate fix for the issue you had btw.

from tzdb.

atelierw avatar atelierw commented on September 4, 2024

Probably, there is a problem with the way we name things.
Current time in Japan is UTC+9, we can confirm from here.
https://24timezones.com/time-zone/utc+9#gref

Where I live, local time is the same as UTC time, except when we are in DTS and it becomes UTC+1.

You have done a great job and I will try again your TZBD some time in the future.
For now, I have solved my problem using the Windows API, and the timezone settings stored in the Registry. I had only 5 cities to handle: Tokyo, Sydney, New York, London and Frankfurt.

from tzdb.

pavkam avatar pavkam commented on September 4, 2024

Hi Jose,
Great that you solved your issue!

I have submitted a tentative fix for your issue to master. If you have time to test it out that would help a lot. I don't have XE2 so it's hard for me to validate.

Thanks,
Alex.

from tzdb.

atelierw avatar atelierw commented on September 4, 2024

Yes, it appears to have fixed it.
Thank you.

from tzdb.

pavkam avatar pavkam commented on September 4, 2024

Thank you Jose,

3a8d6f2

from tzdb.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.