The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,262 other subscribers

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

4 Responses to “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)”

  1. Miso said

    Hi,
    function

    class function TIso8601.DateFromIso8601(const Value: string): TDate;
    

    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.

  2. […] Heute, 14:51 https://wiert.me/2011/08/18/iso-8601-…ebugging-tool/ Markus […]

  3. 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.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.