local_time_io.hpp 6.8 KB

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