posix_time_io.hpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #ifndef DATE_TIME_POSIX_TIME_IO_HPP__
  2. #define DATE_TIME_POSIX_TIME_IO_HPP__
  3. /* Copyright (c) 2004-2005 CrystalClear Software, Inc.
  4. * Use, modification and distribution is subject to the
  5. * Boost Software License, Version 1.0. (See accompanying
  6. * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
  7. * Author: Jeff Garland, Bart Garst
  8. * $Date$
  9. */
  10. #include <locale>
  11. #include <iostream>
  12. #include <iterator> // i/ostreambuf_iterator
  13. #include <boost/io/ios_state.hpp>
  14. #include <boost/date_time/time_facet.hpp>
  15. #include <boost/date_time/period_formatter.hpp>
  16. #include <boost/date_time/posix_time/ptime.hpp>
  17. #include <boost/date_time/posix_time/time_period.hpp>
  18. #include <boost/date_time/posix_time/posix_time_duration.hpp>
  19. #include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets
  20. namespace boost {
  21. namespace posix_time {
  22. //! wptime_facet is depricated and will be phased out. use wtime_facet instead
  23. //typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
  24. //! ptime_facet is depricated and will be phased out. use time_facet instead
  25. //typedef boost::date_time::time_facet<ptime, char> ptime_facet;
  26. //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead
  27. //typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet;
  28. //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead
  29. //typedef boost::date_time::time_input_facet<ptime,char> ptime_input_facet;
  30. typedef boost::date_time::time_facet<ptime, wchar_t> wtime_facet;
  31. typedef boost::date_time::time_facet<ptime, char> time_facet;
  32. typedef boost::date_time::time_input_facet<ptime, wchar_t> wtime_input_facet;
  33. typedef boost::date_time::time_input_facet<ptime, char> time_input_facet;
  34. template <class CharT, class TraitsT>
  35. inline
  36. std::basic_ostream<CharT, TraitsT>&
  37. operator<<(std::basic_ostream<CharT, TraitsT>& os,
  38. const ptime& p) {
  39. boost::io::ios_flags_saver iflags(os);
  40. typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
  41. std::ostreambuf_iterator<CharT> oitr(os);
  42. if (std::has_facet<custom_ptime_facet>(os.getloc()))
  43. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
  44. else {
  45. //instantiate a custom facet for dealing with times since the user
  46. //has not put one in the stream so far. This is for efficiency
  47. //since we would always need to reconstruct for every time period
  48. //if the locale did not already exist. Of course this will be overridden
  49. //if the user imbues as some later point.
  50. custom_ptime_facet* f = new custom_ptime_facet();
  51. std::locale l = std::locale(os.getloc(), f);
  52. os.imbue(l);
  53. f->put(oitr, os, os.fill(), p);
  54. }
  55. return os;
  56. }
  57. //! input operator for ptime
  58. template <class CharT, class Traits>
  59. inline
  60. std::basic_istream<CharT, Traits>&
  61. operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt)
  62. {
  63. boost::io::ios_flags_saver iflags(is);
  64. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  65. if (strm_sentry) {
  66. try {
  67. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
  68. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  69. if(std::has_facet<time_input_facet_local>(is.getloc())) {
  70. std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, pt);
  71. }
  72. else {
  73. time_input_facet_local* f = new time_input_facet_local();
  74. std::locale l = std::locale(is.getloc(), f);
  75. is.imbue(l);
  76. f->get(sit, str_end, is, pt);
  77. }
  78. }
  79. catch(...) {
  80. // mask tells us what exceptions are turned on
  81. std::ios_base::iostate exception_mask = is.exceptions();
  82. // if the user wants exceptions on failbit, we'll rethrow our
  83. // date_time exception & set the failbit
  84. if(std::ios_base::failbit & exception_mask) {
  85. try { is.setstate(std::ios_base::failbit); }
  86. catch(std::ios_base::failure&) {} // ignore this one
  87. throw; // rethrow original exception
  88. }
  89. else {
  90. // if the user want's to fail quietly, we simply set the failbit
  91. is.setstate(std::ios_base::failbit);
  92. }
  93. }
  94. }
  95. return is;
  96. }
  97. template <class CharT, class TraitsT>
  98. inline
  99. std::basic_ostream<CharT, TraitsT>&
  100. operator<<(std::basic_ostream<CharT, TraitsT>& os,
  101. const boost::posix_time::time_period& p) {
  102. boost::io::ios_flags_saver iflags(os);
  103. typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
  104. std::ostreambuf_iterator<CharT> oitr(os);
  105. if (std::has_facet<custom_ptime_facet>(os.getloc())) {
  106. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
  107. }
  108. else {
  109. //instantiate a custom facet for dealing with periods since the user
  110. //has not put one in the stream so far. This is for efficiency
  111. //since we would always need to reconstruct for every time period
  112. //if the local did not already exist. Of course this will be overridden
  113. //if the user imbues as some later point.
  114. custom_ptime_facet* f = new custom_ptime_facet();
  115. std::locale l = std::locale(os.getloc(), f);
  116. os.imbue(l);
  117. f->put(oitr, os, os.fill(), p);
  118. }
  119. return os;
  120. }
  121. //! input operator for time_period
  122. template <class CharT, class Traits>
  123. inline
  124. std::basic_istream<CharT, Traits>&
  125. operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp)
  126. {
  127. boost::io::ios_flags_saver iflags(is);
  128. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  129. if (strm_sentry) {
  130. try {
  131. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
  132. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  133. if(std::has_facet<time_input_facet_local>(is.getloc())) {
  134. std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, tp);
  135. }
  136. else {
  137. time_input_facet_local* f = new time_input_facet_local();
  138. std::locale l = std::locale(is.getloc(), f);
  139. is.imbue(l);
  140. f->get(sit, str_end, is, tp);
  141. }
  142. }
  143. catch(...) {
  144. std::ios_base::iostate exception_mask = is.exceptions();
  145. if(std::ios_base::failbit & exception_mask) {
  146. try { is.setstate(std::ios_base::failbit); }
  147. catch(std::ios_base::failure&) {}
  148. throw; // rethrow original exception
  149. }
  150. else {
  151. is.setstate(std::ios_base::failbit);
  152. }
  153. }
  154. }
  155. return is;
  156. }
  157. //! ostream operator for posix_time::time_duration
  158. // todo fix to use facet -- place holder for now...
  159. template <class CharT, class Traits>
  160. inline
  161. std::basic_ostream<CharT, Traits>&
  162. operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td)
  163. {
  164. boost::io::ios_flags_saver iflags(os);
  165. typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
  166. std::ostreambuf_iterator<CharT> oitr(os);
  167. if (std::has_facet<custom_ptime_facet>(os.getloc()))
  168. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
  169. else {
  170. //instantiate a custom facet for dealing with times since the user
  171. //has not put one in the stream so far. This is for efficiency
  172. //since we would always need to reconstruct for every time period
  173. //if the locale did not already exist. Of course this will be overridden
  174. //if the user imbues as some later point.
  175. custom_ptime_facet* f = new custom_ptime_facet();
  176. std::locale l = std::locale(os.getloc(), f);
  177. os.imbue(l);
  178. f->put(oitr, os, os.fill(), td);
  179. }
  180. return os;
  181. }
  182. //! input operator for time_duration
  183. template <class CharT, class Traits>
  184. inline
  185. std::basic_istream<CharT, Traits>&
  186. operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td)
  187. {
  188. boost::io::ios_flags_saver iflags(is);
  189. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  190. if (strm_sentry) {
  191. try {
  192. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet_local;
  193. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  194. if(std::has_facet<time_input_facet_local>(is.getloc())) {
  195. std::use_facet<time_input_facet_local>(is.getloc()).get(sit, str_end, is, td);
  196. }
  197. else {
  198. time_input_facet_local* f = new time_input_facet_local();
  199. std::locale l = std::locale(is.getloc(), f);
  200. is.imbue(l);
  201. f->get(sit, str_end, is, td);
  202. }
  203. }
  204. catch(...) {
  205. std::ios_base::iostate exception_mask = is.exceptions();
  206. if(std::ios_base::failbit & exception_mask) {
  207. try { is.setstate(std::ios_base::failbit); }
  208. catch(std::ios_base::failure&) {}
  209. throw; // rethrow original exception
  210. }
  211. else {
  212. is.setstate(std::ios_base::failbit);
  213. }
  214. }
  215. }
  216. return is;
  217. }
  218. } } // namespaces
  219. #endif // DATE_TIME_POSIX_TIME_IO_HPP__