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

将Java中的日期转换为整数,然后再转换为Delphi时间,java,delphi,parsing,date,time,Java,Delphi,Parsing,Date,Time,我有一个服务器设备配置,需要使用UDP更改设备日期配置。服务器用Java编写,设备用Delphi编写 因此,数据流如下所示: Java服务器(Java日期)->UDP(整数日期)->Delphi设备(Delphi日期) 问题是,当我将日期作为整数传递时,java计算1970年的毫秒,Delphi计算秒。然后我按如下方式传递日期:today.getTime()/1000,但设备将其理解为2008年的日期,即2012年的日期 我可以更改Java代码,但设备是第三方的,我无法访问它的源代码 Java和

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

因此,数据流如下所示:

Java服务器(Java日期)->UDP(整数日期)->Delphi设备(Delphi日期)

问题是,当我将日期作为整数传递时,java计算1970年的毫秒,Delphi计算秒。然后我按如下方式传递日期:
today.getTime()/1000
,但设备将其理解为2008年的日期,即2012年的日期

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

Java和Delphi数据解析之间存在差异,允许这种差异

编辑:
多亏了MΓΓББLL,我注意到我是在乘以1000,而不是除以它,我现在有了一个更好的日期,但仍然是错误的(2033年的某个时候,现在是2008年)。

Unix时间戳与Java中使用的时间戳相同。另一方面,Delphi的TDateTime基于1899年12月30日上午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;

Delphi的
DateUtils
单元具有
UnixToDateTime()
DateTimeToUnix()
函数,用于在
TDateTime
和Unix时间戳之间进行转换,这些时间戳表示为从Unix纪元开始的秒(1970年1月1日00:00 GMT):

另一方面,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;

据我所知,Java日期基于UTC,因此您还必须将本地时间从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;
从www.progdigy.com获取JSON superobect包,并从源文件中提取函数JavaToDelphiDateTime和v.v

2014年3月3日更新:

Progdigy.com不再提供这些文件。从谷歌获取文件。下载部分中的官方1.2.4 ZIP文件的日期为2010年,但中的单个文件直到2012年10月才有更新


您必须使用这些更新的文件,因为在leapyears中转换为夏令时时时发生了一个模糊的日期时间转换错误。

我不完全理解。你需要从1970年的毫秒到1970年的秒(从1970年开始?),但是你要乘以1000?毫秒=>seconds意味着除以1000。我不知道Delphi中有哪种日期类型是1970年以来的秒。你确定这是德尔菲的问题吗?啊!我确实是在乘法而不是除法。。。但它仍然没有解决问题,请参见edit@Marcus-它是int64;请参见DateUtils中的
UnixToDateTime
函数。过去“在Delphi中”的时间与希腊的其他时间相同对于所有不知道凌晨12:01<代码>是什么的非殖民地居民(“我认为英国人对这种格式负责”)。。是
0:01
不是
12:01
;)对于那些使用24小时制的人来说,这是
0001
0:01
;在12小时(上午/下午)格式中,如我所说,它是
12:01AM
。)是的,我只是想让它听起来更有趣;)但作为一个在24小时制环境中长大的人,我认为这值得一提,因为你不会相信有多少人(至少在德国/奥地利)会直观地将
12:01AM
解释为
12:01
-或者会被难倒,为什么在12小时的时间系统中允许任何大于
12:00
的值。@KenWhite:-1。Unix时间戳从Unix纪元开始以秒表示,而Java时间戳从同一纪元开始以毫秒表示。您的
DateTimeToUnixTime()
函数将
2012年1月3日格林尼治时间下午3:55:44编码为
1325635200
,但在Unix中正确的值是
1325606144
,在Java中正确的值是
1325606144000
UnixTimeToDateTime(1325635200)
然后返回
2012年1月4日00:00:00 GMT
。我刚刚用生成正确值的示例更新了我的答案。在Delphi XE、DateTimeToUnix()和UnixToDateTime()上,您可以从System.DateUtils本机使用。这些函数返回的值为1325606144,对应于2012年1月4日15:55:44,sou您可以使用:YourJavaValue:=DateTimeToUnix(YourDateTimeValue)*1000;这对我不起作用。该函数返回了43000年的TDateTime值。请随时告诉我正确的用法,而不是说我没有正确使用它。我成功地使用了Delphi OOP使用的SuperObject包中的JavaToDelphiDateTime函数。我以前没有考虑秒和毫秒。非常有用。谢谢请注意,UnixToDateTime和DateTimeToUnix都有一个可选的ReturnUTC参数,默认为true。XE2中不存在
ReturnUTC
参数,因此必须是最近添加的。
// 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;
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;