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.