File indexing completed on 2024-05-19 12:26:46
0001 /* 0002 SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "mergeutil_p.h" 0008 0009 #include <QDateTime> 0010 #include <QDebug> 0011 #include <QString> 0012 #include <QTimeZone> 0013 #include <QUrl> 0014 0015 using namespace KPublicTransport; 0016 0017 static QDateTime applyTimeZone(QDateTime dt, const QDateTime &refDt) 0018 { 0019 if (dt.timeSpec() != Qt::LocalTime) { 0020 return dt; 0021 } 0022 0023 if (refDt.timeSpec() == Qt::TimeZone) { 0024 dt.setTimeZone(refDt.timeZone()); 0025 } else if (refDt.timeSpec() == Qt::OffsetFromUTC) { 0026 dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(refDt.offsetFromUtc())); 0027 } 0028 0029 return dt; 0030 } 0031 0032 int MergeUtil::distance(const QDateTime& lhs, const QDateTime& rhs) 0033 { 0034 const auto ldt = applyTimeZone(lhs, rhs); 0035 const auto rdt = applyTimeZone(rhs, lhs); 0036 return std::abs(ldt.secsTo(rdt)); 0037 } 0038 0039 bool MergeUtil::isBefore(const QDateTime& lhs, const QDateTime& rhs) 0040 { 0041 const auto ldt = applyTimeZone(lhs, rhs); 0042 const auto rdt = applyTimeZone(rhs, lhs); 0043 return ldt < rdt; 0044 } 0045 0046 QDateTime MergeUtil::mergeDateTimeEqual(const QDateTime &lhs, const QDateTime &rhs) 0047 { 0048 // anything is better than invalid, timezone is best 0049 if (!rhs.isValid() || lhs.timeSpec() == Qt::TimeZone) { 0050 return lhs; 0051 } 0052 if (!lhs.isValid() || rhs.timeSpec() == Qt::TimeZone) { 0053 return rhs; 0054 } 0055 0056 // UTC offset it better than local time 0057 if (lhs.timeSpec() == Qt::OffsetFromUTC || rhs.timeSpec() == Qt::LocalTime) { 0058 return lhs; 0059 } 0060 return rhs; 0061 } 0062 0063 QDateTime MergeUtil::mergeDateTimeMax(const QDateTime &lhs, const QDateTime &rhs) 0064 { 0065 // if only one side is valid, prefer that one 0066 if (!lhs.isValid()) { 0067 return rhs; 0068 } 0069 if (!rhs.isValid()) { 0070 return lhs; 0071 } 0072 0073 auto dt = isBefore(lhs, rhs) ? rhs : lhs; 0074 if (dt.timeSpec() == Qt::TimeZone) { 0075 return dt; 0076 } 0077 0078 // recover timezone of we can 0079 if (lhs.timeSpec() == Qt::TimeZone) { 0080 dt.setTimeZone(lhs.timeZone()); 0081 return dt; 0082 } else if (rhs.timeSpec() == Qt::TimeZone) { 0083 dt.setTimeZone(rhs.timeZone()); 0084 return dt; 0085 } 0086 0087 // recover UTC offset if we can 0088 if (dt.timeSpec() == Qt::OffsetFromUTC) { 0089 return dt; 0090 } else if (lhs.timeSpec() == Qt::OffsetFromUTC) { 0091 dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(lhs.offsetFromUtc())); 0092 } else if (rhs.timeSpec() == Qt::OffsetFromUTC) { 0093 dt.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(rhs.offsetFromUtc())); 0094 } 0095 0096 return dt; 0097 } 0098 0099 QString MergeUtil::mergeString(const QString &lhs, const QString &rhs) 0100 { 0101 // ### this is deterministic, but not necessarily ideal 0102 // we could prefer mixed case over all caps, unicode over transliterated, etc 0103 if (lhs.size() == rhs.size()) { 0104 return lhs < rhs ? lhs : rhs; 0105 } 0106 return lhs.size() < rhs.size() ? rhs : lhs; 0107 }