mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 16:41:04 +08:00
Create %Ez & %Oz to put ':' in offset for format and parse.
This commit is contained in:
parent
3293637e70
commit
09cf3bba8d
134
tz.h
134
tz.h
@ -48,6 +48,8 @@ On Windows, the names are never "Standard" so mapping is always required.
|
|||||||
Technically any OS may use the mapping process but currently only Windows does use it.
|
Technically any OS may use the mapping process but currently only Windows does use it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifndef TIMEZONE_MAPPING
|
#ifndef TIMEZONE_MAPPING
|
||||||
#define TIMEZONE_MAPPING 1
|
#define TIMEZONE_MAPPING 1
|
||||||
@ -1091,31 +1093,44 @@ format(const std::locale& loc, std::basic_string<CharT, Traits> format,
|
|||||||
// Handle these specially
|
// Handle these specially
|
||||||
// %S append fractional seconds if tp has precision finer than seconds
|
// %S append fractional seconds if tp has precision finer than seconds
|
||||||
// %T append fractional seconds if tp has precision finer than seconds
|
// %T append fractional seconds if tp has precision finer than seconds
|
||||||
// %z replace with offset from zone
|
// %z replace with offset from zone on +/-hhmm format
|
||||||
|
// %Ez, %Oz replace with offset from zone on +/-hh:mm format
|
||||||
// %Z replace with abbreviation from zone
|
// %Z replace with abbreviation from zone
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
auto command = false;
|
||||||
|
auto modified = false;
|
||||||
for (std::size_t i = 0; i < format.size(); ++i)
|
for (std::size_t i = 0; i < format.size(); ++i)
|
||||||
{
|
{
|
||||||
if (format[i] == '%' && i < format.size()-1)
|
switch (format[i])
|
||||||
{
|
{
|
||||||
switch (format[i+1])
|
case '%':
|
||||||
|
command = true;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
case 'E':
|
||||||
|
modified = true;
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
case 'T':
|
||||||
|
if (command && !modified && ratio_less<typename Duration::period, ratio<1>>::value)
|
||||||
|
{
|
||||||
|
basic_ostringstream<CharT, Traits> os;
|
||||||
|
os.imbue(loc);
|
||||||
|
os << make_time(tp - floor<seconds>(tp));
|
||||||
|
auto s = os.str();
|
||||||
|
s.erase(0, 8);
|
||||||
|
format.insert(i+1, s);
|
||||||
|
i += s.size() - 1;
|
||||||
|
}
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
if (command)
|
||||||
{
|
{
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
if (ratio_less<typename Duration::period, ratio<1>>::value)
|
|
||||||
{
|
|
||||||
basic_ostringstream<CharT, Traits> os;
|
|
||||||
os.imbue(loc);
|
|
||||||
os << make_time(tp - floor<seconds>(tp));
|
|
||||||
auto s = os.str();
|
|
||||||
s.erase(0, 8);
|
|
||||||
format.insert(i+2, s);
|
|
||||||
i += 2 + s.size() - 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'z':
|
|
||||||
if (zone == nullptr)
|
if (zone == nullptr)
|
||||||
throw std::runtime_error("Can not format local_time with %z");
|
throw std::runtime_error("Can not format local_time with %z");
|
||||||
else
|
else
|
||||||
@ -1127,12 +1142,18 @@ format(const std::locale& loc, std::basic_string<CharT, Traits> format,
|
|||||||
os << '+';
|
os << '+';
|
||||||
os << make_time(offset);
|
os << make_time(offset);
|
||||||
auto s = os.str();
|
auto s = os.str();
|
||||||
s.erase(s.find(':'), 1);
|
if (!modified)
|
||||||
format.replace(i, 2, s);
|
s.erase(s.find(':'), 1);
|
||||||
|
format.replace(i - 1 - modified, 2 + modified, s);
|
||||||
i += s.size() - 1;
|
i += s.size() - 1;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 'Z':
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
case 'Z':
|
||||||
|
if (command && !modified)
|
||||||
|
{
|
||||||
if (zone == nullptr)
|
if (zone == nullptr)
|
||||||
throw std::runtime_error("Can not format local_time with %z");
|
throw std::runtime_error("Can not format local_time with %z");
|
||||||
else
|
else
|
||||||
@ -1142,8 +1163,14 @@ format(const std::locale& loc, std::basic_string<CharT, Traits> format,
|
|||||||
(info.abbrev.begin(), info.abbrev.end()));
|
(info.abbrev.begin(), info.abbrev.end()));
|
||||||
i += info.abbrev.size() - 1;
|
i += info.abbrev.size() - 1;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto& f = use_facet<time_put<CharT>>(loc);
|
auto& f = use_facet<time_put<CharT>>(loc);
|
||||||
@ -1296,21 +1323,30 @@ parse(std::basic_istream<CharT, Traits>& is,
|
|||||||
auto b = format.data();
|
auto b = format.data();
|
||||||
auto i = b;
|
auto i = b;
|
||||||
auto e = b + format.size();
|
auto e = b + format.size();
|
||||||
|
auto command = false;
|
||||||
|
auto modified = false;
|
||||||
for (; i < e; ++i)
|
for (; i < e; ++i)
|
||||||
{
|
{
|
||||||
if (*i == '%' && i < e-1)
|
switch (*i)
|
||||||
{
|
{
|
||||||
switch (i[1])
|
case '%':
|
||||||
|
command = true;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
case 'O':
|
||||||
|
case 'E':
|
||||||
|
modified = true;
|
||||||
|
break;
|
||||||
|
case 'T':
|
||||||
|
case 'S':
|
||||||
|
if (command && !modified)
|
||||||
{
|
{
|
||||||
case 'T':
|
f.get(is, 0, is, err, &tm, b, i-1);
|
||||||
case 'S':
|
|
||||||
f.get(is, 0, is, err, &tm, b, i);
|
|
||||||
++i;
|
|
||||||
b = i+1;
|
b = i+1;
|
||||||
if (*i == 'T')
|
if (*i == 'T')
|
||||||
{
|
{
|
||||||
const CharT hm[] = {'%', 'H', ':', '%', 'M', ':', 0};
|
const CharT hm[] = {'%', 'H', ':', '%', 'M', ':'};
|
||||||
f.get(is, 0, is, err, &tm, hm, hm);
|
f.get(is, 0, is, err, &tm, hm, hm+6);
|
||||||
}
|
}
|
||||||
if (ratio_less<typename Duration::period, ratio<1>>::value)
|
if (ratio_less<typename Duration::period, ratio<1>>::value)
|
||||||
{
|
{
|
||||||
@ -1326,10 +1362,14 @@ parse(std::basic_istream<CharT, Traits>& is,
|
|||||||
const CharT hm[] = {'%', 'S'};
|
const CharT hm[] = {'%', 'S'};
|
||||||
f.get(is, 0, is, err, &tm, hm, hm+2);
|
f.get(is, 0, is, err, &tm, hm, hm+2);
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 'z':
|
command = false;
|
||||||
f.get(is, 0, is, err, &tm, b, i);
|
modified = false;
|
||||||
++i;
|
break;
|
||||||
|
case 'z':
|
||||||
|
if (command)
|
||||||
|
{
|
||||||
|
f.get(is, 0, is, err, &tm, b, i-1-modified);
|
||||||
b = i+1;
|
b = i+1;
|
||||||
if ((err & ios_base::failbit) == 0)
|
if ((err & ios_base::failbit) == 0)
|
||||||
{
|
{
|
||||||
@ -1338,12 +1378,16 @@ parse(std::basic_istream<CharT, Traits>& is,
|
|||||||
if (!is.fail() && (sign == '+' || sign == '-'))
|
if (!is.fail() && (sign == '+' || sign == '-'))
|
||||||
{
|
{
|
||||||
char h1, h0, m1, m0;
|
char h1, h0, m1, m0;
|
||||||
|
char colon = '\0';
|
||||||
h1 = static_cast<char>(is.get());
|
h1 = static_cast<char>(is.get());
|
||||||
h0 = static_cast<char>(is.get());
|
h0 = static_cast<char>(is.get());
|
||||||
|
if (modified)
|
||||||
|
colon = static_cast<char>(is.get());
|
||||||
m1 = static_cast<char>(is.get());
|
m1 = static_cast<char>(is.get());
|
||||||
m0 = static_cast<char>(is.get());
|
m0 = static_cast<char>(is.get());
|
||||||
if (!is.fail() && std::isdigit(h1) && std::isdigit(h0)
|
if (!is.fail() && std::isdigit(h1) && std::isdigit(h0)
|
||||||
&& std::isdigit(m1) && std::isdigit(m0))
|
&& std::isdigit(m1) && std::isdigit(m0)
|
||||||
|
&& (!modified || colon == ':'))
|
||||||
{
|
{
|
||||||
temp_offset = 10*hours{h1 - '0'} + hours{h0 - '0'} +
|
temp_offset = 10*hours{h1 - '0'} + hours{h0 - '0'} +
|
||||||
10*minutes{m1 - '0'} + minutes{m0 - '0'};
|
10*minutes{m1 - '0'} + minutes{m0 - '0'};
|
||||||
@ -1356,10 +1400,14 @@ parse(std::basic_istream<CharT, Traits>& is,
|
|||||||
else
|
else
|
||||||
err |= ios_base::failbit;
|
err |= ios_base::failbit;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 'Z':
|
command = false;
|
||||||
f.get(is, 0, is, err, &tm, b, i);
|
modified = false;
|
||||||
++i;
|
break;
|
||||||
|
case 'Z':
|
||||||
|
if (command && !modified)
|
||||||
|
{
|
||||||
|
f.get(is, 0, is, err, &tm, b, i-1);
|
||||||
b = i+1;
|
b = i+1;
|
||||||
if ((err & ios_base::failbit) == 0)
|
if ((err & ios_base::failbit) == 0)
|
||||||
{
|
{
|
||||||
@ -1367,8 +1415,14 @@ parse(std::basic_istream<CharT, Traits>& is,
|
|||||||
if (is.fail())
|
if (is.fail())
|
||||||
err |= ios_base::failbit;
|
err |= ios_base::failbit;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
command = false;
|
||||||
|
modified = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((err & ios_base::failbit) == 0)
|
if ((err & ios_base::failbit) == 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user