mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 08:31:03 +08:00
Merge branch 'gm_issue_19' of git://github.com/gmcode/date into gmcode-gm_issue_19
This commit is contained in:
commit
333894fc9d
16
date.h
16
date.h
@ -2245,8 +2245,15 @@ year_month_day::operator day_point() const noexcept
|
||||
auto const d = static_cast<unsigned>(d_);
|
||||
auto const era = (y >= 0 ? y : y-399) / 400;
|
||||
auto const yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
#endif
|
||||
auto const doy = (153*(m + (m > 2 ? -3u : 9)) + 2)/5 + d-1; // [0, 365]
|
||||
auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
|
||||
return day_point{days{era * 146097 + static_cast<int>(doe) - 719468}};
|
||||
}
|
||||
|
||||
@ -2350,7 +2357,14 @@ year_month_day::from_day_point(const day_point& dp) noexcept
|
||||
auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
|
||||
auto const mp = (5*doy + 2)/153; // [0, 11]
|
||||
auto const d = doy - (153*mp+2)/5 + 1; // [1, 31]
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
#endif
|
||||
auto const m = mp + (mp < 10 ? 3 : -9u); // [1, 12]
|
||||
#ifdef _MSVC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)};
|
||||
}
|
||||
|
||||
|
61
tz.cpp
61
tz.cpp
@ -61,6 +61,14 @@
|
||||
// gcc/mingw supports unistd.h on Win32 but MSVC does not.
|
||||
|
||||
#ifdef _WIN32
|
||||
// Prevent windows defining min/max macros that will interfere with C++ versions.
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
// We don't need everything Windows.h has to offer.
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
@ -318,7 +326,7 @@ static void get_windows_timezone_info(std::vector<timezone_info>& tz_list)
|
||||
if (!zone_key.get_binary("TZI", &tz.tzi, sizeof(TZI)))
|
||||
continue;
|
||||
#endif
|
||||
auto result = zone_key.close();
|
||||
zone_key.close();
|
||||
|
||||
tz_list.push_back(std::move(tz));
|
||||
}
|
||||
@ -1157,24 +1165,24 @@ Rule::split_overlaps(std::vector<Rule>& rules)
|
||||
return nm < x.name();
|
||||
}) - rules.cbegin());
|
||||
split_overlaps(rules, i, e);
|
||||
auto first = rules.cbegin() + static_cast<difference_type>(i);
|
||||
auto last = rules.cbegin() + static_cast<difference_type>(e);
|
||||
auto t = std::lower_bound(first, last, min_year);
|
||||
if (t > first+1)
|
||||
auto first_rule = rules.cbegin() + static_cast<difference_type>(i);
|
||||
auto last_rule = rules.cbegin() + static_cast<difference_type>(e);
|
||||
auto t = std::lower_bound(first_rule, last_rule, min_year);
|
||||
if (t > first_rule+1)
|
||||
{
|
||||
if (t == last || t->starting_year() >= min_year)
|
||||
if (t == last_rule || t->starting_year() >= min_year)
|
||||
--t;
|
||||
auto d = static_cast<std::size_t>(t - first);
|
||||
rules.erase(first, t);
|
||||
auto d = static_cast<std::size_t>(t - first_rule);
|
||||
rules.erase(first_rule, t);
|
||||
e -= d;
|
||||
}
|
||||
first = rules.cbegin() + static_cast<difference_type>(i);
|
||||
last = rules.cbegin() + static_cast<difference_type>(e);
|
||||
t = std::upper_bound(first, last, max_year);
|
||||
if (t != last)
|
||||
first_rule = rules.cbegin() + static_cast<difference_type>(i);
|
||||
last_rule = rules.cbegin() + static_cast<difference_type>(e);
|
||||
t = std::upper_bound(first_rule, last_rule, max_year);
|
||||
if (t != last_rule)
|
||||
{
|
||||
auto d = static_cast<std::size_t>(last - t);
|
||||
rules.erase(t, last);
|
||||
auto d = static_cast<std::size_t>(last_rule - t);
|
||||
rules.erase(t, last_rule);
|
||||
e -= d;
|
||||
}
|
||||
i = e;
|
||||
@ -1336,21 +1344,21 @@ find_previous_rule(const Rule* r, date::year y)
|
||||
// [first, last) all have the same name
|
||||
static
|
||||
std::pair<const Rule*, date::year>
|
||||
find_next_rule(const Rule* first, const Rule* last, const Rule* r, date::year y)
|
||||
find_next_rule(const Rule* first_rule, const Rule* last_rule, const Rule* r, date::year y)
|
||||
{
|
||||
using namespace date;
|
||||
if (y == r->ending_year())
|
||||
{
|
||||
if (r == last-1)
|
||||
if (r == last_rule-1)
|
||||
return {nullptr, year::max()};
|
||||
++r;
|
||||
if (y == r->ending_year())
|
||||
return {r, y};
|
||||
return {r, r->starting_year()};
|
||||
}
|
||||
if (r == last-1 || r->ending_year() < r[1].ending_year())
|
||||
if (r == last_rule-1 || r->ending_year() < r[1].ending_year())
|
||||
{
|
||||
while (r > first && r->starting_year() == r[-1].starting_year())
|
||||
while (r > first_rule && r->starting_year() == r[-1].starting_year())
|
||||
--r;
|
||||
return {r, ++y};
|
||||
}
|
||||
@ -1464,6 +1472,7 @@ find_rule_for_zone(const std::pair<const Rule*, const Rule*>& eqr,
|
||||
found = tp_loc < r->mdt().to_time_point(ry);
|
||||
break;
|
||||
default:
|
||||
found = false;
|
||||
assert(false);
|
||||
}
|
||||
if (found)
|
||||
@ -1478,16 +1487,16 @@ find_rule_for_zone(const std::pair<const Rule*, const Rule*>& eqr,
|
||||
|
||||
static
|
||||
Info
|
||||
find_rule(const std::pair<const Rule*, date::year>& first,
|
||||
const std::pair<const Rule*, date::year>& last,
|
||||
find_rule(const std::pair<const Rule*, date::year>& first_rule,
|
||||
const std::pair<const Rule*, date::year>& last_rule,
|
||||
const date::year& y, const std::chrono::seconds& offset,
|
||||
const MonthDayTime& mdt, const std::chrono::minutes& initial_save,
|
||||
const std::string& initial_abbrev)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
using namespace date;
|
||||
auto r = first.first;
|
||||
auto ry = first.second;
|
||||
auto r = first_rule.first;
|
||||
auto ry = first_rule.second;
|
||||
Info x{day_point(year::min()/boring_day), day_point(year::max()/boring_day),
|
||||
seconds{0}, initial_save, initial_abbrev};
|
||||
while (r != nullptr)
|
||||
@ -1495,9 +1504,9 @@ find_rule(const std::pair<const Rule*, date::year>& first,
|
||||
auto tr = r->mdt().to_sys(ry, offset, x.save);
|
||||
auto tx = mdt.to_sys(y, offset, x.save);
|
||||
// Find last rule where tx >= tr
|
||||
if (tx <= tr || (r == last.first && ry == last.second))
|
||||
if (tx <= tr || (r == last_rule.first && ry == last_rule.second))
|
||||
{
|
||||
if (tx < tr && r == first.first && ry == first.second)
|
||||
if (tx < tr && r == first_rule.first && ry == first_rule.second)
|
||||
{
|
||||
x.end = r->mdt().to_sys(ry, offset, x.save);
|
||||
break;
|
||||
@ -1509,12 +1518,12 @@ find_rule(const std::pair<const Rule*, date::year>& first,
|
||||
}
|
||||
// r != nullptr && tx >= tr (if tr were to be recomputed)
|
||||
auto prev_save = initial_save;
|
||||
if (!(r == first.first && ry == first.second))
|
||||
if (!(r == first_rule.first && ry == first_rule.second))
|
||||
prev_save = find_previous_rule(r, ry).first->save();
|
||||
x.begin = r->mdt().to_sys(ry, offset, prev_save);
|
||||
x.save = r->save();
|
||||
x.abbrev = r->abbrev();
|
||||
if (!(r == last.first && ry == last.second))
|
||||
if (!(r == last_rule.first && ry == last_rule.second))
|
||||
{
|
||||
std::tie(r, ry) = find_next_rule(r, ry); // can't return nullptr for r
|
||||
assert(r != nullptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user