将Java中的日期转换为整数,然后再转换为Delphi时间
我有一个服务器设备配置,需要使用UDP更改设备日期配置。服务器用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和
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;