fix: remember the first/last weekday flags from a timezone DST
If a date is given in a relative form with first/last parameters, we must remember them in order to select the appropriate day of the week from the appropriate year.
This commit is contained in:
@@ -53,37 +53,73 @@ class TimeZone
|
||||
public:
|
||||
|
||||
|
||||
struct DstDate
|
||||
{
|
||||
enum DateType {
|
||||
ordinary_date = 0,
|
||||
first_weekday,
|
||||
last_weekday,
|
||||
};
|
||||
|
||||
/*
|
||||
* for ordinary_date
|
||||
*
|
||||
*/
|
||||
DateType date_type;
|
||||
|
||||
/*
|
||||
* a week day (0-sunday, 1-monday, ..., 6-saturday)
|
||||
* used when date_type is first_weekday or last_weekday
|
||||
*/
|
||||
int weekday;
|
||||
|
||||
/*
|
||||
* if date_type=ordinary_date the date is used as normal date represented in UTC time
|
||||
* if date_type=first_weekday we are looking for a first weekday in the date.month (year will be changed)
|
||||
* if date_type=last_weekday we are looking for the last weekady in the date.month (year will be changed)
|
||||
*/
|
||||
pt::Date date;
|
||||
|
||||
|
||||
DstDate();
|
||||
void Clear();
|
||||
int Compare(const pt::Date & utc_date) const;
|
||||
static pt::Date CalculateRelativeDate(int year, int month, bool is_first, int weekday);
|
||||
};
|
||||
|
||||
|
||||
struct Dst
|
||||
{
|
||||
// true if a time zone has daylight saving time
|
||||
/*
|
||||
* true if a time zone has daylight saving time
|
||||
*/
|
||||
bool has_dst;
|
||||
|
||||
// time zone daylight saving time (used if has_dst is true)
|
||||
// the 'year' field is the same in 'start' and 'end'
|
||||
// start and end are represented in UTC time
|
||||
pt::Date start, end;
|
||||
/*
|
||||
* time zone daylight saving time (used if has_dst is true)
|
||||
*/
|
||||
DstDate start, end;
|
||||
|
||||
// time zone daylight saving time offset
|
||||
// used when has_dst is true and the date is whithin start and end
|
||||
// this offset should be added to time zone offset
|
||||
/*
|
||||
* time zone daylight saving time offset
|
||||
* used when has_dst is true and the date is whithin start and end
|
||||
* this offset should be added to time zone offset
|
||||
*/
|
||||
time_t offset;
|
||||
|
||||
Dst();
|
||||
void Clear();
|
||||
|
||||
// checking whether specified 'date' is in the range of <start, end>
|
||||
// the year field in date, start and end is ignored
|
||||
// has_dst must be true
|
||||
/*
|
||||
* checking whether specified 'date' is in the range of Dst
|
||||
* has_dst must be true
|
||||
*/
|
||||
bool IsDstUsed(const pt::Date & utc_date) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
TimeZone();
|
||||
|
||||
|
||||
/*
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
|
||||
@@ -148,9 +184,8 @@ private:
|
||||
time_t ParseStrOffset(const wchar_t * str);
|
||||
time_t GetOffset(pt::Space & space);
|
||||
int ParseDstDateWeekday(const wchar_t * date_str, const wchar_t ** after_date_str);
|
||||
void ParseDstDateDay(bool is_first, int weekday, pt::Date & date);
|
||||
const wchar_t * SkipDstDateSeparator(const wchar_t * date_str);
|
||||
bool ParseDstDate(int year, const wchar_t * date_str, pt::Date & date);
|
||||
bool ParseDstDate(int year, const wchar_t * date_str, DstDate & dst_date);
|
||||
bool SetTzDst(pt::Space & year);
|
||||
static void PrintOffsetPart(long val, pt::Stream & str);
|
||||
|
||||
|
Reference in New Issue
Block a user