time_facet.hpp
来自「support vector clustering for vc++」· HPP 代码 · 共 1,264 行 · 第 1/4 页
HPP
1,264 行
static std::locale::id id;
//! Constructor that takes a format string for a ptime
explicit time_input_facet(const string_type& format, ::size_t a_ref = 0)
: base_type(format, a_ref),
m_time_duration_format(default_time_duration_format)
{ }
explicit time_input_facet(const string_type& format,
const format_date_parser_type& date_parser,
const special_values_parser_type& sv_parser,
const period_parser_type& per_parser,
const date_gen_parser_type& date_gen_parser,
::size_t a_ref = 0)
: base_type(format,
date_parser,
sv_parser,
per_parser,
date_gen_parser,
a_ref),
m_time_duration_format(default_time_duration_format)
{}
//! sets default formats for ptime, local_date_time, and time_duration
explicit time_input_facet(::size_t a_ref = 0)
: base_type(default_time_input_format, a_ref),
m_time_duration_format(default_time_duration_format)
{ }
//! Set the format for time_duration
void time_duration_format(const char_type* const format) {
m_time_duration_format = format;
}
virtual void set_iso_format()
{
this->m_format = iso_time_format_specifier;
}
virtual void set_iso_extended_format()
{
this->m_format = iso_time_format_extended_specifier;
}
InItrT get(InItrT& sitr,
InItrT& stream_end,
std::ios_base& a_ios,
period_type& p) const
{
p = this->m_period_parser.get_period(sitr,
stream_end,
a_ios,
p,
time_duration_type::unit(),
*this);
return sitr;
}
//default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
//default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...]
InItrT get(InItrT& sitr,
InItrT& stream_end,
std::ios_base& a_ios,
time_duration_type& td) const
{
// skip leading whitespace
while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
bool use_current_char = false;
// num_get will consume the +/-, we may need a copy if special_value
char_type c = '\0';
if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
c = *sitr;
}
long hour = 0;
long min = 0;
long sec = 0;
typename time_duration_type::fractional_seconds_type frac(0);
typedef std::num_get<CharT, InItrT> num_get;
if(!std::has_facet<num_get>(a_ios.getloc())) {
num_get* ng = new num_get();
std::locale loc = std::locale(a_ios.getloc(), ng);
a_ios.imbue(loc);
}
const_itr itr(m_time_duration_format.begin());
while (itr != m_time_duration_format.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if (*itr != '%') {
switch(*itr) {
case 'H':
{
match_results mr;
hour = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
if(hour == -1){
return check_special_value(sitr, stream_end, td, c);
}
break;
}
case 'M':
{
match_results mr;
min = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
if(min == -1){
return check_special_value(sitr, stream_end, td, c);
}
break;
}
case 'S':
{
match_results mr;
sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
if(sec == -1){
return check_special_value(sitr, stream_end, td, c);
}
break;
}
case 's':
{
match_results mr;
sec = fixed_string_to_int<short, CharT>(sitr, stream_end, mr, 2);
if(sec == -1){
return check_special_value(sitr, stream_end, td, c);
}
// %s is the same as %S%f so we drop through into %f
//break;
}
case 'f':
{
// check for decimal, check special_values if missing
if(*sitr == '.') {
++sitr;
parse_frac_type(sitr, stream_end, frac);
// sitr will point to next expected char after this parsing
// is complete so no need to advance it
use_current_char = true;
}
else {
return check_special_value(sitr, stream_end, td, c);
}
break;
}
case 'F':
{
// check for decimal, skip if missing
if(*sitr == '.') {
++sitr;
parse_frac_type(sitr, stream_end, frac);
// sitr will point to next expected char after this parsing
// is complete so no need to advance it
use_current_char = true;
}
else {
// nothing was parsed so we don't want to advance sitr
use_current_char = true;
}
break;
}
default:
{} // ignore what we don't understand?
}// switch
}
else { // itr == '%', second consecutive
sitr++;
}
itr++; //advance past format specifier
}
else { //skip past chars in format and in buffer
itr++;
// set use_current_char when sitr is already
// pointing at the next character to process
if (use_current_char) {
use_current_char = false;
}
else {
sitr++;
}
}
}
td = time_duration_type(hour, min, sec, frac);
return sitr;
}
//! Parses a time object from the input stream
InItrT get(InItrT& sitr,
InItrT& stream_end,
std::ios_base& a_ios,
time_type& t) const
{
string_type tz_str;
return get(sitr, stream_end, a_ios, t, tz_str, false);
}
//! Expects a time_zone in the input stream
InItrT get_local_time(InItrT& sitr,
InItrT& stream_end,
std::ios_base& a_ios,
time_type& t,
string_type& tz_str) const
{
return get(sitr, stream_end, a_ios, t, tz_str, true);
}
protected:
InItrT get(InItrT& sitr,
InItrT& stream_end,
std::ios_base& a_ios,
time_type& t,
string_type& tz_str,
bool time_is_local) const
{
// skip leading whitespace
while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
bool use_current_char = false;
bool use_current_format_char = false; // used whith two character flags
// num_get will consume the +/-, we may need a copy if special_value
char_type c = '\0';
if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
c = *sitr;
}
// time elements
long hour = 0;
long min = 0;
long sec = 0;
typename time_duration_type::fractional_seconds_type frac(0);
// date elements
short day_of_year(0);
/* Initialized the following to their minimum values. These intermediate
* objects are used so we get specific exceptions when part of the input
* is unparsable.
* Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
year_type t_year(1400);
month_type t_month(1);
day_type t_day(1);
typedef std::num_get<CharT, InItrT> num_get;
if(!std::has_facet<num_get>(a_ios.getloc())) {
num_get* ng = new num_get();
std::locale loc = std::locale(a_ios.getloc(), ng);
a_ios.imbue(loc);
}
const_itr itr(this->m_format.begin());
while (itr != this->m_format.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if (*itr != '%') {
// the cases are grouped by date & time flags - not alphabetical order
switch(*itr) {
// date flags
case 'Y':
case 'y':
{
char_type cs[3] = { '%', *itr };
string_type s(cs);
match_results mr;
try {
t_year = this->m_parser.parse_year(sitr, stream_end, s, mr);
}
catch(std::out_of_range bad_year) { // base class for bad_year exception
if(this->m_sv_parser.match(sitr, stream_end, mr)) {
t = time_type(static_cast<special_values>(mr.current_match));
return sitr;
}
else {
throw; // rethrow bad_year
}
}
break;
}
case 'B':
case 'b':
case 'm':
{
char_type cs[3] = { '%', *itr };
string_type s(cs);
match_results mr;
try {
t_month = this->m_parser.parse_month(sitr, stream_end, s, mr);
}
catch(std::out_of_range bad_month) { // base class for bad_month exception
if(this->m_sv_parser.match(sitr, stream_end, mr)) {
t = time_type(static_cast<special_values>(mr.current_match));
return sitr;
}
else {
throw; // rethrow bad_year
}
}
// did m_parser already advance sitr to next char?
if(mr.has_remaining()) {
use_current_char = true;
}
break;
}
case 'a':
case 'A':
case 'w':
{
// weekday is not used in construction but we need to get it out of the stream
char_type cs[3] = { '%', *itr };
string_type s(cs);
match_results mr;
typename date_type::day_of_week_type wd(0);
try {
wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?