aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-qt/qt5/qtbase/0022-fix_timezone_dst.patch
blob: 0213e94a72f1f31d30f2f9425603acc063622201 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
From: Dilshod Mukhtarov <dilshodm@gmail.com>
Date: Tue, 2 Nov 2021 22:57:47 +0400
Subject: [PATCH] fix incorrect dst dates bug (backport from Qt 6.2)

In Qt 5.15.2 the DST is incorrectly calculated using Yocto's tzdata
(example America/Los_Angeles).
For example in year 2021 DST has to end at Nov 7, 2021, with this bug it shows Nov 1, 2021.

Upstream-Status: Backport [in Qt 6 the timezone was reworked, closest upstream commit fixing this is probably https://codereview.qt-project.org/c/qt/qtbase/+/343933]

Signed-off-by: Dilshod Mukhtarov <dilshodm@gmail.com>

diff -Nru a/src/corelib/time/qtimezoneprivate_tz.cpp b/src/corelib/time/qtimezoneprivate_tz.cpp
--- a/src/corelib/time/qtimezoneprivate_tz.cpp	2020-10-27 12:02:10.000000000 +0400
+++ b/src/corelib/time/qtimezoneprivate_tz.cpp	2021-11-02 22:03:48.529270348 +0400
@@ -350,6 +350,11 @@

 static QDate calculateDowDate(int year, int month, int dayOfWeek, int week)
 {
+    if (dayOfWeek == 0) // Sunday; we represent it as 7, POSIX uses 0
+        dayOfWeek = 7;
+    else if (dayOfWeek & ~7 || month < 1 || month > 12 || week < 1 || week > 5)
+        return QDate();
+
     QDate date(year, month, 1);
     int startDow = date.dayOfWeek();
     if (startDow <= dayOfWeek)
@@ -364,28 +369,37 @@

 static QDate calculatePosixDate(const QByteArray &dateRule, int year)
 {
+    bool ok;
     // Can start with M, J, or a digit
     if (dateRule.at(0) == 'M') {
         // nth week in month format "Mmonth.week.dow"
         QList<QByteArray> dateParts = dateRule.split('.');
-        int month = dateParts.at(0).mid(1).toInt();
-        int week = dateParts.at(1).toInt();
-        int dow = dateParts.at(2).toInt();
-        if (dow == 0)
-            ++dow;
-        return calculateDowDate(year, month, dow, week);
+        if (dateParts.count() > 2) {
+            int month = dateParts.at(0).mid(1).toInt(&ok);
+            int week = ok ? dateParts.at(1).toInt(&ok) : 0;
+            int dow = ok ? dateParts.at(2).toInt(&ok) : 0;
+            if (ok)
+                return calculateDowDate(year, month, dow, week);
+        }
     } else if (dateRule.at(0) == 'J') {
-        // Day of Year ignores Feb 29
-        int doy = dateRule.mid(1).toInt();
-        QDate date = QDate(year, 1, 1).addDays(doy - 1);
-        if (QDate::isLeapYear(date.year()))
-            date = date.addDays(-1);
-        return date;
+        // Day of Year 1...365, ignores Feb 29.
+        // So March always starts on day 60.
+        int doy = dateRule.mid(1).toInt(&ok);
+        if (ok && doy > 0 && doy < 366) {
+            // Subtract 1 because we're adding days *after* the first of
+            // January, unless it's after February in a leap year, when the leap
+            // day cancels that out:
+            if (!QDate::isLeapYear(year) || doy < 60)
+                --doy;
+            return QDate(year, 1, 1).addDays(doy);
+        }
     } else {
-        // Day of Year includes Feb 29
-        int doy = dateRule.toInt();
-        return QDate(year, 1, 1).addDays(doy - 1);
+        // Day of Year 0...365, includes Feb 29
+        int doy = dateRule.toInt(&ok);
+        if (ok && doy >= 0 && doy < 366)
+            return QDate(year, 1, 1).addDays(doy);
     }
+    return QDate();
 }

 // returns the time in seconds, INT_MIN if we failed to parse