Remove the "T" separator when formatting ISO 8601 date/time to
strings. This improves readability without sacrificing machine
parsing, remaining compliant with RFC 3339.
Technically ISO 8601 specification states "T" can only be omitted,
but that makes readability even worse.
Example:
> Before: 2018-08-22T18:43:10-05:00
> After: 2018-08-22 18:43:10-05:00
..........^ (10th character)
NOTE: Qt's own ISO 8601 parsing of strings to QDateTime will not
handle this correctly. Custom format strings can be used, or just
replace the " " with "T" again.
See https://en.wikipedia.org/wiki/ISO_8601#cite_note-32
4.3.2 NOTE: By mutual agreement of the partners in information
interchange, the character [T] may be omitted in applications where
there is no risk of confusing a date and time of day representation
with others defined in this International Standard.
And https://www.ietf.org/rfc/rfc3339.txt
NOTE: ISO 8601 defines date and time separated by "T".
Applications using this syntax may choose, for the sake of
readability, to specify a full-date and full-time separated by
(say) a space character.
Fixes #1456
// Return the localized date/time
if (useUTC) {
// Return UTC time
// Return the localized date/time
if (useUTC) {
// Return UTC time
- return date.toUTC().toString(dateFormat);
+ if (dateFormat == Qt::DateFormat::ISODate) {
+ // Replace the "T" date/time separator with " " for readability. This isn't quite the
+ // ISO 8601 spec (it specifies omitting the "T" entirely), but RFC 3339 allows this.
+ // Go with RFC 3339 for human readability that's still machine-parseable, too.
+ //
+ // Before: 2018-06-21T21:35:52Z
+ // After: 2018-06-21 21:35:52Z
+ // ..........^ (10th character)
+ //
+ // See https://en.wikipedia.org/wiki/ISO_8601#cite_note-32
+ // And https://www.ietf.org/rfc/rfc3339.txt
+ return date.toUTC().toString(dateFormat).replace(10, 1, " ");
+ } else {
+ return date.toUTC().toString(dateFormat);
+ }
} else if (dateFormat == Qt::DateFormat::ISODate) {
// Add in ISO local timezone information via special handling below
} else if (dateFormat == Qt::DateFormat::ISODate) {
// Add in ISO local timezone information via special handling below
+ // formatDateTimeToOffsetISO() handles converting "T" to " "
return formatDateTimeToOffsetISO(date);
} else {
// Return local time
return formatDateTimeToOffsetISO(date);
} else {
// Return local time
return "formatDateTimeToISO() invalid date/time";
}
return "formatDateTimeToISO() invalid date/time";
}
+ // Replace the "T" date/time separator with " " for readability. This isn't quite the ISO 8601
+ // spec (it specifies omitting the "T" entirely), but RFC 3339 allows this. Go with RFC 3339
+ // for human readability that's still machine-parseable, too.
+ //
+ // Before: 2018-08-22T18:43:10-05:00
+ // After: 2018-08-22 18:43:10-05:00
+ // ..........^ (10th character)
+ //
+ // See https://en.wikipedia.org/wiki/ISO_8601#cite_note-32
+ // And https://www.ietf.org/rfc/rfc3339.txt
+
- // The expected way to get a UTC offset on ISO8601 dates
- return dateTime.toTimeSpec(Qt::OffsetFromUTC).toString(Qt::ISODate);
+ // The expected way to get a UTC offset on ISO 8601 dates
+ // Remove the "T" date/time separator
+ return dateTime.toTimeSpec(Qt::OffsetFromUTC).toString(Qt::ISODate).replace(10, 1, " ");
#else
// Work around Qt bug that converts to UTC instead of including timezone information
// See https://bugreports.qt.io/browse/QTBUG-26161
#else
// Work around Qt bug that converts to UTC instead of including timezone information
// See https://bugreports.qt.io/browse/QTBUG-26161
// Force the local time to follow this offset
local.setUtcOffset(utcOffset);
// Now the output should be correct
// Force the local time to follow this offset
local.setUtcOffset(utcOffset);
// Now the output should be correct
- return local.toString(Qt::ISODate);
+ // Remove the "T" date/time separator
+ return local.toString(Qt::ISODate).replace(10, 1, " ");