This commit is contained in:
Ivan Blinkov 2018-12-13 10:19:03 +03:00
commit 4d3cef0476
5 changed files with 41 additions and 18 deletions

View File

@ -0,0 +1,24 @@
1981-09-30 23:00:00
1981-09-30 23:05:00
1981-09-30 23:10:00
1981-09-30 23:15:00
1981-09-30 23:20:00
1981-09-30 23:25:00
1981-09-30 23:30:00
1981-09-30 23:35:00
1981-09-30 23:40:00
1981-09-30 23:45:00
1981-09-30 23:50:00
1981-09-30 23:55:00
2018-09-21 23:00:00
2018-09-21 23:05:00
2018-09-21 23:10:00
2018-09-21 23:15:00
2018-09-21 23:20:00
2018-09-21 23:25:00
2018-09-21 23:30:00
2018-09-21 23:35:00
2018-09-21 23:40:00
2018-09-21 23:45:00
2018-09-21 23:50:00
2018-09-21 23:55:00

View File

@ -0,0 +1,3 @@
-- concat with empty string to defeat injectiveness of toString assumption.
SELECT concat('', toString(toDateTime('1981-09-29 00:00:00', 'Europe/Moscow') + INTERVAL number * 300 SECOND)) AS k FROM numbers(10000) GROUP BY k HAVING count() > 1 ORDER BY k;
SELECT concat('', toString(toDateTime('2018-09-19 00:00:00', 'Asia/Tehran') + INTERVAL number * 300 SECOND)) AS k FROM numbers(1000) GROUP BY k HAVING count() > 1 ORDER BY k;

View File

@ -160,16 +160,18 @@ h1, h2, h3, .md-logo {
.md-current-lang>svg {
filter: brightness(96%) grayscale(0%) !important;
}
.headerlink:hover {
text-decoration: none;
}
@media only screen and (min-width: 60em) {
#md-sidebar-flags {
display: none;
}
}
.headerlink:hover {
text-decoration: none;
}
@media print {
.md-typeset a:after {
content: "" !important;

View File

@ -24,6 +24,7 @@ public:
DateLUTImpl(const std::string & time_zone);
public:
/// The order of fields matters for alignment and sizeof.
struct Values
{
/// Least significat 32 bits from time_t at beginning of the day.
@ -42,10 +43,12 @@ public:
UInt8 days_in_month;
/// For days, when offset from UTC was changed due to daylight saving time or permanent change, following values could be non zero.
UInt16 time_at_offset_change; /// In seconds from beginning of the day. Assuming offset never changed close to the end of day (so, value < 65536).
Int16 amount_of_offset_change; /// Usually -3600 or 3600, but look at Lord Howe Island.
UInt32 time_at_offset_change; /// In seconds from beginning of the day.
};
static_assert(sizeof(Values) == 16);
private:
/// Lookup table is indexed by DayNum.
/// Day nums are the same in all time zones. 1970-01-01 is 0 and so on.
@ -247,8 +250,7 @@ public:
time_t res = t - lut[index].date;
/// NOTE We doesn't support cases when time change result in switching to previous day.
/// Data is cleaned to avoid these cases, so no underflow occurs here.
/// Data is cleaned to avoid possibility of underflow.
if (res >= lut[index].time_at_offset_change)
res += lut[index].amount_of_offset_change;

View File

@ -101,7 +101,7 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
/// when UTC offset was changed. Search is performed with 15-minute granularity, assuming it is enough.
time_t time_at_offset_change = 900;
while (time_at_offset_change < 65536)
while (time_at_offset_change < 86400)
{
auto utc_offset_at_current_time = cctz_time_zone.lookup(std::chrono::system_clock::from_time_t(
lut[i - 1].date + time_at_offset_change)).offset;
@ -112,17 +112,9 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_)
time_at_offset_change += 900;
}
lut[i - 1].time_at_offset_change = time_at_offset_change >= 65536 ? 0 : time_at_offset_change;
lut[i - 1].time_at_offset_change = time_at_offset_change;
/* std::cerr << lut[i - 1].year << "-" << int(lut[i - 1].month) << "-" << int(lut[i - 1].day_of_month)
<< " offset was changed at " << lut[i - 1].time_at_offset_change << " for " << lut[i - 1].amount_of_offset_change << " seconds.\n";*/
/** We doesn't support cases when time change results in switching to previous day.
* As an example, it was a case in Moscow at years 1981..1983 on October 1:
* clock was adjusted one hour backwards exactly at midnight (that was lead to extra hour 23 of Sep 30th).
* We must clean data (and we will make it slightly incorrect) to avoid these cases.
* (In previous example, it will lead to extra hour 0 of Sep 30 instead.)
*/
/// We doesn't support cases when time change results in switching to previous day.
if (static_cast<int>(lut[i - 1].time_at_offset_change) + static_cast<int>(lut[i - 1].amount_of_offset_change) < 0)
lut[i - 1].time_at_offset_change = -lut[i - 1].amount_of_offset_change;
}