Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将ISO 8601字符串转换为Delphi TDate?_Delphi_Iso8601 - Fatal编程技术网

如何将ISO 8601字符串转换为Delphi TDate?

如何将ISO 8601字符串转换为Delphi TDate?,delphi,iso8601,Delphi,Iso8601,我可以使用以下方法轻松地将Delphi TDate转换为ISO 8601格式: DateTimeToString(result, 'yyyy-mm-dd', myDate); 进行逆转换的惯用方法是什么StringToDateTime()似乎不存在 显然,我可以通过手动解析字符串并对结果进行编码来“艰难”地完成这项工作,但这似乎是一个糟糕的选择。我认为这应该是可行的。。。文档中说,这些方法的重载版本可用于线程,但它可以方便地指定您希望在当时使用的格式设置 Function ISO8601ToD

我可以使用以下方法轻松地将Delphi TDate转换为ISO 8601格式:

DateTimeToString(result, 'yyyy-mm-dd', myDate);
进行逆转换的惯用方法是什么<代码>StringToDateTime()似乎不存在


显然,我可以通过手动解析字符串并对结果进行编码来“艰难”地完成这项工作,但这似乎是一个糟糕的选择。

我认为这应该是可行的。。。文档中说,这些方法的重载版本可用于线程,但它可以方便地指定您希望在当时使用的格式设置

Function ISO8601ToDateTime(Value: String):TDateTime;
var
    FormatSettings: TFormatSettings;
begin
    GetLocaleFormatSettings(GetThreadLocale, FormatSettings);
    FormatSettings.DateSeparator := '-';
    FormatSettings.ShortDateFormat := 'yyyy-MM-dd';
    Result := StrToDate(Value, FormatSettings);
end;

当然,您可以使用StrToDateDef和TryStrToDate编写具有等效功能的变体

您可以在我们的中找到Iso-8601转换例程

它已针对速度进行了深入优化,因此比DateTimeToString()函数等快得多,但当然,代码更难理解。;)

过程Iso8601ToDateTimePUTF8CharVar(P:PUTF8Char;L:integer;var结果:TDateTime);
varⅠ:整数;
B:红衣主教;
Y、 M,D,H,MI,SS:红衣主教;
//我们需要'YYYYMMDDThhmmss'格式,但我们也处理'YYYY-MM-DD hh:MM:ss'
开始
结果:=0;
如果P=nil,则
出口
如果L=0,则
L:=StrLen(P);
如果是L9,则退出else Y:=B;//快速检查“0”…“9”
对于i:=1到3,开始
B:=托宾[ord(P[i])];//3其他数字
如果B>9,则退出其他Y:=Y*10+B;
结束;
如果P[4]在['-','/']中,则开始inc(P);12月(L);完允许YYYY-MM-DD
D:=1;
如果L>=6,则开始//YYYYMM
M:=ord(P[4])*10+ord(P[5])-(48+480);
如果(M=0)或(M>12),则退出;
如果P[6]在['-','/']中,则开始inc(P);12月(L);完允许YYYY-MM-DD
如果L>=8,则开始//YYYYMMDD
D:=ord(P[6])*10+ord(P[7])-(48+480);
如果(D=0)或(D>MonthDays[true][M]),则退出;//闰年更糟=正确
结束;
结束其他
M:=1;
如果M>2,则//内联编码日期(Y,M,D)
12月(月3日)其他
如果M>0,则开始
公司(M,9),;
12月(Y);
结束;
用Div100(Y)do
结果:=(146097*YDiv100)shr 2+(1461*YMod100)shr 2+
(153*M+2)第5+D-693900分区;

如果(L*P>为了更灵活,你可以考虑用任何格式处理字符串的:

var
  D: TDateTime;
begin
  D := ScanDate('yyyy-mm-dd', '2011-07-11');

参见添加到FPC中的(7kB.zip)。

为什么要重新发明轮子

XML使用ISO8601进行日期和日期时间存储

自单元中的Delphi 6以来,Delphi已经内置了对此的支持

对于DateTime,这仅适用于使用类的日期:


Delphi XE3

从XE8开始,从
dateutils.pas
使用
ISO8601ToDate
(和
DateToISO8601


从XE6开始,您可以使用function
System.DateUtils.ISO8601ToDate

uses
  System.DateUtils;
var
  vDat: TDateTime;
begin
  vDat := ISO8601ToDate('2018-03-26T11:01:35.867Z');
end.

很典型。反正我正在使用synapse,但从未意识到其中包括:-)但这个函数并不完全符合ISO8601标准。规范要求使用“T”作为日期和时间字符串之间的分隔符。只有在双方同意的情况下才允许省略。其次,不支持字符串末尾的时区指示,这是许多Web服务所必需的。您可能还需要使用系统默认值初始化formatsettings。取决于您是否将其用于解析日期以外的其他内容:
GetLocaleFormatSettings(LOCALE\u SYSTEM\u默认值,FormatSettings)用系统默认值填充FormatSettings记录。@Roald,谢谢。。我只是对它做了几个测试!我会马上更新它。一定要使用“线程安全”重载版本,否则如果使用DateToStr,或者使用带有“c”或“ddddd”的FormatDateTime,或者任何其他使用ShortDateFormat的格式,您的应用程序显示日期的方式就会改变。英文定语不等于荷兰语的“definitief”。在这种情况下,最好将荷兰语的“确定版本”翻译为“最终版本”。“最终版本”更类似于说“最终”版本。。。再说一遍,也许你的意思是:-)总是乐于帮助一个国家(wo)最后一行的意思是“从XE6向上”吗?此外,请参见。使用XSBuiltins;XMLTimeToDateTime(str,True);-也行,说得好。这在Delphi 7及更高版本中有效。但是请注意,它在内部使用与上面代码相同的
TXSDateTime
,因此它也包括时间部分。
with TXSDate.Create() do
  try
    AsDate := Date; // convert from TDateTime
    DateString := NativeToXS; // convert to WideString
  finally
    Free;
  end;

with TXSDate.Create() do
  try
    XSToNative(DateString); // convert from WideString
    Date := AsDate; // convert to TDateTime
  finally
    Free;
  end;
USES Soap.XSBuiltIns;
...
Function XMLDateTimeToLocalDateTime(const Value: String): TDateTime;
begin
  with TXSDateTime.Create do
  try
    XSToNative(Value);
    result := AsDateTime;
  finally
    Free;
  end;
end;
uses
  System.DateUtils;
var
  vDat: TDateTime;
begin
  vDat := ISO8601ToDate('2018-03-26T11:01:35.867Z');
end.