local_time_io.hpp 7.0 KB

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