From f27435c3d1b2793718e483449c7d6a62ee6cac8e Mon Sep 17 00:00:00 2001 From: Shane Synan Date: Wed, 12 Sep 2018 17:54:25 -0500 Subject: [PATCH] util: Remove T separator from ISO 8601 (RFC 3339) 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 --- src/common/util.cpp | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/src/common/util.cpp b/src/common/util.cpp index 914c9a49..4a9165a3 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -306,9 +306,24 @@ QString tryFormatUnixEpoch(const QString &possibleEpochDate, Qt::DateFormat date // 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 + // formatDateTimeToOffsetISO() handles converting "T" to " " return formatDateTimeToOffsetISO(date); } else { // Return local time @@ -324,9 +339,21 @@ QString formatDateTimeToOffsetISO(const QDateTime &dateTime) 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 + #if 0 - // 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 @@ -348,6 +375,7 @@ QString formatDateTimeToOffsetISO(const QDateTime &dateTime) // 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, " "); #endif } -- 2.20.1