mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 00:14:07 +08:00
parent
1ead6715de
commit
155c6b9e76
79
src/tz.cpp
79
src/tz.cpp
@ -581,27 +581,57 @@ get_tzdb_list()
|
|||||||
return tz_db;
|
return tz_db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
static
|
||||||
|
char
|
||||||
|
tolower(char c)
|
||||||
|
{
|
||||||
|
return static_cast<char>(std::tolower(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
static
|
||||||
|
void
|
||||||
|
tolower(std::string& s)
|
||||||
|
{
|
||||||
|
for (auto& c : s)
|
||||||
|
c = tolower(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
static
|
static
|
||||||
std::string
|
std::string
|
||||||
parse3(std::istream& in)
|
get_alpha_word(std::istream& in)
|
||||||
{
|
{
|
||||||
std::string r(3, ' ');
|
std::string s;
|
||||||
ws(in);
|
while (!in.eof() && std::isalpha(in.peek()))
|
||||||
r[0] = static_cast<char>(in.get());
|
s.push_back(static_cast<char>(in.get()));
|
||||||
r[1] = static_cast<char>(in.get());
|
return s;
|
||||||
r[2] = static_cast<char>(in.get());
|
}
|
||||||
return r;
|
|
||||||
|
inline
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
is_prefix_of(std::string const& key, std::string const& value)
|
||||||
|
{
|
||||||
|
return key.compare(0, key.size(), value, 0, key.size()) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
unsigned
|
unsigned
|
||||||
parse_month(std::istream& in)
|
parse_month(std::istream& in)
|
||||||
{
|
{
|
||||||
CONSTDATA char*const month_names[] =
|
static std::string const month_names[] =
|
||||||
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
{"january", "february", "march", "april", "may", "june",
|
||||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
"july", "august", "september", "october", "november", "december"};
|
||||||
auto s = parse3(in);
|
auto s = get_alpha_word(in);
|
||||||
auto m = std::find(std::begin(month_names), std::end(month_names), s) - month_names;
|
tolower(s);
|
||||||
|
auto m = std::find_if(std::begin(month_names), std::end(month_names),
|
||||||
|
[&s](std::string const& m)
|
||||||
|
{
|
||||||
|
return is_prefix_of(s, m);
|
||||||
|
})
|
||||||
|
- month_names;
|
||||||
if (m >= std::end(month_names) - std::begin(month_names))
|
if (m >= std::end(month_names) - std::begin(month_names))
|
||||||
throw std::runtime_error("oops: bad month name: " + s);
|
throw std::runtime_error("oops: bad month name: " + s);
|
||||||
return static_cast<unsigned>(++m);
|
return static_cast<unsigned>(++m);
|
||||||
@ -817,10 +847,16 @@ static
|
|||||||
unsigned
|
unsigned
|
||||||
parse_dow(std::istream& in)
|
parse_dow(std::istream& in)
|
||||||
{
|
{
|
||||||
CONSTDATA char*const dow_names[] =
|
static std::string const dow_names[] =
|
||||||
{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
|
{"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
|
||||||
auto s = parse3(in);
|
auto s = get_alpha_word(in);
|
||||||
auto dow = std::find(std::begin(dow_names), std::end(dow_names), s) - dow_names;
|
tolower(s);
|
||||||
|
auto dow = std::find_if(std::begin(dow_names), std::end(dow_names),
|
||||||
|
[&s](std::string const& dow)
|
||||||
|
{
|
||||||
|
return is_prefix_of(s, dow);
|
||||||
|
})
|
||||||
|
- dow_names;
|
||||||
if (dow >= std::end(dow_names) - std::begin(dow_names))
|
if (dow >= std::end(dow_names) - std::begin(dow_names))
|
||||||
throw std::runtime_error("oops: bad dow name: " + s);
|
throw std::runtime_error("oops: bad dow name: " + s);
|
||||||
return static_cast<unsigned>(dow);
|
return static_cast<unsigned>(dow);
|
||||||
@ -1081,7 +1117,7 @@ detail::operator>>(std::istream& is, MonthDayTime& x)
|
|||||||
auto m = parse_month(is);
|
auto m = parse_month(is);
|
||||||
if (!is.eof() && ws(is) && !is.eof() && is.peek() != '#')
|
if (!is.eof() && ws(is) && !is.eof() && is.peek() != '#')
|
||||||
{
|
{
|
||||||
if (is.peek() == 'l')
|
if (tolower(is.peek()) == 'l')
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
is.get();
|
is.get();
|
||||||
@ -3642,22 +3678,23 @@ init_tzdb()
|
|||||||
std::istringstream in(line);
|
std::istringstream in(line);
|
||||||
std::string word;
|
std::string word;
|
||||||
in >> word;
|
in >> word;
|
||||||
if (word == "Rule")
|
tolower(word);
|
||||||
|
if (is_prefix_of(word, "rule"))
|
||||||
{
|
{
|
||||||
db->rules.push_back(Rule(line));
|
db->rules.push_back(Rule(line));
|
||||||
continue_zone = false;
|
continue_zone = false;
|
||||||
}
|
}
|
||||||
else if (word == "Link")
|
else if (is_prefix_of(word, "link"))
|
||||||
{
|
{
|
||||||
db->links.push_back(time_zone_link(line));
|
db->links.push_back(time_zone_link(line));
|
||||||
continue_zone = false;
|
continue_zone = false;
|
||||||
}
|
}
|
||||||
else if (word == "Leap")
|
else if (is_prefix_of(word, "leap"))
|
||||||
{
|
{
|
||||||
db->leap_seconds.push_back(leap_second(line, detail::undocumented{}));
|
db->leap_seconds.push_back(leap_second(line, detail::undocumented{}));
|
||||||
continue_zone = false;
|
continue_zone = false;
|
||||||
}
|
}
|
||||||
else if (word == "Zone")
|
else if (is_prefix_of(word, "zone"))
|
||||||
{
|
{
|
||||||
db->zones.push_back(time_zone(line, detail::undocumented{}));
|
db->zones.push_back(time_zone(line, detail::undocumented{}));
|
||||||
continue_zone = true;
|
continue_zone = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user