将Java中的转换日期转换为整数然后转换为Delphi时间

时间:2012-01-03 18:13:22

标签: java delphi parsing date time

我有一个服务器设备配置,我需要使用UDP更改装备日期配置。服务器是用Java和设备编写的,用Delphi编写。

因此,数据流是这样的:

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

问题在于,当我将日期作为整数传递时,java计算1970年的毫秒数和德尔福数秒。我通过了以下日期:today.getTime() / 1000,但设备将此理解为2008年的日期,当我们在2012年。

我可以更改Java代码,但设备是第三方,我无法访问它的源代码。

Java和Delphi日期解析之间存在差异吗?

修改 感谢MДΓΓБДLL,我注意到我乘以1000而不是除以它,我现在有一个更好的约会,但仍然是错的(在2033年是某种情况,现在是在2008年)。

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:5)

Unix时间戳与Java中使用的时间戳相同。另一方面,Delphi的TDateTime基于18/22/18上午12:01的开始日期(它是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;

答案 2 :(得分: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;

答案 3 :(得分: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月。

必须使用这些更新的文件,因为在切换到suapyears的夏令时时,日期时间转换中出现了一个模糊的错误。