ISO 8601 Date, Time and DateTime in Delphi (was: Simple example to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool)
Posted by jpluimers on 2011/08/18
In the past I wrote about a Simple example to show DateTime.Now in ISO 8601 format on ideone.com | Online C# Compiler & Debugging Tool , using ISO 8601 in batch-files, and how ISO 8601 is used in Google Calendar URLs.
Time to write something about ISO 8601 Date, Time and DateTime and Delphi.
First of all the DateUtils unit contains a bunch of routines (for instance DecodeDateWeek) that understand ISO 8601 week numbers, where:
- Weeks start at Monday
- The first week of a year contains (these are equivalent):
- The first thursday in that year
- Has at least 4 days in that year
- Contains the 4th of January
Otherwise the week containing January 1st is week 52 or 53 of the previous year
ISO 8601 also specifies how to format Dates, Times, DateTimes and durations according to some basic principles.
XML uses ISO 8601 to format Date, Time and DateTime and some other formats as text too.
So it is no wonder that since Delphi 6, it contains a XSBuiltIns unit covering (among other things) ISO 8601 formatting.
Given the many Delphi ISO 8601 relates questions on StackOverflow of which I answered two, and my need for ISO 8601 DateTime conversion for exporting Excel XML, here is are some samples to get started in the unit below (and in this codeplex changeset).
The unit covers Date, Time and DateTime.
You can write similar code for Duration.
Oops, I covered it already in ISO 8601: Delphi way to convert XML date and time to TDateTime and back (via: Stack Overflow)
unit Iso8601Unit;
interface
type
TUtc = class(TObject)
public
class function FromUtc(const Value: TDateTime): TDateTime; static;
class function ToUtc(const Value: TDateTime): TDateTime; static;
class function UtcNow: TDateTime; static;
end;
TToTIso8601 = class(TUtc)
public
class function DateTimeToIso8601(const Value: TDateTime): string; static;
class function DateToIso8601(const Value: TDate): string; static;
class function TimeToIso8601(const Value: TTime): string; static;
class function UtcTimeToIso8601(const Value: TTime): string; static;
end;
TIso8601 = class(TToTIso8601)
public
class function DateFromIso8601(const Value: string): TDate; static;
class function DateTimeFromIso8601(const Value: string): TDateTime; static;
class function TimeFromIso8601(const Value: string): TTime; static;
class function UtcDateTimeToIso8601(const Value: TDateTime): string; static;
end;
implementation
uses
XSBuiltIns,
SysUtils,
IdGlobalProtocols;
class function TIso8601.DateFromIso8601(const Value: string): TDate;
begin
with TXSDate.Create() do
try
XSToNative(value); // convert from WideString
Result := AsDate; // convert to TDate
finally
Free();
end;
end;
class function TIso8601.DateTimeFromIso8601(const Value: string): TDateTime;
begin
with TXSDateTime.Create() do
try
XSToNative(value); // convert from WideString
Result := AsDateTime; // convert to TDateTime
finally
Free();
end;
end;
class function TIso8601.TimeFromIso8601(const Value: string): TTime;
begin
with TXSTime.Create() do
try
XSToNative(value); // convert from WideString
Result := AsTime; // convert to TTime
finally
Free();
end;
end;
class function TIso8601.UtcDateTimeToIso8601(const Value: TDateTime): string;
begin
with TXSDateTime.Create() do
try
AsUTCDateTime := Value;
Result := NativeToXS; // convert to WideString
finally
Free();
end;
end;
class function TUtc.FromUtc(const Value: TDateTime): TDateTime;
var
Bias: TDateTime;
begin
Bias := TimeZoneBias;
Result := Value - TimeZoneBias;
end;
class function TUtc.ToUtc(const Value: TDateTime): TDateTime;
var
Bias: TDateTime;
begin
Bias := TimeZoneBias;
Result := Value + TimeZoneBias;
end;
class function TUtc.UtcNow: TDateTime;
begin
Result := ToUtc(Now);
end;
class function TToTIso8601.DateTimeToIso8601(const Value: TDateTime): string;
begin
with TXSDateTime.Create() do
try
AsDateTime := Value; // convert from TDateTime
Result := NativeToXS; // convert to WideString
finally
Free();
end;
end;
class function TToTIso8601.DateToIso8601(const Value: TDate): string;
begin
with TXSDate.Create() do
try
AsDate := Value; // convert from TDate
Result := NativeToXS; // convert to WideString
finally
Free();
end;
end;
class function TToTIso8601.TimeToIso8601(const Value: TTime): string;
begin
with TXSTime.Create() do
try
AsTime := Value; // convert from TTime
Result := NativeToXS; // convert to WideString
finally
Free();
end;
end;
class function TToTIso8601.UtcTimeToIso8601(const Value: TTime): string;
begin
with TXSTime.Create() do
try
AsTime := ToUtc(Value);
Result := NativeToXS; // convert to WideString
finally
Free();
end;
end;
end.
–jeroen






Miso said
Hi,
function
doesn´t work corectly, anyway. In XE function TXSDate.ToDate within uses TryEncodeDatefrom SysUtils unit. Problem is with parameters Day and Month of TryEncodeDate method, that must be >=1, but ISO8601 standard allows YYYY-MM or YYYY format.
jpluimers said
do you have a reproducible test case for this?
datumsformat - Delphi-PRAXiS said
[…] Heute, 14:51 https://wiert.me/2011/08/18/iso-8601-…ebugging-tool/ Markus […]
LDS said
AFAIK Delphi uses automatically ISO date encoding only in its web services implemetation. TXMLDoc code is not smart enough to convert TDateTime values in ISO date formats, it will happily write double values using your regional settings.