large series of changes associated with revamped facet code

[SVN r26940]
This commit is contained in:
Jeff Garland
2005-01-30 20:58:52 +00:00
parent faf814d4e1
commit 94de717857
18 changed files with 1118 additions and 252 deletions

View File

@@ -5,7 +5,7 @@
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Martin Andrian, Jeff Garland
* Author: Martin Andrian, Jeff Garland, Bart Garst
* $Date$
*/
@@ -14,24 +14,50 @@
#include "boost/date_time/period.hpp"
#include "boost/date_time/special_values_formatter.hpp"
#include "boost/date_time/period_formatter.hpp"
#include "boost/date_time/date_generator_formatter.hpp"
#include <string>
#include <vector>
namespace boost { namespace date_time {
/*! TODO: ...
* Format flags are:
*
* %A => long_weekday_format - Full name Ex: Tuesday
* %a => short_weekday_format - Three letter abbreviation Ex: Tue
* %B => long_month_format - Full name Ex: October
* %b => short_month_format - Three letter abbreviation Ex: Oct
* %x => standard_format_specifier - defined by the locale
* %Y-%b-%d => default_date_format - YYYY-Mon-dd
*
* Default month format == %b
* Default weekday format == %a
*/
template <class date_type,
class CharT,
class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class date_facet : public std::locale::facet {
public:
typedef typename date_type::duration_type duration_type;
// greg_weekday is gregorian_calendar::day_of_week_type
typedef typename date_type::day_of_week_type day_of_week_type;
typedef typename date_type::day_type day_type;
typedef typename date_type::month_type month_type;
typedef boost::date_time::period<date_type,duration_type> period_type;
typedef std::basic_string<CharT> string_type;
typedef CharT char_type;
typedef boost::date_time::period_formatter<CharT> period_formatter_type;
typedef boost::date_time::special_values_formatter<CharT> special_values_formatter_type;
typedef std::vector<std::basic_string<CharT> > input_collection_type;
// used for the output of the date_generators
typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
static const char_type long_weekday_format[3];
static const char_type short_weekday_format[3];
static const char_type long_month_format[3];
@@ -40,11 +66,15 @@ namespace boost { namespace date_time {
static const char_type standard_format_specifier[3];
static const char_type iso_format_specifier[7];
static const char_type iso_format_extended_specifier[9];
static const char_type default_date_format[9]; // YYYY-Mon-DD
static std::locale::id id;
explicit date_facet(::size_t a_ref = 0)
: std::locale::facet(a_ref),
m_format(standard_format_specifier)
//m_format(standard_format_specifier)
m_format(default_date_format),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format)
{}
explicit date_facet(const char_type* format,
@@ -52,6 +82,8 @@ namespace boost { namespace date_time {
::size_t ref_count = 0)
: std::locale::facet(ref_count),
m_format(format),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_month_short_names(short_month_names)
{}
@@ -59,10 +91,14 @@ namespace boost { namespace date_time {
explicit date_facet(const char_type* format,
period_formatter_type period_formatter = period_formatter_type(),
special_values_formatter_type special_values_formatter = special_values_formatter_type(),
date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
::size_t ref_count = 0)
: std::locale::facet(ref_count),
m_format(format),
m_month_format(short_month_format),
m_weekday_format(short_weekday_format),
m_period_formatter(period_formatter),
m_date_gen_formatter(dg_formatter),
m_special_values_formatter(special_values_formatter)
{}
void format(const char_type* const format) {
@@ -76,6 +112,12 @@ namespace boost { namespace date_time {
{
m_format = iso_format_extended_specifier;
}
void month_format(const char_type* const format) {
m_month_format = format;
}
void weekday_format(const char_type* const format) {
m_weekday_format = format;
}
void period_formatter(period_formatter_type period_formatter) {
m_period_formatter= period_formatter;
@@ -103,6 +145,12 @@ namespace boost { namespace date_time {
m_month_long_names = long_month_names;
}
void date_gen_phrase_strings(const input_collection_type& new_strings,
typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
{
m_date_gen_formatter.elements(new_strings, beg_pos);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
@@ -115,6 +163,47 @@ namespace boost { namespace date_time {
return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const month_type& m) const
{
//if (d.is_special()) {
// return do_put_special(next, a_ios, fill_char, d.as_special());
//}
//The following line of code required the date to support a to_tm function
tm dtm;
dtm.tm_mon = m -1;
return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
}
//! puts the day of month
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const day_type& day) const
{
tm dtm;
dtm.tm_mday = day.as_number();
char_type tmp[3] = {'%','d'};
string_type temp_format(tmp);
return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const day_of_week_type& dow) const
{
//if (d.is_special()) {
// return do_put_special(next, a_ios, fill_char, d.as_special());
//}
//The following line of code required the date to support a to_tm function
tm dtm;
dtm.tm_wday = dow;
return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
}
// date durations don't interact with the facet...no put code needed here.
// todo is that really true? What about special values?
@@ -125,6 +214,55 @@ namespace boost { namespace date_time {
{
return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const partial_date_type& pd) const
{
return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const nth_kday_type& nkd) const
{
return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const first_kday_type& fkd) const
{
return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const last_kday_type& lkd) const
{
return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const kday_before_type& fkb) const
{
return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
}
OutItrT put(OutItrT next,
std::ios_base& a_ios,
char_type fill_char,
const kday_after_type& fka) const
{
return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
}
protected:
virtual OutItrT do_put_special(OutItrT next,
std::ios_base& a_ios,
@@ -171,7 +309,10 @@ namespace boost { namespace date_time {
}
protected:
string_type m_format;
string_type m_month_format;
string_type m_weekday_format;
period_formatter_type m_period_formatter;
date_gen_formatter_type m_date_gen_formatter;
special_values_formatter_type m_special_values_formatter;
input_collection_type m_month_short_names;
input_collection_type m_month_long_names;
@@ -218,6 +359,10 @@ namespace boost { namespace date_time {
date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
{'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
template <class date_type, class CharT, class OutItrT>
const typename date_facet<date_type, CharT, OutItrT>::char_type
date_facet<date_type, CharT, OutItrT>::default_date_format[9] =
{'%','Y','-','%','b','-','%','d'};
} }

View File

@@ -0,0 +1,205 @@
#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/date_time/date_generators.hpp"
namespace boost {
namespace date_time {
template <class date_type, class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
class date_generator_formatter {
public:
typedef partial_date<date_type> partial_date_type;
typedef nth_kday_of_month<date_type> nth_kday_type;
typedef first_kday_of_month<date_type> first_kday_type;
typedef last_kday_of_month<date_type> last_kday_type;
typedef first_kday_after<date_type> kday_after_type;
typedef first_kday_before<date_type> kday_before_type;
typedef CharT char_type;
typedef std::basic_string<char_type> string_type;
typedef std::vector<string_type> collection_type;
static const char_type first_string[6];
static const char_type second_string[7];
static const char_type third_string[6];
static const char_type fourth_string[7];
static const char_type fifth_string[6];
static const char_type last_string[5];
static const char_type before_string[8];
static const char_type after_string[6];
static const char_type of_string[3];
enum phrase_elements {first=0, second, third, fourth, fifth, last,
before, after, of, number_of_phrase_elements};
date_generator_formatter()
{
phrase_strings.push_back(string_type(first_string));
phrase_strings.push_back(string_type(second_string));
phrase_strings.push_back(string_type(third_string));
phrase_strings.push_back(string_type(fourth_string));
phrase_strings.push_back(string_type(fifth_string));
phrase_strings.push_back(string_type(last_string));
phrase_strings.push_back(string_type(before_string));
phrase_strings.push_back(string_type(after_string));
phrase_strings.push_back(string_type(of_string));
}
void elements(const collection_type& new_strings,
phrase_elements beg_pos=first)
{
if(beg_pos < number_of_phrase_elements) {
typename collection_type::iterator itr = phrase_strings.begin();
itr += beg_pos;
std::copy(new_strings.begin(), new_strings.end(),
itr);
//phrase_strings.begin());
}
}
template<class facet_type>
OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const partial_date_type& pd,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, pd.day());
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, pd.month());
return next;
}
template<class facet_type>
OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const nth_kday_type& nkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[nkd.nth_week() -1]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, nkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, nkd.month());
return next;
}
template<class facet_type>
OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const first_kday_type& fkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[first]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, fkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, fkd.month());
return next;
}
template<class facet_type>
OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const last_kday_type& lkd,
const facet_type& facet) const
{
put_string(next, phrase_strings[last]);
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, lkd.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, string_type(of_string));
next = a_fill; //TODO change this ???
facet.put(next, a_ios, a_fill, lkd.month());
return next;
}
template<class facet_type>
OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const kday_before_type& fkb,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, fkb.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, phrase_strings[before]);
return next;
}
template<class facet_type>
OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios,
CharT a_fill, const kday_after_type& fka,
const facet_type& facet) const
{
facet.put(next, a_ios, a_fill, fka.day_of_week());
next = a_fill; //TODO change this ???
put_string(next, phrase_strings[after]);
return next;
}
private:
collection_type phrase_strings;
//! helper function to put the various member string into stream
OutItrT put_string(OutItrT next, const string_type& str) const
{
typename string_type::const_iterator itr = str.begin();
while(itr != str.end()) {
*next = *itr;
++itr;
++next;
}
return next;
}
};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::first_string[6] =
{'f','i','r','s','t'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::second_string[7] =
{'s','e','c','o','n','d'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::third_string[6] =
{'t','h','i','r','d'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::fourth_string[7] =
{'f','o','u','r','t','h'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::fifth_string[6] =
{'f','i','f','t','h'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::last_string[5] =
{'l','a','s','t'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::before_string[8] =
{'b','e','f','o','r','e'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::after_string[6] =
{'a','f','t','e','r'};
template<class date_type, class CharT, class OutItrT>
const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
date_generator_formatter<date_type, CharT, OutItrT>::of_string[3] =
{'o','f'};
} } // namespaces
#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___

View File

@@ -11,12 +11,17 @@
#include <exception>
#include "boost/date_time/gregorian/gregorian_types.hpp"
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/gregorian/formatters_limited.hpp"
#else
#include "boost/date_time/gregorian/formatters.hpp"
#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
#include "boost/date_time/c_time.hpp"
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
# if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
# include "boost/date_time/gregorian/formatters_limited.hpp"
# else
# include "boost/date_time/gregorian/formatters.hpp"
# endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
#else
# include <sstream>
# include "boost/date_time/gregorian/gregorian_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
namespace boost {
@@ -28,8 +33,14 @@ namespace gregorian {
tm to_tm(const date& d)
{
if(d.is_pos_infinity() || d.is_neg_infinity() || d.is_not_a_date()){
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
std::string s("tm unable to handle date value of " + to_simple_string(d));
throw std::out_of_range(s);
#else
std::stringstream ss;
ss << "tm unable to handle date value of " << d;
throw std::out_of_range(ss.str());
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
}
tm datetm;
boost::gregorian::date::ymd_type ymd = d.year_month_day();

View File

@@ -11,7 +11,6 @@
#include "boost/date_time/compiler_config.hpp"
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/gregorian/greg_facet.hpp"
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/date_formatting_limited.hpp"
#else

View File

@@ -10,7 +10,6 @@
*/
#include "boost/date_time/gregorian/gregorian_types.hpp"
#include "boost/date_time/gregorian/greg_facet.hpp"
#include "boost/date_time/date_formatting_limited.hpp"
#include "boost/date_time/iso_format.hpp"
#include "boost/date_time/date_format_simple.hpp"

View File

@@ -31,6 +31,7 @@ namespace gregorian {
typedef boost::date_time::weekdays weekday_enum;
};
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
//! Create the base facet type for gregorian::date
typedef boost::date_time::date_names_put<greg_facet_config> greg_base_facet;
@@ -199,7 +200,7 @@ namespace gregorian {
os << fkb.day_of_week() << " before";
return os;
}
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
/**************** Input Streaming ******************/
#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)

View File

@@ -24,7 +24,13 @@
#else
#include "boost/date_time/gregorian/formatters.hpp"
#endif
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/gregorian/greg_facet.hpp"
#else
#include "boost/date_time/gregorian/gregorian_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
#include "boost/date_time/gregorian/parsers.hpp"

View File

@@ -0,0 +1,249 @@
#ifndef DATE_TIME_GREGORIAN_IO_HPP__
#define DATE_TIME_GREGORIAN_IO_HPP__
/* Copyright (c) 2004 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/date_facet.hpp"
#include "boost/date_time/period_formatter.hpp"
#include <iostream>
#include <locale>
namespace boost {
namespace gregorian {
typedef boost::date_time::period_formatter<wchar_t> wperiod_formatter;
typedef boost::date_time::period_formatter<char> period_formatter;
typedef boost::date_time::date_facet<date,wchar_t> wdate_facet;
typedef boost::date_time::date_facet<date,char> date_facet;
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date& d) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), d);
else {
//instantiate a custom facet for dealing with dates since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every date
//if the locale did not already exist. Of course this will be overridden
//if the user imbues at some later point. With the default settings
//for the facet the resulting format will be the same as the
//std::time_facet settings.
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), d);
}
return os;
}
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const date_duration& dd)
{
os << dd.get_rep();
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_period& dp) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), dp);
else {
//instantiate a custom facet for dealing with date periods since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the local did not already exist. Of course this will be overridden
//if the user imbues at some later point. With the default settings
//for the facet the resulting format will be the same as the
//std::time_facet settings.
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), dp);
}
return os;
}
/********** small gregorian types **********/
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_month& gm) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), gm);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...)
//custom_date_facet* f = new custom_date_facet("%B");
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), gm);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_weekday& gw) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), gw);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), gw);
}
return os;
}
/********** date generator types **********/
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::partial_date& pd) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), pd);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), pd);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), nkd);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), nkd);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), fkd);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), fkd);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc()))
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), lkd);
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), lkd);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_after& fda) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc())) {
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), fda);
}
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), fda);
}
return os;
}
template <class CharT, class TraitsT>
inline std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_before& fdb) {
typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
typedef std::time_put<CharT> std_date_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_date_facet>(os.getloc())) {
std::use_facet<custom_date_facet>(os.getloc()).put(oitr, os, os.fill(), fdb);
}
else {
std::ostreambuf_iterator<CharT> oitr(os);
custom_date_facet* f = new custom_date_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), fdb);
}
return os;
}
} } // namespaces
#endif // DATE_TIME_GREGORIAN_IO_HPP__

View File

@@ -27,15 +27,15 @@ namespace local_time {
ambiguous_result (std::string _msg="") :
std::logic_error(std::string("Daylight Savings Results are ambiguous: " + _msg)) {}
};
//
struct InvalidTimeLabel : public std::logic_error
//! simple exception for when time label given cannot exist
struct time_label_invalid : public std::logic_error
{
InvalidTimeLabel(std::string _msg="") :
time_label_invalid (std::string _msg="") :
std::logic_error(std::string("Time label given is invalid: " + _msg)) {}
};
struct DSTNotValid: public std::logic_error
struct dst_not_valid: public std::logic_error
{
DSTNotValid(std::string _msg="") :
dst_not_valid(std::string _msg="") :
std::logic_error(std::string("is_dst flag does not match resulting dst for time label given: " + _msg)) {}
};
@@ -46,7 +46,16 @@ namespace local_time {
using date_time::is_not_in_dst;
using date_time::ambiguous;
using date_time::invalid_time_label;
//! Representation of "wall-clock" time in a particular time zone
/*! Representation of "wall-clock" time in a particular time zone
* Local_date_time_base holds a time value (date and time offset from 00:00)
* along with a time zone. The time value is stored as UTC and conversions
* to wall clock time are made as needed. This approach allows for
* operations between wall-clock times in different time zones, and
* daylight savings time considerations, to be made. Time zones are
* required to be in the form of a boost::shared_ptr<time_zone_base>.
*/
template<class utc_time_=posix_time::ptime,
class tz_type=date_time::time_zone_base<utc_time_> >
class local_date_time_base : public date_time::base_time<utc_time_,
@@ -57,7 +66,7 @@ namespace local_time {
typedef typename utc_time_type::date_type date_type;
typedef typename date_type::duration_type date_duration_type;
typedef typename utc_time_type::time_system_type time_system_type;
/** This constructor interprets the passed time as a UTC time.
/*! This constructor interprets the passed time as a UTC time.
* So, for example, if the passed timezone is UTC-5 then the
* time will be adjusted back 5 hours. The time zone allows for
* automatic calculation of whether the particular time is adjusted for
@@ -74,15 +83,15 @@ namespace local_time {
// param was already utc so nothing more to do
}
/** This constructs a local time -- the passed time information
/*! This constructs a local time -- the passed time information
* understood to be in the passed tz. The DST flag must be passed
* to indicate whether the time is in daylight savings or not.
* @throws -- InvalidTimeLabel if the time passed does not exist in
* the given locale. The non-existant case occurs typically
* @throws -- time_label_invalid if the time passed does not exist in
* the given locale. The non-existent case occurs typically
* during the shift-back from daylight savings time. When
* the clock is shifted forward a range of times
* (2 am to 3 am in the US) is skipped and hence is invalid.
* @throws -- DSTNotValid if the DST flag is passed for a period
* @throws -- dst_not_valid if the DST flag is passed for a period
* where DST is not active.
*/
local_date_time_base(date_type d,
@@ -103,7 +112,7 @@ namespace local_time {
// Ex: 2:15am local on trans-in day in nyc, dst_flag irrelevant
std::stringstream ss;
ss << "time given: " << d << ' ' << td;
throw InvalidTimeLabel(ss.str());
throw time_label_invalid(ss.str());
}
else if(result != ambiguous && in_dst != dst_flag){
// is dst_flag accurate?
@@ -111,7 +120,7 @@ namespace local_time {
std::stringstream ss;
ss << "flag given: " << (dst_flag ? "dst=true" : "dst=false")
<< ", dst calculated: " << (in_dst ? "dst=true" : "dst=false");
throw DSTNotValid(ss.str());
throw dst_not_valid(ss.str());
}
// everything checks out and conversion to utc already done
@@ -122,7 +131,7 @@ namespace local_time {
enum DST_CALC_OPTIONS { EXCEPTION_ON_ERROR, NOT_DATE_TIME_ON_ERROR };
//ASSUME_DST_ON_ERROR, ASSUME_NOT_DST_ON_ERROR };
/** This constructs a local time -- the passed time information
/*! This constructs a local time -- the passed time information
* understood to be in the passed tz. The DST flag is calculated
* according to the specified rule.
*/
@@ -149,7 +158,7 @@ namespace local_time {
if(calc_option == EXCEPTION_ON_ERROR){
std::stringstream ss;
ss << "time given: " << d << ' ' << td;
throw InvalidTimeLabel(ss.str());
throw time_label_invalid(ss.str());
}
else{ // NADT on error
time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
@@ -170,9 +179,10 @@ namespace local_time {
}
//! takes a date and time_duration representing a local time
/*!
* returns TODO: ...
//! Determines if given time label is in daylight savings for given zone
/*! Determines if given time label is in daylight savings for given zone.
* Takes a date and time_duration representing a local time, along
* with time zone, and returns a time_is_dst_result object as result.
*/
static time_is_dst_result check_dst(date_type d,
time_duration_type td,
@@ -194,7 +204,7 @@ namespace local_time {
}
}
//! Simple destructor, releases time zone if last referer
//! Simple destructor, releases time zone if last referrer
~local_date_time_base() {};
//! Copy constructor
@@ -210,6 +220,7 @@ namespace local_time {
zone_(tz)
{}
//! returns time zone associated with calling instance
boost::shared_ptr<tz_type> zone() const
{
return zone_;
@@ -299,30 +310,73 @@ namespace local_time {
{
return local_date_time_base(utc_time_type(time_) + td, new_tz);
}
//! Returns name of associated time zone or "Coordinated Universal Time".
std::string zone_name() const
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00" extended iso format). Empty string is returned for
* classes that do not use a time_zone */
std::string zone_name(bool as_offset=false) const
{
if(zone_ == NULL) {
return std::string("Coordinated Universal Time");
if(as_offset) {
return std::string("Z");
}
else {
return std::string("Coordinated Universal Time");
}
}
if (is_dst()) {
return zone_->dst_zone_name();
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
td += zone_->dst_offset();
return zone_as_offset(td, ":");
}
else {
return zone_->dst_zone_name();
}
}
else {
return zone_->std_zone_name();
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
return zone_as_offset(td, ":");
}
else {
return zone_->std_zone_name();
}
}
}
//! Returns abreviation of associated time zone or "UTC".
std::string zone_abbrev() const
//! Returns abbreviation of associated time zone or "UTC".
/*! Optional bool parameter will return time zone as an offset
* (ie "+0700" iso format). Empty string is returned for classes
* that do not use a time_zone */
std::string zone_abbrev(bool as_offset=false) const
{
if(zone_ == NULL) {
return std::string("UTC");
if(as_offset) {
return std::string("Z");
}
else {
return std::string("UTC");
}
}
if (is_dst()) {
return zone_->dst_zone_abbrev();
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
td += zone_->dst_offset();
return zone_as_offset(td, "");
}
else {
return zone_->dst_zone_abbrev();
}
}
else {
return zone_->std_zone_abbrev();
if(as_offset) {
time_duration_type td = zone_->base_utc_offset();
return zone_as_offset(td, "");
}
else {
return zone_->std_zone_abbrev();
}
}
}
@@ -425,6 +479,32 @@ namespace local_time {
}
return t;
}
std::string zone_as_offset(const time_duration_type& td,
const std::string& separator) const
{
// time_duration op<< uses the ptime facet. If we want to change
// its format we must use a time_facet<ptime, ...>
typedef boost::date_time::time_facet<utc_time_, char> timefacet;
timefacet* facet_ptr = new timefacet();
std::stringstream ss;
// build the format first
ss << "%H" << separator << "%M";
facet_ptr->time_duration_format(ss.str().c_str());
ss.str("");
std::locale loc(std::locale::classic(), facet_ptr);
ss.imbue(loc);
if(td.is_negative()) {
// a negative duration is represented as "-[h]h:mm"
// we require two digits for the hour. A positive duration
// with the %H flag will always give two digits
ss << "-" << td.invert_sign();
}
else {
ss << "+" << td;
}
return ss.str();
}
};
//!Use the default parameters to define local_date_time

View File

@@ -37,16 +37,16 @@ namespace local_time{
typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone_base;
//! A time zone class constructed from a POSIX time zone string
/*! A POSIX time zone string takes to form of:<br>
/*! A POSIX time zone string takes the form of:<br>
* "std offset dst [offset],start[/time],end[/time]" (w/no spaces)
* 'std' specifies the abbrev of the time zone.<br>
* 'offset' is the offset from UTC.<br>
* 'dst' specifies the abbrev of the time zone during daylight savings time.<br>
* The second offset is how many hours changed during DST. Default=1<br>
* 'start' & 'end' are the dates when DST goes into (and out of) effect.<br>
* 'start' and'end' are the dates when DST goes into (and out of) effect.<br>
* 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br>
* 'time' and 'offset' take the same form. Time defaults=02:00:00<br>
* 'start' & 'end' can be one of three forms:<br>
* 'start' and 'end' can be one of three forms:<br>
* Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br>
* Jn {n=1-365 Feb29 is never counted}<br>
* n {n=0-365 Feb29 is counted in leap years}<br>
@@ -173,16 +173,16 @@ namespace local_time{
// get duration
while(!isalpha(*sit) && sit != obj.end()){
ss << *sit++;
}
base_utc_offset_ = posix_time::duration_from_string(ss.str());
ss.str("");
}
base_utc_offset_ = posix_time::duration_from_string(ss.str());
ss.str("");
// base offset must be within range of -12 hours to +12 hours
if(base_utc_offset_ < time_duration_type(-12,0,0) ||
base_utc_offset_ > time_duration_type(12,0,0))
{
throw bad_offset(posix_time::to_simple_string(base_utc_offset_));
}
// base offset must be within range of -12 hours to +12 hours
if(base_utc_offset_ < time_duration_type(-12,0,0) ||
base_utc_offset_ > time_duration_type(12,0,0))
{
throw bad_offset(posix_time::to_simple_string(base_utc_offset_));
}
}
// get DST data if given
@@ -210,12 +210,12 @@ namespace local_time{
dst_offsets_.dst_adjust_ = posix_time::hours(1);
}
// adjustment must be within +|- 1 day
if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
{
throw bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_));
}
// adjustment must be within +|- 1 day
if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
{
throw bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_));
}
}
// full names not extracted so abbrevs used in their place
zone_names_ = time_zone_names(std_zone_abbrev, std_zone_abbrev, dst_zone_abbrev, dst_zone_abbrev);
@@ -316,7 +316,7 @@ namespace local_time{
}
int em=1, ed=0;
ed = lexical_cast<int>(e.substr(1)); // skip 'J'
while(ed >= calendar::end_of_month_day(year,em)){
while(ed > calendar::end_of_month_day(year,em)){
ed -= calendar::end_of_month_day(year,em++);
}
@@ -344,6 +344,19 @@ namespace local_time{
);
}
//! helper function used when throwing exceptions
static std::string td_as_string(const time_duration_type& td)
{
std::string s;
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
s = posix_time::to_simple_string(td);
#else
std::stringstream ss;
ss << td;
s = ss.str();
#endif
return s;
}
};
} } // namespace boost::local_time

View File

@@ -1,7 +1,7 @@
#ifndef POSIX_TIME_CONVERSION_HPP___
#define POSIX_TIME_CONVERSION_HPP___
/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
@@ -35,7 +35,23 @@ namespace posix_time {
timetm.tm_hour = td.hours();
timetm.tm_min = td.minutes();
timetm.tm_sec = td.seconds();
timetm.tm_isdst = -1; //?
timetm.tm_isdst = -1; // -1 used when dst info is unknown
return timetm;
}
//! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components
inline
tm to_tm(const boost::posix_time::time_duration& td) {
tm timetm;
timetm.tm_year = 0;
timetm.tm_mon = 0;
timetm.tm_mday = 0;
timetm.tm_wday = 0;
timetm.tm_yday = 0;
timetm.tm_hour = td.hours();
timetm.tm_min = td.minutes();
timetm.tm_sec = td.seconds();
timetm.tm_isdst = -1; // -1 used when dst info is unknown
return timetm;
}

View File

@@ -1,7 +1,7 @@
#ifndef POSIX_TIME_HPP___
#define POSIX_TIME_HPP___
/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
* Use, modification and distribution is subject to the
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE-1.0 or http://www.boost.org/LICENSE-1.0)
@@ -16,11 +16,21 @@
#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
#include "boost/date_time/posix_time/date_duration_operators.hpp"
#endif
// output functions
#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
#include "boost/date_time/posix_time/time_formatters_limited.hpp"
#else
#include "boost/date_time/posix_time/time_formatters.hpp"
#endif
#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
// streaming operators
#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
#include "boost/date_time/posix_time/posix_time_legacy_io.hpp"
#else
#include "boost/date_time/posix_time/posix_time_io.hpp"
#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
#include "boost/date_time/posix_time/time_parsers.hpp"
#include "boost/date_time/posix_time/conversion.hpp"

View File

@@ -0,0 +1,117 @@
#ifndef DATE_TIME_POSIX_TIME_IO_HPP__
#define DATE_TIME_POSIX_TIME_IO_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 or http://www.boost.org/LICENSE-1.0)
* Author: Jeff Garland, Bart Garst
* $Date$
*/
#include "boost/date_time/time_facet.hpp"
#include "boost/date_time/period_formatter.hpp"
#include "boost/date_time/posix_time/time_period.hpp"
#include "boost/date_time/posix_time/posix_time_duration.hpp"
//#include "boost/date_time/gregorian/gregorian_io.hpp"
#include <iostream>
#include <locale>
namespace boost {
namespace posix_time {
typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
typedef boost::date_time::time_facet<ptime, char> ptime_facet;
template <class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os,
const ptime& p) {
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
typedef std::time_put<CharT> std_ptime_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc()))
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
else {
//instantiate a custom facet for dealing with times since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the locale did not already exist. Of course this will be overridden
//if the user imbues as some later point.
std::ostreambuf_iterator<CharT> oitr(os);
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), p);
}
return os;
}
template <class CharT, class TraitsT>
inline
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& os,
const boost::posix_time::time_period& p) {
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
typedef std::time_put<CharT> std_time_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc())) {
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
}
else {
//instantiate a custom facet for dealing with periods since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the local did not already exist. Of course this will be overridden
//if the user imbues as some later point.
std::ostreambuf_iterator<CharT> oitr(os);
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), p);
}
return os;
}
//! ostream operator for posix_time::time_duration
// todo fix to use facet -- place holder for now...
template <class CharT, class traits>
inline
std::basic_ostream<CharT, traits>&
operator<<(std::basic_ostream<CharT, traits>& os, const time_duration& td)
{
typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
typedef std::time_put<CharT> std_ptime_facet;
std::ostreambuf_iterator<CharT> oitr(os);
if (std::has_facet<custom_ptime_facet>(os.getloc()))
std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
else {
//instantiate a custom facet for dealing with times since the user
//has not put one in the stream so far. This is for efficiency
//since we would always need to reconstruct for every time period
//if the locale did not already exist. Of course this will be overridden
//if the user imbues as some later point.
std::ostreambuf_iterator<CharT> oitr(os);
// TODO create a default time_duration format
//const CharT fmt[] = {'%', 'H', ':', '%', 'M', ':', '%', 's', '\0'};
custom_ptime_facet* f = new custom_ptime_facet();
std::locale l = std::locale(os.getloc(), f);
os.imbue(l);
f->put(oitr, os, os.fill(), td);
}
return os;
/*
typedef boost::date_time::ostream_time_duration_formatter<time_duration, CharT> duration_formatter;
duration_formatter::duration_put(td, os);
return os;
*/
}
} } // namespaces
#endif // DATE_TIME_POSIX_TIME_IO_HPP__

View File

@@ -282,130 +282,6 @@ namespace posix_time {
#endif // BOOST_NO_STD_WSTRING
/* ATTENTION: The following operator<< functions are exactly duplicated
* in time_formatters_limited.hpp. Any changes here must also be made there
*/
//The following code is removed for configurations with good std::locale support (eg: MSVC6, gcc 2.9x)
#ifndef BOOST_DATE_TIME_NO_LOCALE
//! ostream operator for posix_time::time_duration
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_duration& td)
{
typedef boost::date_time::ostream_time_duration_formatter<time_duration, charT> duration_formatter;
duration_formatter::duration_put(td, os);
return os;
}
//! ostream operator for posix_time::ptime
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const ptime& t)
{
typedef boost::date_time::ostream_time_formatter<ptime, charT> time_formatter;
time_formatter::time_put(t, os);
return os;
}
//! ostream operator for posix_time::time_period
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_period& tp)
{
typedef boost::date_time::ostream_time_period_formatter<time_period, charT> period_formatter;
period_formatter::period_put(tp, os);
return os;
}
/******** input streaming ********/
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_duration& td)
{
// need to create a std::string and parse it
std::basic_string<charT> inp_s;
std::stringstream out_ss;
is >> inp_s;
typename std::basic_string<charT>::iterator b = inp_s.begin();
// need to use both iterators because there is no requirement
// for the data held by a std::basic_string<> be terminated with
// any marker (such as '\0').
typename std::basic_string<charT>::iterator e = inp_s.end();
while(b != e){
out_ss << out_ss.narrow(*b, 0);
++b;
}
td = date_time::parse_delimited_time_duration<time_duration>(out_ss.str());
return is;
}
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, ptime& pt)
{
gregorian::date d(not_a_date_time);
time_duration td(0,0,0);
is >> d >> td;
pt = ptime(d, td);
return is;
}
/** operator>> for time_period. time_period must be in
* "[date time_duration/date time_duration]" format. */
template<class charT>
inline
std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_period& tp)
{
gregorian::date d(not_a_date_time);
time_duration td(0,0,0);
ptime beg(d, td);
ptime end(beg);
std::basic_string<charT> s;
// get first date string and remove leading '['
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(s.find('[')+1);
ss >> d;
}
// get first time_duration & second date string, remove the '/'
// and split into 2 strings
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(0, s.find('/'));
ss >> td;
}
beg = ptime(d, td);
{
std::basic_stringstream<charT> ss;
ss << s.substr(s.find('/')+1);
ss >> d;
}
// get last time_duration and remove the trailing ']'
is >> s;
{
std::basic_stringstream<charT> ss;
ss << s.substr(0, s.find(']'));
ss >> td;
}
end = ptime(d, td);
tp = time_period(beg,end);
return is;
}
#endif //BOOST_DATE_TIME_NO_LOCALE
} } //namespace posix_time

View File

@@ -204,51 +204,6 @@ namespace posix_time {
}
/* ATTENTION: The following operator<< functions are exactly duplicated
* in time_formatters.hpp. Any changes here must also be made there
*/
//The following code is removed for configurations with good std::locale support (eg: MSVC6, gcc 2.9x)
#ifndef BOOST_DATE_TIME_NO_LOCALE
//! ostream operator for posix_time::time_duration
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_duration& td)
{
typedef boost::date_time::ostream_time_duration_formatter<time_duration, charT> duration_formatter;
duration_formatter::duration_put(td, os);
return os;
}
//! ostream operator for posix_time::ptime
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const ptime& t)
{
typedef boost::date_time::ostream_time_formatter<ptime, charT> time_formatter;
time_formatter::time_put(t, os);
return os;
}
//! ostream operator for posix_time::time_period
template <class charT, class traits>
inline
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const time_period& tp)
{
typedef boost::date_time::ostream_time_period_formatter<time_period, charT> period_formatter;
period_formatter::period_put(tp, os);
return os;
}
#endif //BOOST_DATE_TIME_NO_LOCALE
} } //namespace posix_time

View File

@@ -9,6 +9,11 @@
* $Date$
*/
#include <sstream>
#include <string>
#include <vector>
#include <locale>
namespace boost { namespace date_time {
//! This function gathers up all the month strings from a std::locale

View File

@@ -74,7 +74,17 @@ namespace date_time {
{
return time_system::get_time_of_day(time_);
}
std::string zone_name() const
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00"). Empty string is returned for classes that do
* not use a time_zone */
std::string zone_name(bool as_offset=false) const
{
return time_system::zone_name(time_);
}
/*! Optional bool parameter will return time zone as an offset
* (ie "+07:00"). Empty string is returned for classes that do
* not use a time_zone */
std::string zone_abbrev(bool as_offset=false) const
{
return time_system::zone_name(time_);
}

View File

@@ -11,6 +11,7 @@
*/
#include "boost/date_time/date_facet.hpp"
#include <sstream>
namespace boost {
namespace date_time {
@@ -41,48 +42,68 @@ namespace date_time {
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[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
// TODO: Our standard format currently includes a time sone abbreviation.
// we want it to be "+|-hh:mm"
static const char_type standard_format[5]; // c
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 duration_sign_specifier[3]; // #
static const char_type duration_seperator[2];
static const char_type iso_time_format_specifier[16];
static const char_type iso_time_format_extended_specifier[20];
static std::locale::id id;
static const char_type iso_time_format_specifier[18];
static const char_type iso_time_format_extended_specifier[22];
// TODO: Our standard format currently includes a time zone abbreviation.
// we want it to be "+|-hh:mm"
//default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz]
static const char_type default_time_format[23];
//default time_duration format is HH:MM:SS[.fff...]
static const char_type default_time_duration_format[11];
static std::locale::id id;
//! sets default formats for ptime, local_date_time, and time_duration
explicit time_facet(::size_t a_ref = 0)
: base_type(standard_format),
//: base_type(standard_format),
: base_type(default_time_format),
m_time_duration_format(default_time_duration_format),
m_time_duration_seperator(duration_seperator)
{
set_duration_seperator_from_facet(); //todo fix this
}
//TODO sets time_dur to default - change to a custom?
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(default_time_duration_format),
m_time_duration_seperator(duration_seperator)
{}
//! Changes format for time_duration
void time_duration_format(const char_type* const format) {
m_time_duration_format = format;
}
virtual void set_iso_format()
{
m_format = iso_time_format_specifier;
//TODO: set time_dur format to iso spec too?
}
virtual void set_iso_extended_format()
{
m_format = iso_time_format_extended_specifier;
//TODO: set time_dur format to iso_ext spec too?
}
OutItrT put(OutItrT a_next,
@@ -110,14 +131,80 @@ namespace date_time {
replace_string);
}
if (format.find(zone_name_format)) {
boost::algorithm::replace_all(format,
zone_name_format,
a_time.zone_name());
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_stringstream<char_type> ss;
ss << ' ' << zone_name_format;
boost::algorithm::replace_all(format,
ss.str(),
"");
}
else{
boost::algorithm::replace_all(format,
zone_name_format,
a_time.zone_name());
}
}
if (format.find(zone_abbrev_format)) {
boost::algorithm::replace_all(format,
zone_abbrev_format,
a_time.zone_abbrev());
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_stringstream<char_type> ss;
ss << ' ' << zone_abbrev_format;
boost::algorithm::replace_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)) {
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::replace_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)) {
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::replace_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)) {
// replace %f with nnnnnnn
@@ -148,12 +235,72 @@ namespace date_time {
}
}
// trim format before put to remove empty whitespace
boost::algorithm::trim(format);
return 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
{
/* TODO: Fix this
if (a_time_dur.is_special()) {
return do_put_special(a_next, a_ios, a_fill,
a_time_dur.date().as_special());
}
*/
string_type format(m_time_duration_format);
string_type frac_str;
if (format.find(seconds_with_fractional_seconds_format)) {
// 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)) {
// 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)) {
// 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);
}
}
// trim format before put to remove empty whitespace
//boost::algorithm::trim(format);
return 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
@@ -200,6 +347,7 @@ namespace date_time {
{
//todo write this function
}
string_type m_time_duration_format;
string_type m_time_duration_seperator;
};
@@ -229,6 +377,14 @@ namespace date_time {
const typename time_facet<time_type, CharT, OutItrT>::char_type
time_facet<time_type, CharT, OutItrT>::zone_abbrev_format[3] = {'%','z'};
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[3] ={'%','Q'};
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[3] = {'%','q'};
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[3] = {'%','S'};
@@ -243,13 +399,26 @@ namespace date_time {
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[16] =
{'%', 'Y', '%', 'm', '%', 'd', 'T', '%', 'H', '%', 'M', '%', 'S', '%', 'F'};
time_facet<time_type,CharT, OutItrT>::iso_time_format_specifier[18] =
{'%', 'Y', '%', 'm', '%', 'd', 'T',
'%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' };
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[20] =
{'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F'};
time_facet<time_type, CharT, OutItrT>::iso_time_format_extended_specifier[22] =
{'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ',
'%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'};
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[23] =
{'%','Y','-','%','b','-','%','d',' ',
'%','H',':','%','M',':','%','S','%','F',' ','%','z'};
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[11] =
{'%','H',':','%','M',':','%','S','%','F'};
} }