1/*
2 This file is part of the KFileMetaData project
3 SPDX-FileCopyrightText: 2024 Stefan BrĂ¼ns <stefan.bruens@rwth-aachen.de>
4
5 SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8#include "kfilemetadata_debug.h"
9
10#include <QDateTime>
11#include <QString>
12#include <QTimeZone>
13
14#include <array>
15
16namespace KFileMetaData
17{
18namespace Parser
19{
20
21inline QDateTime dateTimeFromExifString(QStringView dateString, QStringView subSecsString, QStringView offsetString, std::optional<int> offsetSecs)
22{
23 using namespace Qt::Literals::StringLiterals;
24
25 if (auto dateTime = QDateTime::fromString(string: dateString, format: u"yyyy:MM:dd hh:mm:ss"_s); dateTime.isValid()) {
26 subSecsString = subSecsString.trimmed();
27 if (!subSecsString.isEmpty()) {
28 long subSecs = 0;
29 if (subSecsString.size() >= 4) {
30 subSecsString = subSecsString.first(n: 4);
31 subSecs = (subSecsString.toLong() + 5) / 10;
32 } else if (subSecsString.size() == 3) {
33 subSecs = subSecsString.toLong();
34 } else if (subSecsString.size() == 2) {
35 subSecs = subSecsString.toLong() * 10;
36 } else if (subSecsString.size() == 1) {
37 subSecs = subSecsString.toLong() * 100;
38 }
39 dateTime = dateTime.addMSecs(msecs: subSecs);
40 }
41 if (!offsetString.isEmpty()) {
42 if (auto offset = QDateTime::fromString(string: offsetString, format: u"ttt"_s); offset.isValid()) {
43 dateTime.setTimeZone(toZone: offset.timeZone());
44 } else {
45 qCWarning(KFILEMETADATA_LOG) << "Could not parse timezone from:" << offsetString;
46 }
47 } else if (offsetSecs) {
48 dateTime.setTimeZone(toZone: QTimeZone(*offsetSecs));
49 }
50 return dateTime;
51 }
52
53 qCWarning(KFILEMETADATA_LOG) << "Could not parse datetime from:" << dateString << subSecsString << offsetString;
54 return {};
55}
56
57inline QDateTime dateTimeFromString(const QString &dateString)
58{
59 if (auto dateTime = QDateTime::fromString(string: dateString, format: Qt::ISODate); dateTime.isValid()) {
60 return dateTime;
61 }
62
63 std::array<QString, 13> formats{
64 QStringLiteral("yyyy-MM-dd"),
65 QStringLiteral("dd-MM-yyyy"),
66 QStringLiteral("yyyy-MM"),
67 QStringLiteral("MM-yyyy"),
68 QStringLiteral("yyyy.MM.dd"),
69 QStringLiteral("dd.MM.yyyy"),
70 QStringLiteral("dd MMMM yyyy"),
71 QStringLiteral("MM.yyyy"),
72 QStringLiteral("yyyy.MM"),
73 QStringLiteral("yyyy"),
74 QStringLiteral("yy"),
75 QStringLiteral("dddd d MMM yyyy h':'mm':'ss AP"),
76 QStringLiteral("yyyy:MM:dd hh:mm:ss"),
77 };
78
79 for (const auto& formatString : formats) {
80 if (auto dateTime = QDateTime::fromString(string: dateString, format: formatString); dateTime.isValid()) {
81 dateTime.setTimeZone(toZone: QTimeZone::UTC);
82 return dateTime;
83 }
84 }
85
86 if (auto dateTime = QLocale().toDateTime(string: dateString, format: QLocale::ShortFormat); dateTime.isValid()) {
87 dateTime.setTimeZone(toZone: QTimeZone::UTC);
88 return dateTime;
89 }
90
91 if (auto dateTime = QLocale().toDateTime(string: dateString, format: QLocale::LongFormat); dateTime.isValid()) {
92 dateTime.setTimeZone(toZone: QTimeZone::UTC);
93 return dateTime;
94 }
95
96 qCWarning(KFILEMETADATA_LOG) << "Could not determine correct datetime format from:" << dateString;
97 return {};
98}
99
100} // namespace Parser
101} // namespace KFileMetaData
102

source code of kfilemetadata/src/datetimeparser_p.h