我需要通过AJAX发送一个delphi服务器的日期,该服务器接受float格式的日期并设置一个TDateTime属性。

例如。

var
   date: TDateTime;
begin
   date := StrToFloat(Request.QueryFields.Values['date']);
end;


Delphi TDateTime从1989年12月30日开始,我已经测试过:

var
   date: TDateTime;
begin
   date := StrToFloat('0');
   ShowMessage( DateTimeToStr(date) ); // show: 30/12/1899
end;


JavaScript日期从Unix时代开始,我已经测试过:

console.log(new Date(0)); // Thu Jan 01 1970 01:00:00 GMT+0100


一个简单的转换似乎会减去差异,但不起作用,例如:

// javascipt
var delphiTime = (new Date("07-24-2019") - new Date("12-30-1899")) / 1000;
console.log(delphiTime ); // 3773084400


// delphi
ShowMessage( DateTimeToStr(3773084400) ); // show 00/00/00


奇怪的事实是,在delphi上,Now是43670.654378:

ShowMessage( FloatToStr(Now) ); // 43670.654378


在delphi中0是1899,43670是2019 ...

Delphi中的日期格式如何工作以及如何使用数学将Unix日期转换为Delphi日期?

旁注:我无法修改服务器,我需要使用JavaScript解决客户端问题

更新:

在Delphi中,浮点值= 1将是31.12.1899,2 = 01.01.1900,依此类推。每个单元似乎一天。

function jsDateToDelphiDate(date){
  const seconds = (new Date(date).getTime() - new Date("12-30-1899").getTime()) / 1000;
  const days = seconds / 60 / 60 / 24;
  return days;
}

console.log(jsDateToDelphiDate(new Date("07-24-2019 16:00:00"))); // 43670.625


delphi上的43670.62523/07/2019 15:00

为什么我会损失1个小时?

最佳答案

如何在Delphi中使用日期格式


这在Embarcadero's DocWiki上有完整记录:

System.TDateTime


  TDateTime类继承了一个val数据成员(声明为double成员),该成员保留日期时间值。 TDateTime值的整数部分是自1899年12月30日以来经过的天数。TDateTime值的小数部分是一天中的时间。
  
  ...
  
  下表显示了TDateTime值及其对应的日期和时间的示例:

Value     Description
0         December 30, 1899; 12:00 A.M.
2.75      January 1, 1900; 6:00 P.M.
-1.25     December 29, 1899; 6:00 A.M.
35065     January 1, 1996; 12:00 A.M.

A Unix date/time is represented as the number of seconds since January 1 1970 00:00:00 UTC. Delphi has a UnixDateDelta constant in the SysUtils unit which is defined as 25569, the number of days from December 31 1899 to January 1 1970. So, a TDateTime value of 25569.0 exactly represents January 1 1970 00:00:00 (UTC vs local is up to you to decide when creating a TDateTime). You can then add seconds to that value to get the final TDateTime value for any Unix date/time.

In a TDateTime, you can add whole days to the integral portion (ie, Unix + 1 day = 25569.0 + 1 = 25570.0), but adding seconds within a day is slightly more work, as seconds are not represented as-is in TDateTime, as you can see in the table above. 0.25 is 6:00 AM (21600 seconds after midnight) and 0.75 is 6:00 PM (64800 seconds after midnight). So seconds are represented in TDateTime as a fraction with 86400 (the number of seconds in a day) as the denominator.

A JavaScript Date object is represented as the number of milliseconds since midnight on January 1 1970. You can divide a Date value by 1000 to get whole seconds, and divide that value by 86400 to get whole days and fractional seconds, which you can then add to 25569.0 to produce a TDateTime value.

function jsDateToDelphiDate(dateToConvert){
  const UnixDateDelta = 25569.0;
  const SecsPerDay = 86400;
  const MSecsPerSec = 1000;
  var UnixSeconds = dateToConvert.getTime() / MSecsPerSec; // 1563984000
  var SecsToAdd = UnixSeconds / SecsPerDay; // 18101.666666666668
  return UnixDateDelta + SecsToAdd;
}

// don't forget to force UTC, or else the Date value
// will be skewed by the local timezone offset...
console.log(jsDateToDelphiDate(new Date("2019-07-24T16:00:00Z"))); // 43670.66666666667
console.log(jsDateToDelphiDate(new Date(Date.UTC(2019, 6, 24, 16, 0, 0)))); // 43670.66666666667


Delphi在UnixToDateTime()单元中具有DateUtils函数,该函数可以为您执行此计算。因此,如果可以更改AJAX代码以将Unix时间戳原样传递给Delphi,则可以让Delphi计算合适的TDateTime

注意,在此示例中,结果TDateTime值以UTC为单位。通过AJAX将值传输到Delphi后,如果您的Delphi代码在本地时间需要TDateTime,这是一种基于本地计算机的时区偏移量(以分钟为单位)调整TDateTime的简单计算,您可以使用平台API来获取,例如Windows上的GetTimeZoneInformation()等。Delphi在IncMinute()单元中具有DateUtils函数,您可以使用该函数进行调整。

关于javascript - JavaScript日期为Delphi TDateTime,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57184472/

10-09 16:57