#ifndef _DATE_TIME_FACET__HPP__ | |
#define _DATE_TIME_FACET__HPP__ | |
/* Copyright (c) 2004-2005 CrystalClear Software, Inc. | |
* Use, modification and distribution is subject to the | |
* Boost Software License, Version 1.0. (See accompanying | |
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
* Author: Martin Andrian, Jeff Garland, Bart Garst | |
* $Date: 2010-06-09 12:39:31 -0400 (Wed, 09 Jun 2010) $ | |
*/ | |
#include <cctype> | |
#include <locale> | |
#include <limits> | |
#include <string> | |
#include <sstream> | |
#include <iomanip> | |
#include <iterator> // i/ostreambuf_iterator | |
#include <exception> | |
#include <boost/assert.hpp> | |
#include <boost/lexical_cast.hpp> | |
#include <boost/throw_exception.hpp> | |
#include <boost/range/as_literal.hpp> | |
#include <boost/algorithm/string/erase.hpp> | |
#include <boost/algorithm/string/replace.hpp> | |
#include <boost/date_time/compiler_config.hpp> | |
#include <boost/date_time/date_facet.hpp> | |
#include <boost/date_time/string_convert.hpp> | |
#include <boost/date_time/special_defs.hpp> | |
#include <boost/date_time/time_resolution_traits.hpp> // absolute_value | |
namespace boost { | |
namespace date_time { | |
template <class CharT> | |
struct time_formats { | |
public: | |
typedef CharT char_type; | |
static const char_type fractional_seconds_format[3]; // f | |
static const char_type fractional_seconds_or_none_format[3]; // F | |
static const char_type seconds_with_fractional_seconds_format[3]; // s | |
static const char_type seconds_format[3]; // S | |
static const char_type hours_format[3]; // H | |
static const char_type unrestricted_hours_format[3]; // O | |
static const char_type full_24_hour_time_format[3]; // T | |
static const char_type full_24_hour_time_expanded_format[9]; // HH:MM:SS | |
static const char_type short_24_hour_time_format[3]; // R | |
static const char_type short_24_hour_time_expanded_format[6]; // HH:MM | |
static const char_type standard_format[9]; // x X | |
static const char_type zone_abbrev_format[3]; // z | |
static const char_type zone_name_format[3]; // Z | |
static const char_type zone_iso_format[3]; // q | |
static const char_type zone_iso_extended_format[3]; // Q | |
static const char_type posix_zone_string_format[4]; // ZP | |
static const char_type duration_sign_negative_only[3]; // - | |
static const char_type duration_sign_always[3]; // + | |
static const char_type duration_seperator[2]; | |
static const char_type negative_sign[2]; //- | |
static const char_type positive_sign[2]; //+ | |
static const char_type iso_time_format_specifier[18]; | |
static const char_type iso_time_format_extended_specifier[22]; | |
//default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] | |
static const char_type default_time_format[23]; | |
// default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev | |
static const char_type default_time_input_format[24]; | |
//default time_duration format is HH:MM:SS[.fff...] | |
static const char_type default_time_duration_format[11]; | |
}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::fractional_seconds_format[3] = {'%','f'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::fractional_seconds_or_none_format[3] = {'%','F'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::seconds_with_fractional_seconds_format[3] = {'%','s'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::seconds_format[3] = {'%','S'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::hours_format[3] = {'%','H'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::unrestricted_hours_format[3] = {'%','O'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::full_24_hour_time_format[3] = {'%','T'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::full_24_hour_time_expanded_format[9] = | |
{'%','H',':','%','M',':','%','S'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::short_24_hour_time_format[3] = {'%','R'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::short_24_hour_time_expanded_format[6] = | |
{'%','H',':','%','M'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
//time_formats<CharT>::standard_format[5] = {'%','c',' ','%','z'}; | |
time_formats<CharT>::standard_format[9] = {'%','x',' ','%','X',' ','%','z'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::zone_abbrev_format[3] = {'%','z'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::zone_name_format[3] = {'%','Z'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::zone_iso_format[3] = {'%','q'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::zone_iso_extended_format[3] ={'%','Q'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::posix_zone_string_format[4] ={'%','Z','P'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::duration_seperator[2] = {':'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::negative_sign[2] = {'-'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::positive_sign[2] = {'+'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::duration_sign_negative_only[3] ={'%','-'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::duration_sign_always[3] ={'%','+'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::iso_time_format_specifier[18] = | |
{'%', 'Y', '%', 'm', '%', 'd', 'T', | |
'%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' }; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::iso_time_format_extended_specifier[22] = | |
{'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', | |
'%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::default_time_format[23] = | |
{'%','Y','-','%','b','-','%','d',' ', | |
'%','H',':','%','M',':','%','S','%','F',' ','%','z'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::default_time_input_format[24] = | |
{'%','Y','-','%','b','-','%','d',' ', | |
'%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'}; | |
template <class CharT> | |
const typename time_formats<CharT>::char_type | |
time_formats<CharT>::default_time_duration_format[11] = | |
{'%','O',':','%','M',':','%','S','%','F'}; | |
/*! Facet used for format-based output of time types | |
* This class provides for the use of format strings to output times. In addition | |
* to the flags for formatting date elements, the following are the allowed format flags: | |
* - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z") | |
* - %f => fractional seconds ".123456" | |
* - %F => fractional seconds or none: like frac sec but empty if frac sec == 0 | |
* - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f) | |
* - %S => seconds "02" | |
* - %z => abbreviated time zone "EDT" | |
* - %Z => full time zone name "Eastern Daylight Time" | |
*/ | |
template <class time_type, | |
class CharT, | |
class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > > | |
class time_facet : | |
public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> { | |
typedef time_formats< CharT > formats_type; | |
public: | |
typedef typename time_type::date_type date_type; | |
typedef typename time_type::time_duration_type time_duration_type; | |
typedef boost::date_time::period<time_type,time_duration_type> period_type; | |
typedef boost::date_time::date_facet<typename time_type::date_type, CharT, OutItrT> base_type; | |
typedef typename base_type::string_type string_type; | |
typedef typename base_type::char_type char_type; | |
typedef typename base_type::period_formatter_type period_formatter_type; | |
typedef typename base_type::special_values_formatter_type special_values_formatter_type; | |
typedef typename base_type::date_gen_formatter_type date_gen_formatter_type; | |
static const char_type* fractional_seconds_format; // %f | |
static const char_type* fractional_seconds_or_none_format; // %F | |
static const char_type* seconds_with_fractional_seconds_format; // %s | |
static const char_type* seconds_format; // %S | |
static const char_type* hours_format; // %H | |
static const char_type* unrestricted_hours_format; // %O | |
static const char_type* standard_format; // %x X | |
static const char_type* zone_abbrev_format; // %z | |
static const char_type* zone_name_format; // %Z | |
static const char_type* zone_iso_format; // %q | |
static const char_type* zone_iso_extended_format; // %Q | |
static const char_type* posix_zone_string_format; // %ZP | |
static const char_type* duration_seperator; | |
static const char_type* duration_sign_always; // %+ | |
static const char_type* duration_sign_negative_only; // %- | |
static const char_type* negative_sign; //- | |
static const char_type* positive_sign; //+ | |
static const char_type* iso_time_format_specifier; | |
static const char_type* iso_time_format_extended_specifier; | |
//default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] | |
static const char_type* default_time_format; | |
//default time_duration format is HH:MM:SS[.fff...] | |
static const char_type* default_time_duration_format; | |
static std::locale::id id; | |
#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) | |
std::locale::id& __get_id (void) const { return id; } | |
#endif | |
//! sets default formats for ptime, local_date_time, and time_duration | |
explicit time_facet(::size_t a_ref = 0) | |
: base_type(default_time_format, period_formatter_type(), special_values_formatter_type(), date_gen_formatter_type(), a_ref), | |
m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) | |
{} | |
//! Construct the facet with an explicitly specified format | |
explicit time_facet(const char_type* a_format, | |
period_formatter_type period_formatter = period_formatter_type(), | |
const special_values_formatter_type& special_value_formatter = special_values_formatter_type(), | |
date_gen_formatter_type dg_formatter = date_gen_formatter_type(), | |
::size_t a_ref = 0) | |
: base_type(a_format, | |
period_formatter, | |
special_value_formatter, | |
dg_formatter, | |
a_ref), | |
m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) | |
{} | |
//! Changes 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; | |
} | |
OutItrT put(OutItrT a_next, | |
std::ios_base& a_ios, | |
char_type a_fill, | |
const time_type& a_time) const | |
{ | |
if (a_time.is_special()) { | |
return this->do_put_special(a_next, a_ios, a_fill, | |
a_time.date().as_special()); | |
} | |
string_type format(this->m_format); | |
// %T and %R have to be replaced here since they are not standard | |
boost::algorithm::replace_all(format, | |
boost::as_literal(formats_type::full_24_hour_time_format), | |
boost::as_literal(formats_type::full_24_hour_time_expanded_format)); | |
boost::algorithm::replace_all(format, | |
boost::as_literal(formats_type::short_24_hour_time_format), | |
boost::as_literal(formats_type::short_24_hour_time_expanded_format)); | |
string_type frac_str; | |
if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { | |
// replace %s with %S.nnn | |
frac_str = | |
fractional_seconds_as_string(a_time.time_of_day(), false); | |
char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | |
string_type replace_string(seconds_format); | |
replace_string += sep; | |
replace_string += frac_str; | |
boost::algorithm::replace_all(format, | |
seconds_with_fractional_seconds_format, | |
replace_string); | |
} | |
/* NOTE: replacing posix_zone_string_format must be done BEFORE | |
* zone_name_format: "%ZP" & "%Z", if Z is checked first it will | |
* incorrectly replace a zone_name where a posix_string should go */ | |
if (format.find(posix_zone_string_format) != string_type::npos) { | |
if(a_time.zone_abbrev().empty()) { | |
// if zone_abbrev() returns an empty string, we want to | |
// erase posix_zone_string_format from format | |
boost::algorithm::erase_all(format, posix_zone_string_format); | |
} | |
else{ | |
boost::algorithm::replace_all(format, | |
posix_zone_string_format, | |
a_time.zone_as_posix_string()); | |
} | |
} | |
if (format.find(zone_name_format) != string_type::npos) { | |
if(a_time.zone_name().empty()) { | |
/* TODO: this'll probably create problems if a user places | |
* the zone_*_format flag in the format with a ptime. This | |
* code removes the flag from the default formats */ | |
// if zone_name() returns an empty string, we want to | |
// erase zone_name_format & one preceeding space | |
std::basic_ostringstream<char_type> ss; | |
ss << ' ' << zone_name_format; | |
boost::algorithm::erase_all(format, ss.str()); | |
} | |
else{ | |
boost::algorithm::replace_all(format, | |
zone_name_format, | |
a_time.zone_name()); | |
} | |
} | |
if (format.find(zone_abbrev_format) != string_type::npos) { | |
if(a_time.zone_abbrev(false).empty()) { | |
/* TODO: this'll probably create problems if a user places | |
* the zone_*_format flag in the format with a ptime. This | |
* code removes the flag from the default formats */ | |
// if zone_abbrev() returns an empty string, we want to | |
// erase zone_abbrev_format & one preceeding space | |
std::basic_ostringstream<char_type> ss; | |
ss << ' ' << zone_abbrev_format; | |
boost::algorithm::erase_all(format, ss.str()); | |
} | |
else{ | |
boost::algorithm::replace_all(format, | |
zone_abbrev_format, | |
a_time.zone_abbrev(false)); | |
} | |
} | |
if (format.find(zone_iso_extended_format) != string_type::npos) { | |
if(a_time.zone_name(true).empty()) { | |
/* TODO: this'll probably create problems if a user places | |
* the zone_*_format flag in the format with a ptime. This | |
* code removes the flag from the default formats */ | |
// if zone_name() returns an empty string, we want to | |
// erase zone_iso_extended_format from format | |
boost::algorithm::erase_all(format, zone_iso_extended_format); | |
} | |
else{ | |
boost::algorithm::replace_all(format, | |
zone_iso_extended_format, | |
a_time.zone_name(true)); | |
} | |
} | |
if (format.find(zone_iso_format) != string_type::npos) { | |
if(a_time.zone_abbrev(true).empty()) { | |
/* TODO: this'll probably create problems if a user places | |
* the zone_*_format flag in the format with a ptime. This | |
* code removes the flag from the default formats */ | |
// if zone_abbrev() returns an empty string, we want to | |
// erase zone_iso_format from format | |
boost::algorithm::erase_all(format, zone_iso_format); | |
} | |
else{ | |
boost::algorithm::replace_all(format, | |
zone_iso_format, | |
a_time.zone_abbrev(true)); | |
} | |
} | |
if (format.find(fractional_seconds_format) != string_type::npos) { | |
// replace %f with nnnnnnn | |
if (frac_str.empty()) { | |
frac_str = fractional_seconds_as_string(a_time.time_of_day(), false); | |
} | |
boost::algorithm::replace_all(format, | |
fractional_seconds_format, | |
frac_str); | |
} | |
if (format.find(fractional_seconds_or_none_format) != string_type::npos) { | |
// replace %F with nnnnnnn or nothing if fs == 0 | |
frac_str = | |
fractional_seconds_as_string(a_time.time_of_day(), true); | |
if (frac_str.size()) { | |
char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | |
string_type replace_string; | |
replace_string += sep; | |
replace_string += frac_str; | |
boost::algorithm::replace_all(format, | |
fractional_seconds_or_none_format, | |
replace_string); | |
} | |
else { | |
boost::algorithm::erase_all(format, | |
fractional_seconds_or_none_format); | |
} | |
} | |
return this->do_put_tm(a_next, a_ios, a_fill, | |
to_tm(a_time), format); | |
} | |
//! put function for time_duration | |
OutItrT put(OutItrT a_next, | |
std::ios_base& a_ios, | |
char_type a_fill, | |
const time_duration_type& a_time_dur) const | |
{ | |
if (a_time_dur.is_special()) { | |
return this->do_put_special(a_next, a_ios, a_fill, | |
a_time_dur.get_rep().as_special()); | |
} | |
string_type format(m_time_duration_format); | |
if (a_time_dur.is_negative()) { | |
// replace %- with minus sign. Should we use the numpunct facet? | |
boost::algorithm::replace_all(format, | |
duration_sign_negative_only, | |
negative_sign); | |
// remove all the %+ in the string with '-' | |
boost::algorithm::replace_all(format, | |
duration_sign_always, | |
negative_sign); | |
} | |
else { //duration is positive | |
// remove all the %- combos from the string | |
boost::algorithm::erase_all(format, duration_sign_negative_only); | |
// remove all the %+ in the string with '+' | |
boost::algorithm::replace_all(format, | |
duration_sign_always, | |
positive_sign); | |
} | |
// %T and %R have to be replaced here since they are not standard | |
boost::algorithm::replace_all(format, | |
boost::as_literal(formats_type::full_24_hour_time_format), | |
boost::as_literal(formats_type::full_24_hour_time_expanded_format)); | |
boost::algorithm::replace_all(format, | |
boost::as_literal(formats_type::short_24_hour_time_format), | |
boost::as_literal(formats_type::short_24_hour_time_expanded_format)); | |
/* | |
* It is possible for a time duration to span more then 24 hours. | |
* Standard time_put::put is obliged to behave the same as strftime | |
* (See ISO 14882-2003 22.2.5.3.1 par. 1) and strftime's behavior is | |
* unspecified for the case when tm_hour field is outside 0-23 range | |
* (See ISO 9899-1999 7.23.3.5 par. 3). So we must output %H and %O | |
* here ourself. | |
*/ | |
string_type hours_str; | |
if (format.find(unrestricted_hours_format) != string_type::npos) { | |
hours_str = hours_as_string(a_time_dur); | |
boost::algorithm::replace_all(format, unrestricted_hours_format, hours_str); | |
} | |
// We still have to process restricted hours format specifier. In order to | |
// support parseability of durations in ISO format (%H%M%S), we'll have to | |
// restrict the stringified hours length to 2 characters. | |
if (format.find(hours_format) != string_type::npos) { | |
if (hours_str.empty()) | |
hours_str = hours_as_string(a_time_dur); | |
BOOST_ASSERT(hours_str.length() <= 2); | |
boost::algorithm::replace_all(format, hours_format, hours_str); | |
} | |
string_type frac_str; | |
if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { | |
// replace %s with %S.nnn | |
frac_str = | |
fractional_seconds_as_string(a_time_dur, false); | |
char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | |
string_type replace_string(seconds_format); | |
replace_string += sep; | |
replace_string += frac_str; | |
boost::algorithm::replace_all(format, | |
seconds_with_fractional_seconds_format, | |
replace_string); | |
} | |
if (format.find(fractional_seconds_format) != string_type::npos) { | |
// replace %f with nnnnnnn | |
if (!frac_str.size()) { | |
frac_str = fractional_seconds_as_string(a_time_dur, false); | |
} | |
boost::algorithm::replace_all(format, | |
fractional_seconds_format, | |
frac_str); | |
} | |
if (format.find(fractional_seconds_or_none_format) != string_type::npos) { | |
// replace %F with nnnnnnn or nothing if fs == 0 | |
frac_str = | |
fractional_seconds_as_string(a_time_dur, true); | |
if (frac_str.size()) { | |
char_type sep = std::use_facet<std::numpunct<char_type> >(a_ios.getloc()).decimal_point(); | |
string_type replace_string; | |
replace_string += sep; | |
replace_string += frac_str; | |
boost::algorithm::replace_all(format, | |
fractional_seconds_or_none_format, | |
replace_string); | |
} | |
else { | |
boost::algorithm::erase_all(format, | |
fractional_seconds_or_none_format); | |
} | |
} | |
return this->do_put_tm(a_next, a_ios, a_fill, | |
to_tm(a_time_dur), format); | |
} | |
OutItrT put(OutItrT next, std::ios_base& a_ios, | |
char_type fill, const period_type& p) const | |
{ | |
return this->m_period_formatter.put_period(next, a_ios, fill,p,*this); | |
} | |
protected: | |
static | |
string_type | |
fractional_seconds_as_string(const time_duration_type& a_time, | |
bool null_when_zero) | |
{ | |
typename time_duration_type::fractional_seconds_type frac_sec = | |
a_time.fractional_seconds(); | |
if (null_when_zero && (frac_sec == 0)) { | |
return string_type(); | |
} | |
//make sure there is no sign | |
return integral_as_string( | |
date_time::absolute_value(frac_sec), | |
time_duration_type::num_fractional_digits()); | |
} | |
static | |
string_type | |
hours_as_string(const time_duration_type& a_time, int width = 2) | |
{ | |
return integral_as_string(date_time::absolute_value(a_time.hours()), width); | |
} | |
template< typename IntT > | |
static | |
string_type | |
integral_as_string(IntT val, int width = 2) | |
{ | |
std::basic_ostringstream<char_type> ss; | |
ss.imbue(std::locale::classic()); // don't want any formatting | |
ss << std::setw(width) | |
<< std::setfill(static_cast<char_type>('0')); | |
#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) | |
// JDG [7/6/02 VC++ compatibility] | |
char_type buff[34]; | |
ss << _i64toa(static_cast<boost::int64_t>(val), buff, 10); | |
#else | |
ss << val; | |
#endif | |
return ss.str(); | |
} | |
private: | |
string_type m_time_duration_format; | |
}; | |
template <class time_type, class CharT, class OutItrT> | |
std::locale::id time_facet<time_type, CharT, OutItrT>::id; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::seconds_with_fractional_seconds_format = | |
time_formats<CharT>::seconds_with_fractional_seconds_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::zone_name_format = time_formats<CharT>::zone_name_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::zone_iso_extended_format =time_formats<CharT>::zone_iso_extended_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::posix_zone_string_format =time_formats<CharT>::posix_zone_string_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::seconds_format = time_formats<CharT>::seconds_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::hours_format = time_formats<CharT>::hours_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::unrestricted_hours_format = time_formats<CharT>::unrestricted_hours_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::standard_format = time_formats<CharT>::standard_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::duration_seperator = time_formats<CharT>::duration_seperator; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::negative_sign = time_formats<CharT>::negative_sign; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::positive_sign = time_formats<CharT>::positive_sign; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::duration_sign_negative_only = time_formats<CharT>::duration_sign_negative_only; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::duration_sign_always = time_formats<CharT>::duration_sign_always; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type,CharT, OutItrT>::char_type* | |
time_facet<time_type,CharT, OutItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::default_time_format = | |
time_formats<CharT>::default_time_format; | |
template <class time_type, class CharT, class OutItrT> | |
const typename time_facet<time_type, CharT, OutItrT>::char_type* | |
time_facet<time_type, CharT, OutItrT>::default_time_duration_format = | |
time_formats<CharT>::default_time_duration_format; | |
//! Facet for format-based input. | |
/*! | |
*/ | |
template <class time_type, | |
class CharT, | |
class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > > | |
class time_input_facet : | |
public boost::date_time::date_input_facet<typename time_type::date_type , CharT, InItrT> { | |
public: | |
typedef typename time_type::date_type date_type; | |
typedef typename time_type::time_duration_type time_duration_type; | |
typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type; | |
typedef boost::date_time::period<time_type,time_duration_type> period_type; | |
typedef boost::date_time::date_input_facet<typename time_type::date_type, CharT, InItrT> base_type; | |
typedef typename base_type::duration_type date_duration_type; | |
typedef typename base_type::year_type year_type; | |
typedef typename base_type::month_type month_type; | |
typedef typename base_type::day_type day_type; | |
typedef typename base_type::string_type string_type; | |
typedef typename string_type::const_iterator const_itr; | |
typedef typename base_type::char_type char_type; | |
typedef typename base_type::format_date_parser_type format_date_parser_type; | |
typedef typename base_type::period_parser_type period_parser_type; | |
typedef typename base_type::special_values_parser_type special_values_parser_type; | |
typedef typename base_type::date_gen_parser_type date_gen_parser_type; | |
typedef typename base_type::special_values_parser_type::match_results match_results; | |
static const char_type* fractional_seconds_format; // f | |
static const char_type* fractional_seconds_or_none_format; // F | |
static const char_type* seconds_with_fractional_seconds_format; // s | |
static const char_type* seconds_format; // S | |
static const char_type* standard_format; // x X | |
static const char_type* zone_abbrev_format; // z | |
static const char_type* zone_name_format; // Z | |
static const char_type* zone_iso_format; // q | |
static const char_type* zone_iso_extended_format; // Q | |
static const char_type* duration_seperator; | |
static const char_type* iso_time_format_specifier; | |
static const char_type* iso_time_format_extended_specifier; | |
static const char_type* default_time_input_format; | |
static const char_type* default_time_duration_format; | |
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; | |
} | |
typedef typename time_duration_type::hour_type hour_type; | |
typedef typename time_duration_type::min_type min_type; | |
typedef typename time_duration_type::sec_type sec_type; | |
hour_type hour = 0; | |
min_type min = 0; | |
sec_type 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 'O': | |
{ | |
// A period may span more than 24 hours. In that case the format | |
// string should be composed with the unrestricted hours specifier. | |
hour = var_string_to_int<hour_type, CharT>(sitr, stream_end, | |
std::numeric_limits<hour_type>::digits10 + 1); | |
if(hour == -1){ | |
return check_special_value(sitr, stream_end, td, c); | |
} | |
break; | |
} | |
case 'H': | |
{ | |
match_results mr; | |
hour = fixed_string_to_int<hour_type, 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<min_type, CharT>(sitr, stream_end, mr, 2); | |
if(min == -1){ | |
return check_special_value(sitr, stream_end, td, c); | |
} | |
break; | |
} | |
case 's': | |
case 'S': | |
{ | |
match_results mr; | |
sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2); | |
if(sec == -1){ | |
return check_special_value(sitr, stream_end, td, c); | |
} | |
if (*itr == 'S') | |
break; | |
// %s is the same as %S%f so we drop through into %f | |
} | |
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; | |
} | |
typedef typename time_duration_type::hour_type hour_type; | |
typedef typename time_duration_type::min_type min_type; | |
typedef typename time_duration_type::sec_type sec_type; | |
// time elements | |
hour_type hour = 0; | |
min_type min = 0; | |
sec_type 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&) { // 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&) { // 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_month | |
} | |
} | |
// 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); | |
} | |
catch(std::out_of_range&) { // base class for bad_weekday 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_weekday | |
} | |
} | |
// did m_parser already advance sitr to next char? | |
if(mr.has_remaining()) { | |
use_current_char = true; | |
} | |
break; | |
} | |
case 'j': | |
{ | |
// code that gets julian day (from format_date_parser) | |
match_results mr; | |
day_of_year = fixed_string_to_int<unsigned short, CharT>(sitr, stream_end, mr, 3); | |
if(day_of_year == -1) { | |
if(this->m_sv_parser.match(sitr, stream_end, mr)) { | |
t = time_type(static_cast<special_values>(mr.current_match)); | |
return sitr; | |
} | |
} | |
// these next two lines are so we get an exception with bad input | |
typedef typename time_type::date_type::day_of_year_type day_of_year_type; | |
day_of_year_type t_day_of_year(day_of_year); | |
break; | |
} | |
case 'd': | |
{ | |
try { | |
t_day = this->m_parser.parse_day_of_month(sitr, stream_end); | |
} | |
catch(std::out_of_range&) { // base class for exception bad_day_of_month | |
match_results mr; | |
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_day_of_month | |
} | |
} | |
break; | |
} | |
// time flags | |
case 'H': | |
{ | |
match_results mr; | |
hour = fixed_string_to_int<hour_type, CharT>(sitr, stream_end, mr, 2); | |
if(hour == -1){ | |
return check_special_value(sitr, stream_end, t, c); | |
} | |
break; | |
} | |
case 'M': | |
{ | |
match_results mr; | |
min = fixed_string_to_int<min_type, CharT>(sitr, stream_end, mr, 2); | |
if(min == -1){ | |
return check_special_value(sitr, stream_end, t, c); | |
} | |
break; | |
} | |
case 's': | |
case 'S': | |
{ | |
match_results mr; | |
sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2); | |
if(sec == -1){ | |
return check_special_value(sitr, stream_end, t, c); | |
} | |
if (*itr == 'S') | |
break; | |
// %s is the same as %S%f so we drop through into %f | |
} | |
case 'f': | |
{ | |
// check for decimal, check SV 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, t, 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; | |
} | |
// time_zone flags | |
//case 'q': | |
//case 'Q': | |
//case 'z': | |
case 'Z': | |
{ | |
if(time_is_local) { // skip if 't' is a ptime | |
++itr; | |
if(*itr == 'P') { | |
// skip leading whitespace | |
while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } | |
// parse zone | |
while((sitr != stream_end) && (!std::isspace(*sitr))) { | |
tz_str += *sitr; | |
++sitr; | |
} | |
} | |
else { | |
use_current_format_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; | |
} | |
if(use_current_format_char) { | |
use_current_format_char = false; | |
} | |
else { | |
++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; | |
} | |
} | |
} | |
date_type d(not_a_date_time); | |
if (day_of_year > 0) { | |
d = date_type(static_cast<unsigned short>(t_year-1),12,31) + date_duration_type(day_of_year); | |
} | |
else { | |
d = date_type(t_year, t_month, t_day); | |
} | |
time_duration_type td(hour, min, sec, frac); | |
t = time_type(d, td); | |
return sitr; | |
} | |
//! Helper function to check for special_value | |
/*! First character may have been consumed during original parse | |
* attempt. Parameter 'c' should be a copy of that character. | |
* Throws ios_base::failure if parse fails. */ | |
template<class temporal_type> | |
inline | |
InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const | |
{ | |
match_results mr; | |
if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed? | |
mr.cache += c; | |
} | |
this->m_sv_parser.match(sitr, stream_end, mr); | |
if(mr.current_match == match_results::PARSE_ERROR) { | |
std::string tmp = convert_string_type<char_type, char>(mr.cache); | |
boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'")); | |
BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return sitr); // should never reach | |
} | |
tt = temporal_type(static_cast<special_values>(mr.current_match)); | |
return sitr; | |
} | |
//! Helper function for parsing a fractional second type from the stream | |
void parse_frac_type(InItrT& sitr, | |
InItrT& stream_end, | |
fracional_seconds_type& frac) const | |
{ | |
string_type cache; | |
while((sitr != stream_end) && std::isdigit(*sitr)) { | |
cache += *sitr; | |
++sitr; | |
} | |
if(cache.size() > 0) { | |
unsigned short precision = time_duration_type::num_fractional_digits(); | |
// input may be only the first few decimal places | |
if(cache.size() < precision) { | |
frac = lexical_cast<fracional_seconds_type>(cache); | |
frac = decimal_adjust(frac, static_cast<unsigned short>(precision - cache.size())); | |
} | |
else { | |
// if input has too many decimal places, drop excess digits | |
frac = lexical_cast<fracional_seconds_type>(cache.substr(0, precision)); | |
} | |
} | |
} | |
private: | |
string_type m_time_duration_format; | |
//! Helper function to adjust trailing zeros when parsing fractional digits | |
template<class int_type> | |
inline | |
int_type decimal_adjust(int_type val, const unsigned short places) const | |
{ | |
unsigned long factor = 1; | |
for(int i = 0; i < places; ++i){ | |
factor *= 10; // shift decimal to the right | |
} | |
return val * factor; | |
} | |
}; | |
template <class time_type, class CharT, class InItrT> | |
std::locale::id time_input_facet<time_type, CharT, InItrT>::id; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::seconds_with_fractional_seconds_format = time_formats<CharT>::seconds_with_fractional_seconds_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::seconds_format = time_formats<CharT>::seconds_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::standard_format = time_formats<CharT>::standard_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::zone_name_format = time_formats<CharT>::zone_name_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::zone_iso_extended_format = time_formats<CharT>::zone_iso_extended_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::duration_seperator = time_formats<CharT>::duration_seperator; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::default_time_input_format = time_formats<CharT>::default_time_input_format; | |
template <class time_type, class CharT, class InItrT> | |
const typename time_input_facet<time_type, CharT, InItrT>::char_type* | |
time_input_facet<time_type, CharT, InItrT>::default_time_duration_format = time_formats<CharT>::default_time_duration_format; | |
} } // namespaces | |
#endif | |