+ char_count += 3;
+ TmpStamp.Second = atoi(datestr + 17);
+ }
+
+ if ( datestr[19] == '.' )
+ {
+ if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) )
+ return false;
+
+ // we don't carry the ms value
+ datestr += 4;
+ }
+
+ if ( datestr[19] == '-' || datestr[19] == '+' )
+ {
+ if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) )
+ || datestr[22] != ':'
+ || ! ( isdigit(datestr[23]) && isdigit(datestr[24]) ) )
+ return false;
+
+ char_count += 6;
+
+ ui32_t TZ_hh = atoi(datestr + 20);
+ ui32_t TZ_mm = atoi(datestr + 23);
+ if ((TZ_hh > 14) || (TZ_mm > 59) || ((TZ_hh == 14) && (TZ_mm > 0)))
+ return false;
+
+ i32_t TZ_offset = 60 * TZ_hh + TZ_mm;
+ if (datestr[19] == '-')
+ TZ_offset = -TZ_offset;
+ /* at this point, TZ_offset reflects the contents of the string */
+
+ /* a negative offset is behind UTC and so needs to increment to
+ * convert, while a positive offset must do the reverse */
+ TmpStamp.AddMinutes(-TZ_offset);
+ }
+ else if (datestr[19] == 'Z')
+ {
+ /* act as if the offset were +00:00 */
+ char_count++;
+ }
+ }
+
+ if ( datestr[char_count] != 0 )
+ {
+ Kumu::DefaultLogSink().Error("Unexpected extra characters in string: %s (%ld)\n",
+ datestr, char_count);
+ return false;
+ }
+
+#ifdef KM_WIN32
+ SYSTEMTIME st;
+ FILETIME ft;
+ TIMESTAMP_TO_SYSTIME(TmpStamp, &st);
+ if ( SystemTimeToFileTime(&st, &ft) == 0 )
+ return false;
+ SYSTIME_TO_TIMESTAMP(&st, *this);
+#else
+ Kumu::TAI::tai t;
+ Kumu::TAI::caltime ct;
+ TIMESTAMP_TO_CALTIME(TmpStamp, &ct);
+ t = ct; // back and forth to tai to normalize offset
+ ct = t;
+ CALTIME_TO_TIMESTAMP(&ct, *this)
+#endif