2012-01-03 57 views
6

我有一個服務器設備配置,我需要使用UDP更改裝備日期配置。服務器使用Java編寫,使用Delphi編寫的設備。Java中的轉換日期爲整數,然後轉換爲Delphi時間

因此,數據流是這樣的:

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

的問題是,當我通過的時間爲一個整數,JAVA從1970計算毫秒,和Delphi,秒。我通過日期如下:today.getTime()/1000,但設備理解這是2008年的日期,當我們在2012年。

我可以更改Java代碼,但設備是第三方,我沒有訪問它的源代碼。

Java和Delphi日期解析有什麼區別,允許這種差異?

編輯: 感謝MДΓΓБДLL我發現我被乘以1000,而不是由它劃分,我現在有一個美好的約會,但仍然是錯誤的(2033年被somewhen,現在是2008年)。

+4

我不完全明白。你需要從1970年以來的毫秒到幾秒(自1970年以來?),但是你正乘以1000?毫秒=>秒錶示_divide_除以1000. – 2012-01-03 18:19:11

+3

我不知道Delphi中的任何Date類型是1970年以來的秒數。你確定這是一個Delphi問題嗎? – 2012-01-03 18:27:07

+0

Doh!我的確在擴大而不是分割......但它仍然沒有解決問題,請參閱編輯 – 2012-01-03 18:36:55

回答

4

Unix時間戳與Java中使用的時間戳相同。另一方面,德爾福的TDateTime則基於開始日期爲12:01 AM(18/18/1899)(這是一個COM兼容的事情),所以一些轉換是必要的。這些功能將做到這一點;我還添加了一段快速的測試代碼,以顯示轉換正確的兩種方式。

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; 
+0

對於所有的非殖民地(?我認爲英國人負責這種格式?)誰不知道什麼'12: 01 AM'是..它是'0:01'而不是'12:01';) – Voo 2012-01-03 20:10:49

+0

對於那些使用24小時時間的人來說,它是'0001'或'0:01';如我所說,在12小時(上午/下午)格式它是'上午12:01'。 :) – 2012-01-03 20:15:24

+0

是的,我只是想讓它聽起來更有趣;)但作爲一個與24小時系統一起成長的人,我認爲這值得一提,因爲你不會相信有多少人(至少在德國/奧地利)會直觀地將'12:01 AM'解釋爲'12:01' - 或者在12小時系統中允許大於'12:00'的任何值被允許開始。 – Voo 2012-01-03 20:37:45

6

Delphi的DateUtils單元具有UnixToDateTime()DateTimeToUnix()功能TDateTime和Unix時間戳,其被表示爲秒從Unix時間戳(1970年1月1日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; 

另一方面,Java的Date類基於來自Unix時代的毫秒代替。這是很容易考慮到,雖然:

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; 

或者:

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; 

無論哪種方式:

// 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; 
+0

這不適合我。該函數返回43,000年的TDateTime值。 – TomC 2014-03-03 19:32:43

+0

然後你沒有正確使用它。 – 2014-03-03 22:52:30

+0

請隨時告訴我正確的用法,而不是說我錯誤地使用它。我已經成功地使用了Delphi-OOP使用的SuperObject包中的JavaToDelphiDateTime函數。 – TomC 2014-03-05 23:25:28

3

據我瞭解Java日期基於UTC所以你也有將本地時間轉換爲UTC。 這些函數使用毫秒,使代碼適應您的需求。

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; 
1

從www.progdigy.com獲取JSON superobect包並提取功能JavaToDelphiDateTime和V.V.來自源文件。

更新2014年3月3日:

Progdigy.com不再提供這些文件。從Google獲取文件。下載部分http://code.google.com/p/superobject/downloads/list中的官方1.2.4 ZIP文件可用於2010年,但http://code.google.com/p/superobject/source/browse中的單個文件有更新,直到2012年10月。

必須使用這些更新的文件,因爲在切換到閏年的夏令時時發生的日期時間轉換中存在一個模糊的錯誤。