Comments (11)
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
Yes, it appears to have fixed it.
Thank you.
from tzdb.
Thank you Jose,
from tzdb.
Related Issues (20)
- Negative DST biases not properly supported (Dublin). HOT 1
- Support for breakdown with rule-less years. HOT 1
- Remove all pre-Delphi XE and pre-FPC 3 support HOT 1
- Update wiki with new code HOT 1
- Query: Is that "Release Number" really 2019G? HOT 8
- Get rid of TCompiledPeriod and TCompiledRule HOT 1
- Incorrect handling of Pacific/Apia zone in 2010 and 2011 HOT 1
- Incompatible types 'TTimeZone' and 'TBundledTimeZone' HOT 1
- Obsolete data HOT 1
- Please use fully qualified unitname HOT 3
- Issue in ToLocalTime for Stockholm time zone. HOT 1
- New Zealand - ETimeZoneInvalid HOT 2
- Update to version 2020f HOT 2
- C++Builder error compiling - constant expression expected - TZDB requires at least Delphi XE to compile! HOT 3
- ToISO8601Format: missing "T" date-time separator and documentation error HOT 1
- A problem with Argentina /Buenos aires time regime HOT 2
- I needed to convert some date times to one timezone to another, and I found your TZDB project. HOT 1
- Aamiinjimcaale
- ICU Zones compatibility
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tzdb.