posix_time_io.hpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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: 2008-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
  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. typedef std::time_put<CharT> std_ptime_facet;
  42. std::ostreambuf_iterator<CharT> oitr(os);
  43. if (std::has_facet<custom_ptime_facet>(os.getloc()))
  44. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
  45. else {
  46. //instantiate a custom facet for dealing with times since the user
  47. //has not put one in the stream so far. This is for efficiency
  48. //since we would always need to reconstruct for every time period
  49. //if the locale did not already exist. Of course this will be overridden
  50. //if the user imbues as some later point.
  51. custom_ptime_facet* f = new custom_ptime_facet();
  52. std::locale l = std::locale(os.getloc(), f);
  53. os.imbue(l);
  54. f->put(oitr, os, os.fill(), p);
  55. }
  56. return os;
  57. }
  58. //! input operator for ptime
  59. template <class CharT, class Traits>
  60. inline
  61. std::basic_istream<CharT, Traits>&
  62. operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt)
  63. {
  64. boost::io::ios_flags_saver iflags(is);
  65. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  66. if (strm_sentry) {
  67. try {
  68. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
  69. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  70. if(std::has_facet<time_input_facet>(is.getloc())) {
  71. std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, pt);
  72. }
  73. else {
  74. time_input_facet* f = new time_input_facet();
  75. std::locale l = std::locale(is.getloc(), f);
  76. is.imbue(l);
  77. f->get(sit, str_end, is, pt);
  78. }
  79. }
  80. catch(...) {
  81. // mask tells us what exceptions are turned on
  82. std::ios_base::iostate exception_mask = is.exceptions();
  83. // if the user wants exceptions on failbit, we'll rethrow our
  84. // date_time exception & set the failbit
  85. if(std::ios_base::failbit & exception_mask) {
  86. try { is.setstate(std::ios_base::failbit); }
  87. catch(std::ios_base::failure&) {} // ignore this one
  88. throw; // rethrow original exception
  89. }
  90. else {
  91. // if the user want's to fail quietly, we simply set the failbit
  92. is.setstate(std::ios_base::failbit);
  93. }
  94. }
  95. }
  96. return is;
  97. }
  98. template <class CharT, class TraitsT>
  99. inline
  100. std::basic_ostream<CharT, TraitsT>&
  101. operator<<(std::basic_ostream<CharT, TraitsT>& os,
  102. const boost::posix_time::time_period& p) {
  103. boost::io::ios_flags_saver iflags(os);
  104. typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
  105. typedef std::time_put<CharT> std_time_facet;
  106. std::ostreambuf_iterator<CharT> oitr(os);
  107. if (std::has_facet<custom_ptime_facet>(os.getloc())) {
  108. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
  109. }
  110. else {
  111. //instantiate a custom facet for dealing with periods since the user
  112. //has not put one in the stream so far. This is for efficiency
  113. //since we would always need to reconstruct for every time period
  114. //if the local did not already exist. Of course this will be overridden
  115. //if the user imbues as some later point.
  116. custom_ptime_facet* f = new custom_ptime_facet();
  117. std::locale l = std::locale(os.getloc(), f);
  118. os.imbue(l);
  119. f->put(oitr, os, os.fill(), p);
  120. }
  121. return os;
  122. }
  123. //! input operator for time_period
  124. template <class CharT, class Traits>
  125. inline
  126. std::basic_istream<CharT, Traits>&
  127. operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp)
  128. {
  129. boost::io::ios_flags_saver iflags(is);
  130. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  131. if (strm_sentry) {
  132. try {
  133. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
  134. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  135. if(std::has_facet<time_input_facet>(is.getloc())) {
  136. std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
  137. }
  138. else {
  139. time_input_facet* f = new time_input_facet();
  140. std::locale l = std::locale(is.getloc(), f);
  141. is.imbue(l);
  142. f->get(sit, str_end, is, tp);
  143. }
  144. }
  145. catch(...) {
  146. std::ios_base::iostate exception_mask = is.exceptions();
  147. if(std::ios_base::failbit & exception_mask) {
  148. try { is.setstate(std::ios_base::failbit); }
  149. catch(std::ios_base::failure&) {}
  150. throw; // rethrow original exception
  151. }
  152. else {
  153. is.setstate(std::ios_base::failbit);
  154. }
  155. }
  156. }
  157. return is;
  158. }
  159. //! ostream operator for posix_time::time_duration
  160. // todo fix to use facet -- place holder for now...
  161. template <class CharT, class Traits>
  162. inline
  163. std::basic_ostream<CharT, Traits>&
  164. operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td)
  165. {
  166. boost::io::ios_flags_saver iflags(os);
  167. typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
  168. typedef std::time_put<CharT> std_ptime_facet;
  169. std::ostreambuf_iterator<CharT> oitr(os);
  170. if (std::has_facet<custom_ptime_facet>(os.getloc()))
  171. std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
  172. else {
  173. //instantiate a custom facet for dealing with times since the user
  174. //has not put one in the stream so far. This is for efficiency
  175. //since we would always need to reconstruct for every time period
  176. //if the locale did not already exist. Of course this will be overridden
  177. //if the user imbues as some later point.
  178. custom_ptime_facet* f = new custom_ptime_facet();
  179. std::locale l = std::locale(os.getloc(), f);
  180. os.imbue(l);
  181. f->put(oitr, os, os.fill(), td);
  182. }
  183. return os;
  184. }
  185. //! input operator for time_duration
  186. template <class CharT, class Traits>
  187. inline
  188. std::basic_istream<CharT, Traits>&
  189. operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td)
  190. {
  191. boost::io::ios_flags_saver iflags(is);
  192. typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
  193. if (strm_sentry) {
  194. try {
  195. typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
  196. std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
  197. if(std::has_facet<time_input_facet>(is.getloc())) {
  198. std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, td);
  199. }
  200. else {
  201. time_input_facet* f = new time_input_facet();
  202. std::locale l = std::locale(is.getloc(), f);
  203. is.imbue(l);
  204. f->get(sit, str_end, is, td);
  205. }
  206. }
  207. catch(...) {
  208. std::ios_base::iostate exception_mask = is.exceptions();
  209. if(std::ios_base::failbit & exception_mask) {
  210. try { is.setstate(std::ios_base::failbit); }
  211. catch(std::ios_base::failure&) {}
  212. throw; // rethrow original exception
  213. }
  214. else {
  215. is.setstate(std::ios_base::failbit);
  216. }
  217. }
  218. }
  219. return is;
  220. }
  221. } } // namespaces
  222. #endif // DATE_TIME_POSIX_TIME_IO_HPP__