File indexing completed on 2024-04-21 03:44:46
0001 /* 0002 SPDX-FileCopyrightText: 2002 Jason Harris <kstars@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "kstarsdatetime.h" 0010 0011 #include <QTime> 0012 0013 class QString; 0014 0015 /** @class TimeZoneRule 0016 *This class provides the information needed to determine whether Daylight 0017 *Savings Time (DST; a.k.a. "Summer Time") is currently active at a given 0018 *location. There are (at least) 25 different "rules" which govern DST 0019 *around the world; a string identifying the appropriate rule is attached 0020 *to each city in citydb.sqlite. 0021 * 0022 *The rules themselves are stored in the TZrulebook.dat file, which is read 0023 *on startup; each line in the file creates a TimeZoneRule object. 0024 * 0025 *TimeZoneRule consists of QStrings identifying the months and days on which 0026 *DST starts and ends, QTime objects identifying the time at which the 0027 *changes occur, and a double indicating the size of the offset in hours 0028 *(probably always 1.00). 0029 * 0030 *Month names should be the English three-letter abbreviation, uncapitalized. 0031 *Day names are either an integer indicating the calendar date (i.e., "15" is 0032 *the fifteenth of the month), or a number paired with a three-letter 0033 *abbreviation for a weekday. This indicates the Nth weekday of the month 0034 *(i.e., "2sun" is the second Sunday of the Month). Finally, the weekday 0035 *string on its own indicates the last weekday of the month (i.e., 0036 *"mon" is the last Monday of the month). 0037 * 0038 *The isDSTActive(KStarsDateTime) function returns true if DST is active for the 0039 *DateTime given as an argument. 0040 * 0041 *The nextDSTChange(KStarsDateTime) function returns the KStarsDateTime of the moment 0042 *at which the next DST change will occur for the current location. 0043 *@author Jason Harris 0044 *@version 1.0 0045 */ 0046 0047 class TimeZoneRule 0048 { 0049 public: 0050 /** Default Constructor. Makes the "empty" time zone rule (i.e., no DST correction)*/ 0051 TimeZoneRule(); 0052 0053 /** Constructor. Create a TZ rule according to the arguments. 0054 *@param smonth the three-letter code for the month in which DST starts 0055 *@param sday a string encoding the day on which DST starts (see the class description) 0056 *@param stime the time at which DST starts 0057 *@param rmonth the three-letter code for the month in which DST reverts 0058 *@param rday a string encoding the day on which DST reverts (see the class description) 0059 *@param rtime the time at which DST reverts 0060 *@param offset the offset between normal time and DS time (always 1.00?) 0061 */ 0062 TimeZoneRule(const QString &smonth, const QString &sday, const QTime &stime, const QString &rmonth, 0063 const QString &rday, const QTime &rtime, const double &offset = 1.00); 0064 0065 /** Determine whether DST is in effect for the given DateTime, according to this rule 0066 *@param date the date/time to test for DST 0067 */ 0068 bool isDSTActive(const KStarsDateTime &date); 0069 0070 /** @return true if the rule is the "empty" TZ rule. */ 0071 bool isEmptyRule() const { return (HourOffset == 0.0); } 0072 0073 /** Toggle DST on/off. The @p activate argument should probably be isDSTActive() 0074 *@param activate if true, then set DST active; otherwise, deactivate DST 0075 */ 0076 void setDST(bool activate = true); 0077 0078 /** @return the current Timezone offset, compared to the timezone's Standard Time. 0079 *This is typically 0.0 if DST is inactive, and 1.0 if DST is active. */ 0080 double deltaTZ() const { return dTZ; } 0081 0082 /** Recalculate next dst change and if DST is active by a given local time with 0083 *timezone offset and time direction. 0084 *@param ltime the time to be tested 0085 *@param time_runs_forward time direction 0086 *@param TZoffset offset of timezone in some fictional unit 0087 *@param automaticDSTchange is automatic DST change? 0088 * 0089 * @todo Check dox for TZoffset 0090 */ 0091 void reset_with_ltime(KStarsDateTime <ime, const double TZoffset, const bool time_runs_forward, 0092 const bool automaticDSTchange = false); 0093 0094 /** @return computed value for next DST change in universal time. */ 0095 KStarsDateTime nextDSTChange() const { return next_change_utc; } 0096 0097 /** @return computed value for next DST change in local time. */ 0098 KStarsDateTime nextDSTChange_LTime() const { return next_change_ltime; } 0099 0100 /** @return true if this rule is the same as the argument. 0101 * @param r the rule to check for equivalence 0102 */ 0103 bool equals(TimeZoneRule *r); 0104 0105 private: 0106 /** @return the KStarsDateTime of the moment when the next DST change will occur in local time 0107 *This is useful because DST change times are saved in local times*/ 0108 void nextDSTChange_LTime(const KStarsDateTime &date); 0109 0110 /** @return the KStarsDateTime of the moment when the last DST change occurred in local time 0111 *This is useful because DST change times are saved in local times 0112 *We need this in case time is running backwards. */ 0113 void previousDSTChange_LTime(const KStarsDateTime &date); 0114 0115 /** calculate the next DST change in universal time for current location */ 0116 void nextDSTChange(const KStarsDateTime &local_date, const double TZoffset); 0117 0118 /** calculate the previous DST change in universal time for current location */ 0119 void previousDSTChange(const KStarsDateTime &local_date, const double TZoffset); 0120 0121 /** Interpret the string as a month of the year; 0122 *@return the month integer (1=jan ... 12=dec) 0123 */ 0124 int initMonth(const QString &m); 0125 0126 /** Set up empty time zone rule */ 0127 void setEmpty(); 0128 0129 /** Interpret the day string as a week ID and a day-of-week ID. The day-of-week 0130 *is an integer between 1 (sunday) and 7 (saturday); the week integer can 0131 *be 1-3 (1st/2nd/third weekday of the month), or 5 (last weekday of the month) 0132 *@param day the day integer is returned by reference through this value 0133 *@param week the week integer is returned by reference through this value 0134 *@return true if the day string was successfully parsed 0135 */ 0136 bool initDay(const QString &d, int &day, int &week); 0137 0138 /** Find the calendar date on which DST starts for the calendar year 0139 *of the given KStarsDateTime. 0140 *@param d the date containing the year to be tested 0141 *@return the calendar date, an integer between 1 and 31. */ 0142 int findStartDay(const KStarsDateTime &d); 0143 0144 /** Find the calendar date on which DST ends for the calendar year 0145 *of the given KStarsDateTime. 0146 *@param d the date containing the year to be tested 0147 *@return the calendar date, an integer between 1 and 31. */ 0148 int findRevertDay(const KStarsDateTime &d); 0149 0150 int StartDay { 0 }; 0151 int RevertDay { 0 }; 0152 int StartMonth { 0 }; 0153 int RevertMonth { 0 }; 0154 int StartWeek { 0 }; 0155 int RevertWeek { 0 }; 0156 QTime StartTime, RevertTime; 0157 KStarsDateTime next_change_utc; 0158 KStarsDateTime next_change_ltime; 0159 double dTZ { 0 }; 0160 double HourOffset { 0 }; 0161 };