Soap.XSBuiltIns.XMLTimeToDateTime转换

时间:2014-01-23 21:49:10

标签: delphi delphi-xe3

我正在使用XMLTimeToDateTime作为JSON中datetime字段的时间转换函数。我看到这个功能意外转换。它似乎尝试将某种UTC时间用于本地时间转换,即使你告诉它不要。

这是一些测试代码(在DUnit中):

uses
  System.SysUtils,
  Soap.XSBuiltIns,
  System.DateUtils;

procedure TestXMLTimeConversion.TestXMLTimeToDateTime;
var
  ReturnValue: TDateTime;
  testDate: TDateTime;
begin
  testDate := EncodeDateTime(2014, 3, 2, 3, 12, 45, 0);
  ReturnValue := XMLTimeToDateTime('2014-03-02T03:12:45', False);
  CheckEquals(testDate, ReturnValue, 'ReturnValue: ' + FormatDateTime('yyyy-mm-dd"T"hh:nn:ss', ReturnValue));
end;

返回

ReturnValue: 2014-03-02T04:12:45, expected: <41700,1338541667> but was: <41700,1755208333>

如果将XMLTimeToDateTime的布尔参数更改为True,则转换将变为正确。我原本预计会出现相反的情况。我在这里误解了什么吗?

编辑:

我挖了一下,我相信我找到了原因。根据我在互联网上找到的varius ISO8601配置文件的规范,其中一个是this one from W3,似乎系统可能希望时区指示在指定时间戳时始终可用。

如果您将时区指示附加到测试用例,它会计算正确的时间(在这种情况下,我会调整为CET)。

procedure TestTXSDateTime.TestXMLTimeToDateTimeWithTimeZone;
var
  ReturnValue: TDateTime;
  testDate: TDateTime;
begin
  testDate := EncodeDateTime(2014, 3, 2, 3, 12, 45, 0);
  ReturnValue := XMLTimeToDateTime('2014-03-02T03:12:45+01:00', False);
  CheckEquals(testDate, ReturnValue, 'ReturnValue: ' + FormatDateTime('yyyy-mm-dd"T"hh:nn:ss', ReturnValue));
end;

这样就没有指定时间戳。这应该是合法的,我希望这会导致datetime值的分数设置为0,无论你在哪个时区。

procedure TestTXSDateTime.TestXMLDateToDateTime;
var
  ReturnValue: TDateTime;
  testDate: TDateTime;
begin
  testDate := EncodeDateTime(2014, 3, 2, 0, 0, 0, 0);
  ReturnValue := XMLTimeToDateTime('2014-03-02', False);
  CheckEquals(testDate, ReturnValue, 'ReturnValue: ' + FormatDateTime('yyyy-mm-dd"T"hh:nn:ss', ReturnValue));
end;

然而,在这种情况下,XMLTimeToDateTime仍会针对本地偏差进行调整,在我看来这是一个错误。如果您居住在美国或其他任何落后于UTC的地方,则意味着您获得的TDateTime值的日期部分对应于实际给出的前一天。

0 个答案:

没有答案