View Issue Details

IDProjectCategoryView StatusLast Update
0035544FPCRTLpublic2019-05-12 10:06
ReporterOndrej PokornyAssigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version3.3.1Product Build 
Target VersionFixed in Version3.3.1 
Summary0035544: TryISO8601ToDate: support short time zone designators
DescriptionAccording to the ISO norm, the short time zone designators are also valid:
+0000
+00

https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators

The attached patch adds support for them. (Currently only the +00:00 format is supported.)
Steps To ReproduceTest project:

program ISODate;
uses
  SysUtils, DateUtils;
var
  D1, D2, D3: TDateTime;
begin
  if TryISO8601ToDate('2019-01-01T10:00:00+04', True, D1)
  and TryISO8601ToDate('2019-01-01T10:00:00+0400', True, D2)
  and TryISO8601ToDate('2019-01-01T10:00:00+04:00', True, D3)
  and SameDateTime(D1, D2) and SameDateTime(D2, D3)
  then
    Writeln(DateToISO8601(D1, True))
  else
    WriteLn('error');
end.
TagsNo tags attached.
Fixed in Revision42040.
FPCOldBugId
FPCTarget3.2.0
Attached Files
  • short-tz-01.patch (1,779 bytes)
    Index: packages/rtl-objpas/src/inc/dateutil.inc
    ===================================================================
    --- packages/rtl-objpas/src/inc/dateutil.inc	(revision 42022)
    +++ packages/rtl-objpas/src/inc/dateutil.inc	(working copy)
    @@ -448,7 +448,7 @@
     // Combination of previous
     function TryISOStrToDateTime(const aString: string; out outDateTime: TDateTime): Boolean;
     // Z +hh:nn -hh:nn
    -Function TryISOTZStrToTZOffset(TZ : String; Out TZOffset : Integer) : boolean;
    +Function TryISOTZStrToTZOffset(const TZ : String; Out TZOffset : Integer) : boolean;
     
     // ISO 8601 Date/Time formatting
     
    @@ -2857,7 +2857,7 @@
         outDateTime := 0;
     end;
     
    -Function TryISOTZStrToTZOffset(TZ : String; Out TZOffset : Integer) : boolean;
    +Function TryISOTZStrToTZOffset(const TZ : String; Out TZOffset : Integer) : boolean;
     
     Var
       H,M : LongInt;
    @@ -2871,7 +2871,16 @@
         Result:=TZ[1] in ['+','-'];
         if Not Result then
           Exit;
    -    Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,5,2),M);
    +    case Length(TZ) of
    +      3: begin
    +        Result:=TryStrToInt(Copy(TZ,2,2),H);
    +        M := 0;
    +      end;
    +      5: Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,4,2),M);
    +      6: Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,5,2),M);
    +    else
    +      Result := False;
    +    end;
         if not Result then
           exit;
         TZOffset:=H*60+M;
    @@ -2904,6 +2913,16 @@
         TZ:='Z';
         S:=Copy(S,1,L-1);
         end
    +  else If (L>2) and (S[L-2] in ['+','-']) then
    +    begin
    +    TZ:=Copy(S,L-2,3);
    +    S:=Copy(S,1,L-3);
    +    end
    +  else If (L>4) and (S[L-4] in ['+','-']) then
    +    begin
    +    TZ:=Copy(S,L-4,5);
    +    S:=Copy(S,1,L-5);
    +    end
       else If (L>5) and (S[L-5] in ['+','-']) then
         begin
         TZ:=Copy(S,L-5,6);
    
    short-tz-01.patch (1,779 bytes)

Activities

Ondrej Pokorny

2019-05-08 18:55

reporter  

short-tz-01.patch (1,779 bytes)
Index: packages/rtl-objpas/src/inc/dateutil.inc
===================================================================
--- packages/rtl-objpas/src/inc/dateutil.inc	(revision 42022)
+++ packages/rtl-objpas/src/inc/dateutil.inc	(working copy)
@@ -448,7 +448,7 @@
 // Combination of previous
 function TryISOStrToDateTime(const aString: string; out outDateTime: TDateTime): Boolean;
 // Z +hh:nn -hh:nn
-Function TryISOTZStrToTZOffset(TZ : String; Out TZOffset : Integer) : boolean;
+Function TryISOTZStrToTZOffset(const TZ : String; Out TZOffset : Integer) : boolean;
 
 // ISO 8601 Date/Time formatting
 
@@ -2857,7 +2857,7 @@
     outDateTime := 0;
 end;
 
-Function TryISOTZStrToTZOffset(TZ : String; Out TZOffset : Integer) : boolean;
+Function TryISOTZStrToTZOffset(const TZ : String; Out TZOffset : Integer) : boolean;
 
 Var
   H,M : LongInt;
@@ -2871,7 +2871,16 @@
     Result:=TZ[1] in ['+','-'];
     if Not Result then
       Exit;
-    Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,5,2),M);
+    case Length(TZ) of
+      3: begin
+        Result:=TryStrToInt(Copy(TZ,2,2),H);
+        M := 0;
+      end;
+      5: Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,4,2),M);
+      6: Result:=TryStrToInt(Copy(TZ,2,2),H) and TryStrToInt(Copy(TZ,5,2),M);
+    else
+      Result := False;
+    end;
     if not Result then
       exit;
     TZOffset:=H*60+M;
@@ -2904,6 +2913,16 @@
     TZ:='Z';
     S:=Copy(S,1,L-1);
     end
+  else If (L>2) and (S[L-2] in ['+','-']) then
+    begin
+    TZ:=Copy(S,L-2,3);
+    S:=Copy(S,1,L-3);
+    end
+  else If (L>4) and (S[L-4] in ['+','-']) then
+    begin
+    TZ:=Copy(S,L-4,5);
+    S:=Copy(S,1,L-5);
+    end
   else If (L>5) and (S[L-5] in ['+','-']) then
     begin
     TZ:=Copy(S,L-5,6);
short-tz-01.patch (1,779 bytes)

Michael Van Canneyt

2019-05-12 09:52

administrator   ~0116141

Checked and applied, thank you !

Ondrej Pokorny

2019-05-12 10:06

reporter   ~0116144

Thank you!

Issue History

Date Modified Username Field Change
2019-05-08 18:55 Ondrej Pokorny New Issue
2019-05-08 18:55 Ondrej Pokorny File Added: short-tz-01.patch
2019-05-10 09:17 Michael Van Canneyt Assigned To => Michael Van Canneyt
2019-05-10 09:17 Michael Van Canneyt Status new => assigned
2019-05-12 09:52 Michael Van Canneyt Status assigned => resolved
2019-05-12 09:52 Michael Van Canneyt Resolution open => fixed
2019-05-12 09:52 Michael Van Canneyt Fixed in Version => 3.3.1
2019-05-12 09:52 Michael Van Canneyt Fixed in Revision => 42040.
2019-05-12 09:52 Michael Van Canneyt FPCTarget => 3.2.0
2019-05-12 09:52 Michael Van Canneyt Note Added: 0116141
2019-05-12 10:06 Ondrej Pokorny Status resolved => closed
2019-05-12 10:06 Ondrej Pokorny Note Added: 0116144