Browse Source

Fix ISO 8601 parser for dates with year < 160

vadim-xd 1 year ago
parent
commit
7695c63bbc
2 changed files with 16 additions and 8 deletions
  1. 9 8
      util/datetime/parser.rl6
  2. 7 0
      util/datetime/parser_ut.cpp

+ 9 - 8
util/datetime/parser.rl6

@@ -74,13 +74,14 @@ wkday   = 'Mon'i | 'Tue'i | 'Wed'i | 'Thu'i | 'Fri'i | 'Sat'i | 'Sun'i;
 weekday = 'Monday'i | 'Tuesday'i | 'Wednesday'i | 'Thursday'i
         | 'Friday'i | 'Saturday'i | 'Sunday'i;
 
-action set_second   { DateTimeFields.Second = I; }
-action set_minute   { DateTimeFields.Minute = I; }
-action set_hour     { DateTimeFields.Hour = I; }
-action set_day      { DateTimeFields.Day = I; }
-action set_month    { DateTimeFields.Month = I; }
-action set_year     { DateTimeFields.SetLooseYear(I); }
-action set_zone_utc { DateTimeFields.ZoneOffsetMinutes = 0; }
+action set_second       { DateTimeFields.Second = I; }
+action set_minute       { DateTimeFields.Minute = I; }
+action set_hour         { DateTimeFields.Hour = I; }
+action set_day          { DateTimeFields.Day = I; }
+action set_month        { DateTimeFields.Month = I; }
+action set_year         { DateTimeFields.SetLooseYear(I); }
+action set_precise_year { DateTimeFields.Year = I; }
+action set_zone_utc     { DateTimeFields.ZoneOffsetMinutes = 0; }
 
 }%%
 
@@ -193,7 +194,7 @@ machine ISO8601DateTimeParser;
 
 include DateTimeParserCommon;
 
-year = int4 @set_year;
+year = int4 @set_precise_year;
 month = int2 @set_month;
 day = int2 @set_day;
 hour = int2 @set_hour;

+ 7 - 0
util/datetime/parser_ut.cpp

@@ -281,6 +281,13 @@ Y_UNIT_TEST_SUITE(TDateTimeParseTest) {
         UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(637487058), p.GetResult(TInstant::Zero()));
     }
 
+    Y_UNIT_TEST(TestIso8601BeforeEpoch) {
+        TIso8601DateTimeParser p;
+        static constexpr TStringBuf timestamp = "0001-01-01T00:00:00Z";
+        UNIT_ASSERT(p.ParsePart(timestamp.begin(), timestamp.size()));
+        UNIT_ASSERT_VALUES_EQUAL(p.GetDateTimeFields().Year, 1);
+    }
+
     Y_UNIT_TEST(TestIso8601Correct) {
         bool ret;
         time_t t;