Convert date in Java to integer and then in Delphi Time

I have a server hardware configuration where I need to change the equipment date configuration using UDP. The server is written in Java and hardware in Delphi.

So the data stream is this:

Java server (Java date) -> UDP (integer date) -> Delphi equipment (Delphi date)

The problem is that when I pass the date as an integer, java calculates milliseconds since 1970 and Delphi, seconds. Then I pass in the following date: today.getTime() / 1000 , but the equipment understands this as the date of 2008, when we are in 2012.

I can change the Java code, but the equipment is third-party, and I do not have access to its source code.

Difference between Java date parsing and Delphi allowing this mismatch?

EDIT: Thanks to the MDGΓ BDLL, I noticed that I multiplied by 1000 instead of dividing by it, now I have a better date, but still incorrect (it was in 2033, now it is in 2008).

+6
source share
4 answers

The Unix timestamp is the same as that used in Java. Delphi TDateTime, on the other hand, is based on a starting date of 12:01 AM 12/30/1899 (this is COM compatibility), so some conversion is necessary. These functions will do this; I also added a quick piece of test code to show that the conversion works correctly in both directions.

 const UnixStartDate = 25569.0; function DateTimeToUnixTime(const ADateTime: TDateTime): Cardinal; begin Result := Round(ADateTime - UnixStartDate) * 86400; end; function UnixTimeToDateTime(const UnixDate: Cardinal): TDateTime; begin Result := UnixDate / 86400 + UnixStartDate; end; procedure TForm1.Button1Click(Sender: TObject); var StartDate: TDateTime; UnixDate: Cardinal; begin StartDate := Date(); Memo1.Lines.Add('Start Date: ' + DateToStr(StartDate)); UnixDate := DateTimeToUnixTime(StartDate); Memo1.Lines.Add('DateTimeToUnixTime = ' + IntToStr(UnixDate)); Memo1.Lines.Add('UnixTimeToDateTime = ' + DateToStr(UnixTimeToDateTime(UnixDate))); end; 
+4
source

Delphi DateUtils has the UnixToDateTime() and DateTimeToUnix() functions for converting between TDateTime and Unix marks, which are expressed as seconds from the Unix era (January 1, 1970 00:00) .: 00 GMT):

 // 1325606144 = Jan 3 2012 3:55:44 PM GMT uses DateUtils; var DT: TDateTime; Unix: Int64; begin DT := UnixToDateTime(1325606144); // returns Jan 3 2012 3:55:44 PM Unix := DateTimeToUnix(EncodeDate(2012, 1, 3) + EncodeTime(15, 55, 44, 0)); // returns 1325606144 end; 

The Java Date class, on the other hand, is based on milliseconds since the Unix era . This is easy to take into account:

 uses DateUtils; function JavaToDateTime(Value: Int64): TDateTime; begin Result := UnixToDateTime(Value div 1000); end; function DateTimeToJava(const Value: TDateTime): Int64; begin Result := DateTimeToUnix(Value) * 1000; end; 

As an alternative:

 uses SysUtils, DateUtils; // UnixDateDelta is defined in SysUtils... function JavaToDateTime(Value: Int64): TDateTime; begin Result := IncMilliSecond(UnixDateDelta, Value); end; function DateTimeToJava(const Value: TDateTime): Int64; begin Result := MilliSecondsBetween(UnixDateDelta, Value); if Value < UnixDateDelta then Result := -Result; end; 

Anyway:

 // 1325606144000 = Jan 3 2012 3:55:44 PM GMT var DT: TDateTime; Java: Int64; begin DT := JavaToDateTime(1325606144000); // returns Jan 3 2012 3:55:44 PM Java := DateTimeToJava(EncodeDate(2012, 1, 3) + EncodeTime(15, 55, 44, 0)); // returns 1325606144000 end; 
+6
source

As far as I know, Java date is based on UTC, so you also need to convert local time from / to UTC. These functions use milliseconds, adapt the code to your needs.

 function TzSpecificLocalTimeToSystemTime( lpTimeZoneInformation: PTimeZoneInformation; lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; function SystemTimeToTzSpecificLocalTime( lpTimeZoneInformation: PTimeZoneInformation; lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll'; function JavaToDelphiDateTime(const dt: int64): TDateTime; var t: TSystemTime; begin DateTimeToSystemTime(25569 + (dt / 86400000), t); SystemTimeToTzSpecificLocalTime(nil, @t, @t); Result := SystemTimeToDateTime(t); end; function DelphiToJavaDateTime(const dt: TDateTime): int64; var t: TSystemTime; begin DateTimeToSystemTime(dt, t); TzSpecificLocalTimeToSystemTime(nil, @t, @t); Result := Round((SystemTimeToDateTime(t) - 25569) * 86400000) end; 
+3
source

Get the package of JSON superobjects from www.progdigy.com and extract the JavaToDelphiDateTime and vv functions from the source files.

Updated March 3, 2014:

Progdigy.com no longer serves these files. Get files from Google. The official ZIP 1.2.4 file in the http://code.google.com/p/superobject/downloads/list download section dates from 2010, but the individual files in http://code.google.com/p/superobject/source/ browse updated to October 2012.

You should use these updated files because an unclear error occurred in the datetime conversions occurring around the switch to daylight saving time in leapyears.

+1
source

Source: https://habr.com/ru/post/905008/


All Articles