local_time_io.hpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
  2. #define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
  3. /* Copyright (c) 2003-2004 CrystalClear Software, Inc.
  4. * Subject to the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  6. * Author: Jeff Garland, Bart Garst
  7. * $Date: 2008-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
  8. */
  9. #include <locale>
  10. #include <iostream>
  11. #include <iterator> // i/ostreambuf_iterator
  12. #include <boost/io/ios_state.hpp>
  13. #include <boost/date_time/time_facet.hpp>
  14. #include <boost/date_time/string_convert.hpp>
  15. #include <boost/date_time/local_time/local_date_time.hpp>
  16. #include <boost/date_time/local_time/posix_time_zone.hpp>
  17. #include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
  18. namespace boost {
  19. namespace local_time {
  20. typedef boost::date_time::time_facet<local_date_time, wchar_t> wlocal_time_facet;
  21. typedef boost::date_time::time_facet<local_date_time, char> local_time_facet;
  22. typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,wchar_t> wlocal_time_input_facet;
  23. typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,char> local_time_input_facet;
  24. //! operator<< for local_date_time - see local_time docs for formatting details
  25. template<class CharT, class TraitsT>
  26. inline
  27. std::basic_ostream<CharT, TraitsT>&
  28. operator<<(std::basic_ostream<CharT, TraitsT>& os, const local_date_time& ldt)
  29. {
  30. boost::io::ios_flags_saver iflags(os);
  31. typedef local_date_time time_type;//::utc_time_type typename
  32. typedef date_time::time_facet<time_type, CharT> custom_time_facet;
  33. typedef std::time_put<CharT> std_time_facet;
  34. std::ostreambuf_iterator<CharT> oitr(os);
  35. if(std::has_facet<custom_time_facet>(os.getloc())) {
  36. std::use_facet<custom_time_facet>(os.getloc()).put(oitr,
  37. os,
  38. os.fill(),
  39. ldt);
  40. }
  41. else {
  42. custom_time_facet* f = new custom_time_facet();
  43. std::locale l = std::locale(os.getloc(), f);
  44. os.imbue(l);
  45. f->put(oitr, os, os.fill(), ldt);
  46. }
  47. return os;
  48. }
  49. //! input operator for local_date_time
  50. template <class CharT, class Traits>
  51. inline
  52. std::basic_istream<CharT, Traits>&
  53. operator>>(std::basic_istream<CharT, Traits>& is, local_date_time& ldt)
  54. {
  55. boost::io::ios_flags_saver iflags(is);
  56. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  57. if (strm_sentry) {
  58. try {
  59. typedef typename local_date_time::utc_time_type utc_time_type;
  60. typedef typename date_time::time_input_facet<utc_time_type, CharT> time_input_facet;
  61. // intermediate objects
  62. std::basic_string<CharT> tz_str;
  63. utc_time_type pt(not_a_date_time);
  64. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  65. if(std::has_facet<time_input_facet>(is.getloc())) {
  66. std::use_facet<time_input_facet>(is.getloc()).get_local_time(sit, str_end, is, pt, tz_str);
  67. }
  68. else {
  69. time_input_facet* f = new time_input_facet();
  70. std::locale l = std::locale(is.getloc(), f);
  71. is.imbue(l);
  72. f->get_local_time(sit, str_end, is, pt, tz_str);
  73. }
  74. if(tz_str.empty()) {
  75. time_zone_ptr null_ptr;
  76. // a null time_zone_ptr creates a local_date_time that is UTC
  77. ldt = local_date_time(pt, null_ptr);
  78. }
  79. else {
  80. time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type<CharT,char>(tz_str)));
  81. // the "date & time" constructor expects the time label to *not* be utc.
  82. // a posix_tz_string also expects the time label to *not* be utc.
  83. ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR);
  84. }
  85. }
  86. catch(...) {
  87. // mask tells us what exceptions are turned on
  88. std::ios_base::iostate exception_mask = is.exceptions();
  89. // if the user wants exceptions on failbit, we'll rethrow our
  90. // date_time exception & set the failbit
  91. if(std::ios_base::failbit & exception_mask) {
  92. try { is.setstate(std::ios_base::failbit); }
  93. catch(std::ios_base::failure&) {} // ignore this one
  94. throw; // rethrow original exception
  95. }
  96. else {
  97. // if the user want's to fail quietly, we simply set the failbit
  98. is.setstate(std::ios_base::failbit);
  99. }
  100. }
  101. }
  102. return is;
  103. }
  104. //! output operator for local_time_period
  105. template <class CharT, class TraitsT>
  106. inline
  107. std::basic_ostream<CharT, TraitsT>&
  108. operator<<(std::basic_ostream<CharT, TraitsT>& os,
  109. const boost::local_time::local_time_period& p) {
  110. boost::io::ios_flags_saver iflags(os);
  111. typedef boost::date_time::time_facet<local_date_time, CharT> custom_facet;
  112. typedef std::time_put<CharT> std_time_facet;
  113. std::ostreambuf_iterator<CharT> oitr(os);
  114. if (std::has_facet<custom_facet>(os.getloc())) {
  115. std::use_facet<custom_facet>(os.getloc()).put(oitr, os, os.fill(), p);
  116. }
  117. else {
  118. //instantiate a custom facet for dealing with periods since the user
  119. //has not put one in the stream so far. This is for efficiency
  120. //since we would always need to reconstruct for every time period
  121. //if the local did not already exist. Of course this will be overridden
  122. //if the user imbues as some later point.
  123. custom_facet* f = new custom_facet();
  124. std::locale l = std::locale(os.getloc(), f);
  125. os.imbue(l);
  126. f->put(oitr, os, os.fill(), p);
  127. }
  128. return os;
  129. }
  130. //! input operator for local_time_period
  131. template <class CharT, class Traits>
  132. inline
  133. std::basic_istream<CharT, Traits>&
  134. operator>>(std::basic_istream<CharT, Traits>& is, boost::local_time::local_time_period& tp)
  135. {
  136. boost::io::ios_flags_saver iflags(is);
  137. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  138. if (strm_sentry) {
  139. try {
  140. typedef typename date_time::time_input_facet<local_date_time, CharT> time_input_facet;
  141. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  142. if(std::has_facet<time_input_facet>(is.getloc())) {
  143. std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
  144. }
  145. else {
  146. time_input_facet* f = new time_input_facet();
  147. std::locale l = std::locale(is.getloc(), f);
  148. is.imbue(l);
  149. f->get(sit, str_end, is, tp);
  150. }
  151. }
  152. catch(...) {
  153. std::ios_base::iostate exception_mask = is.exceptions();
  154. if(std::ios_base::failbit & exception_mask) {
  155. try { is.setstate(std::ios_base::failbit); }
  156. catch(std::ios_base::failure&) {}
  157. throw; // rethrow original exception
  158. }
  159. else {
  160. is.setstate(std::ios_base::failbit);
  161. }
  162. }
  163. }
  164. return is;
  165. }
  166. } } // namespaces
  167. #endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__