Browse Source

added more dependency for asio

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jinmei-asio@1212 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 15 years ago
parent
commit
64593f39e0
100 changed files with 18714 additions and 0 deletions
  1. 178 0
      ext/boost/date_time/adjust_functors.hpp
  2. 66 0
      ext/boost/date_time/c_local_time_adjustor.hpp
  3. 105 0
      ext/boost/date_time/c_time.hpp
  4. 171 0
      ext/boost/date_time/compiler_config.hpp
  5. 121 0
      ext/boost/date_time/constrained_value.hpp
  6. 197 0
      ext/boost/date_time/date.hpp
  7. 77 0
      ext/boost/date_time/date_clock_device.hpp
  8. 26 0
      ext/boost/date_time/date_defs.hpp
  9. 146 0
      ext/boost/date_time/date_duration.hpp
  10. 269 0
      ext/boost/date_time/date_duration_types.hpp
  11. 764 0
      ext/boost/date_time/date_facet.hpp
  12. 159 0
      ext/boost/date_time/date_format_simple.hpp
  13. 127 0
      ext/boost/date_time/date_formatting.hpp
  14. 121 0
      ext/boost/date_time/date_formatting_limited.hpp
  15. 233 0
      ext/boost/date_time/date_formatting_locales.hpp
  16. 265 0
      ext/boost/date_time/date_generator_formatter.hpp
  17. 330 0
      ext/boost/date_time/date_generator_parser.hpp
  18. 509 0
      ext/boost/date_time/date_generators.hpp
  19. 101 0
      ext/boost/date_time/date_iterator.hpp
  20. 320 0
      ext/boost/date_time/date_names_put.hpp
  21. 316 0
      ext/boost/date_time/date_parsing.hpp
  22. 391 0
      ext/boost/date_time/dst_rules.hpp
  23. 75 0
      ext/boost/date_time/dst_transition_generators.hpp
  24. 170 0
      ext/boost/date_time/filetime_functions.hpp
  25. 743 0
      ext/boost/date_time/format_date_parser.hpp
  26. 66 0
      ext/boost/date_time/gregorian/conversion.hpp
  27. 162 0
      ext/boost/date_time/gregorian/formatters.hpp
  28. 81 0
      ext/boost/date_time/gregorian/formatters_limited.hpp
  29. 47 0
      ext/boost/date_time/gregorian/greg_calendar.hpp
  30. 136 0
      ext/boost/date_time/gregorian/greg_date.hpp
  31. 57 0
      ext/boost/date_time/gregorian/greg_day.hpp
  32. 38 0
      ext/boost/date_time/gregorian/greg_day_of_year.hpp
  33. 134 0
      ext/boost/date_time/gregorian/greg_duration.hpp
  34. 43 0
      ext/boost/date_time/gregorian/greg_duration_types.hpp
  35. 354 0
      ext/boost/date_time/gregorian/greg_facet.hpp
  36. 105 0
      ext/boost/date_time/gregorian/greg_month.hpp
  37. 489 0
      ext/boost/date_time/gregorian/greg_serialize.hpp
  38. 66 0
      ext/boost/date_time/gregorian/greg_weekday.hpp
  39. 53 0
      ext/boost/date_time/gregorian/greg_year.hpp
  40. 33 0
      ext/boost/date_time/gregorian/greg_ymd.hpp
  41. 38 0
      ext/boost/date_time/gregorian/gregorian.hpp
  42. 784 0
      ext/boost/date_time/gregorian/gregorian_io.hpp
  43. 109 0
      ext/boost/date_time/gregorian/gregorian_types.hpp
  44. 91 0
      ext/boost/date_time/gregorian/parsers.hpp
  45. 70 0
      ext/boost/date_time/gregorian_calendar.hpp
  46. 219 0
      ext/boost/date_time/gregorian_calendar.ipp
  47. 509 0
      ext/boost/date_time/int_adapter.hpp
  48. 303 0
      ext/boost/date_time/iso_format.hpp
  49. 34 0
      ext/boost/date_time/local_time/conversion.hpp
  50. 169 0
      ext/boost/date_time/local_time/custom_time_zone.hpp
  51. 115 0
      ext/boost/date_time/local_time/date_duration_operators.hpp
  52. 77 0
      ext/boost/date_time/local_time/dst_transition_day_rules.hpp
  53. 527 0
      ext/boost/date_time/local_time/local_date_time.hpp
  54. 24 0
      ext/boost/date_time/local_time/local_time.hpp
  55. 186 0
      ext/boost/date_time/local_time/local_time_io.hpp
  56. 52 0
      ext/boost/date_time/local_time/local_time_types.hpp
  57. 464 0
      ext/boost/date_time/local_time/posix_time_zone.hpp
  58. 32 0
      ext/boost/date_time/local_time/tz_database.hpp
  59. 218 0
      ext/boost/date_time/local_time_adjustor.hpp
  60. 193 0
      ext/boost/date_time/local_timezone_defs.hpp
  61. 31 0
      ext/boost/date_time/locale_config.hpp
  62. 127 0
      ext/boost/date_time/microsec_time_clock.hpp
  63. 29 0
      ext/boost/date_time/parse_format_base.hpp
  64. 377 0
      ext/boost/date_time/period.hpp
  65. 196 0
      ext/boost/date_time/period_formatter.hpp
  66. 198 0
      ext/boost/date_time/period_parser.hpp
  67. 91 0
      ext/boost/date_time/posix_time/conversion.hpp
  68. 114 0
      ext/boost/date_time/posix_time/date_duration_operators.hpp
  69. 39 0
      ext/boost/date_time/posix_time/posix_time.hpp
  70. 178 0
      ext/boost/date_time/posix_time/posix_time_config.hpp
  71. 82 0
      ext/boost/date_time/posix_time/posix_time_duration.hpp
  72. 239 0
      ext/boost/date_time/posix_time/posix_time_io.hpp
  73. 153 0
      ext/boost/date_time/posix_time/posix_time_legacy_io.hpp
  74. 68 0
      ext/boost/date_time/posix_time/posix_time_system.hpp
  75. 55 0
      ext/boost/date_time/posix_time/posix_time_types.hpp
  76. 65 0
      ext/boost/date_time/posix_time/ptime.hpp
  77. 289 0
      ext/boost/date_time/posix_time/time_formatters.hpp
  78. 211 0
      ext/boost/date_time/posix_time/time_formatters_limited.hpp
  79. 44 0
      ext/boost/date_time/posix_time/time_parsers.hpp
  80. 29 0
      ext/boost/date_time/posix_time/time_period.hpp
  81. 200 0
      ext/boost/date_time/posix_time/time_serialize.hpp
  82. 25 0
      ext/boost/date_time/special_defs.hpp
  83. 96 0
      ext/boost/date_time/special_values_formatter.hpp
  84. 159 0
      ext/boost/date_time/special_values_parser.hpp
  85. 33 0
      ext/boost/date_time/string_convert.hpp
  86. 278 0
      ext/boost/date_time/string_parse_tree.hpp
  87. 125 0
      ext/boost/date_time/strings_from_facet.hpp
  88. 191 0
      ext/boost/date_time/time.hpp
  89. 83 0
      ext/boost/date_time/time_clock.hpp
  90. 43 0
      ext/boost/date_time/time_defs.hpp
  91. 282 0
      ext/boost/date_time/time_duration.hpp
  92. 1327 0
      ext/boost/date_time/time_facet.hpp
  93. 122 0
      ext/boost/date_time/time_formatting_streams.hpp
  94. 52 0
      ext/boost/date_time/time_iterator.hpp
  95. 321 0
      ext/boost/date_time/time_parsing.hpp
  96. 144 0
      ext/boost/date_time/time_resolution_traits.hpp
  97. 254 0
      ext/boost/date_time/time_system_counted.hpp
  98. 207 0
      ext/boost/date_time/time_system_split.hpp
  99. 99 0
      ext/boost/date_time/time_zone_base.hpp
  100. 0 0
      ext/boost/date_time/time_zone_names.hpp

+ 178 - 0
ext/boost/date_time/adjust_functors.hpp

@@ -0,0 +1,178 @@
+#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___
+#define _DATE_TIME_ADJUST_FUNCTORS_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/date.hpp"
+#include "boost/date_time/wrapping_int.hpp"
+
+namespace boost {
+namespace date_time {
+  
+
+  //! Functor to iterate a fixed number of days
+  template<class date_type>
+  class day_functor 
+  {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    day_functor(int f) : f_(f) {}
+    duration_type get_offset(const date_type& d) const 
+    {
+      // why is 'd' a parameter???
+      // fix compiler warnings
+      d.year();
+      return duration_type(f_);
+    }
+    duration_type get_neg_offset(const date_type& d) const 
+    {
+      // fix compiler warnings
+      d.year();
+      return duration_type(-f_);
+    }
+  private:
+    int f_;
+  };
+
+
+  //! Provides calculation to find next nth month given a date
+  /*! This adjustment function provides the logic for 'month-based'
+   *  advancement on a ymd based calendar.  The policy it uses 
+   *  to handle the non existant end of month days is to back
+   *  up to the last day of the month.  Also, if the starting
+   *  date is the last day of a month, this functor will attempt
+   *  to adjust to the end of the month.
+
+   */
+  template<class date_type>
+  class month_functor 
+  {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    typedef typename date_type::calendar_type cal_type;
+    typedef typename cal_type::ymd_type ymd_type;
+    typedef typename cal_type::day_type day_type;
+
+    month_functor(int f) : f_(f), origDayOfMonth_(0) {}
+    duration_type get_offset(const date_type& d) const 
+    {
+      ymd_type ymd(d.year_month_day());
+      if (origDayOfMonth_ == 0) {
+        origDayOfMonth_ = ymd.day;
+        day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
+        if (endOfMonthDay == ymd.day) {
+          origDayOfMonth_ = -1; //force the value to the end of month
+        }
+      }
+      typedef date_time::wrapping_int2<short,1,12> wrap_int2;
+      typedef typename wrap_int2::int_type int_type;
+      wrap_int2 wi(ymd.month);
+      //calc the year wrap around, add() returns 0 or 1 if wrapped
+      int_type year = wi.add(static_cast<int_type>(f_)); 
+      year = static_cast<int_type>(year + ymd.year); //calculate resulting year
+//       std::cout << "trace wi: " << wi.as_int() << std::endl;
+//       std::cout << "trace year: " << year << std::endl;
+      //find the last day for the new month
+      day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
+      //original was the end of month -- force to last day of month
+      if (origDayOfMonth_ == -1) {
+        return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
+      }
+      day_type dayOfMonth = origDayOfMonth_;
+      if (dayOfMonth > resultingEndOfMonthDay) {
+        dayOfMonth = resultingEndOfMonthDay;
+      }
+      return date_type(year, wi.as_int(), dayOfMonth) - d;
+    }
+    //! Returns a negative duration_type
+    duration_type get_neg_offset(const date_type& d) const 
+    {
+      ymd_type ymd(d.year_month_day());
+      if (origDayOfMonth_ == 0) {
+        origDayOfMonth_ = ymd.day;
+        day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month));
+        if (endOfMonthDay == ymd.day) {
+          origDayOfMonth_ = -1; //force the value to the end of month
+        }
+      }
+      typedef date_time::wrapping_int2<short,1,12> wrap_int2;
+      typedef typename wrap_int2::int_type int_type;
+      wrap_int2 wi(ymd.month);
+      //calc the year wrap around, add() returns 0 or 1 if wrapped
+      int_type year = wi.subtract(static_cast<int_type>(f_)); 
+      year = static_cast<int_type>(year + ymd.year); //calculate resulting year
+      //find the last day for the new month
+      day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int()));
+      //original was the end of month -- force to last day of month
+      if (origDayOfMonth_ == -1) {
+        return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d;
+      }
+      day_type dayOfMonth = origDayOfMonth_;
+      if (dayOfMonth > resultingEndOfMonthDay) {
+        dayOfMonth = resultingEndOfMonthDay;
+      }
+      return date_type(year, wi.as_int(), dayOfMonth) - d;
+    }
+  private:
+    int f_;
+    mutable short origDayOfMonth_;
+  };
+
+
+  //! Functor to iterate a over weeks
+  template<class date_type>
+  class week_functor 
+  {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    typedef typename date_type::calendar_type calendar_type;
+    week_functor(int f) : f_(f) {}
+    duration_type get_offset(const date_type& d) const 
+    {
+      // why is 'd' a parameter???
+      // fix compiler warnings
+      d.year();
+      return duration_type(f_*calendar_type::days_in_week());
+    }
+    duration_type get_neg_offset(const date_type& d) const 
+    {
+      // fix compiler warnings
+      d.year();
+      return duration_type(-f_*calendar_type::days_in_week());
+    }
+  private:
+    int f_;
+  };
+
+  //! Functor to iterate by a year adjusting for leap years
+  template<class date_type>
+  class year_functor 
+  {
+  public:
+    //typedef typename date_type::year_type year_type;
+    typedef typename date_type::duration_type duration_type;
+    year_functor(int f) : _mf(f * 12) {}
+    duration_type get_offset(const date_type& d) const 
+    {
+      return _mf.get_offset(d);
+    }
+    duration_type get_neg_offset(const date_type& d) const 
+    {
+      return _mf.get_neg_offset(d);
+    }
+  private:
+    month_functor<date_type> _mf;
+  };
+
+  
+} }//namespace date_time
+
+
+#endif
+

+ 66 - 0
ext/boost/date_time/c_local_time_adjustor.hpp

@@ -0,0 +1,66 @@
+#ifndef DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
+#define DATE_TIME_C_LOCAL_TIME_ADJUSTOR_HPP__
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file c_local_time_adjustor.hpp
+  Time adjustment calculations based on machine
+*/
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/c_time.hpp>
+
+namespace boost {
+namespace date_time {
+
+  //! Adjust to / from utc using the C API
+  /*! Warning!!! This class assumes that timezone settings of the
+   *  machine are correct.  This can be a very dangerous assumption.
+   */
+  template<class time_type>
+  class c_local_adjustor {
+  public:
+    typedef typename time_type::time_duration_type time_duration_type;
+    typedef typename time_type::date_type date_type;
+    typedef typename date_type::duration_type date_duration_type;
+    //! Convert a utc time to local time
+    static time_type utc_to_local(const time_type& t)
+    {
+      date_type time_t_start_day(1970,1,1);
+      time_type time_t_start_time(time_t_start_day,time_duration_type(0,0,0));
+      if (t < time_t_start_time) {
+        boost::throw_exception(std::out_of_range("Cannot convert dates prior to Jan 1, 1970"));
+        BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_t_start_time); // should never reach
+      }
+      date_duration_type dd = t.date() - time_t_start_day;
+      time_duration_type td = t.time_of_day();
+      std::time_t t2 = dd.days()*86400 + td.hours()*3600 + td.minutes()*60 + td.seconds();
+      std::tm tms, *tms_ptr;
+      tms_ptr = c_time::localtime(&t2, &tms);
+      date_type d(static_cast<unsigned short>(tms_ptr->tm_year + 1900),
+                  static_cast<unsigned short>(tms_ptr->tm_mon + 1),
+                  static_cast<unsigned short>(tms_ptr->tm_mday));
+      time_duration_type td2(tms_ptr->tm_hour,
+                             tms_ptr->tm_min,
+                             tms_ptr->tm_sec,
+                             t.time_of_day().fractional_seconds());
+      
+      return time_type(d,td2);
+    }
+  };
+
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 105 - 0
ext/boost/date_time/c_time.hpp

@@ -0,0 +1,105 @@
+#ifndef DATE_TIME_C_TIME_HPP___
+#define DATE_TIME_C_TIME_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+/*! @file c_time.hpp
+  Provide workarounds related to the ctime header
+*/
+
+#include <ctime>
+#include <string> // to be able to convert from string literals to exceptions
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+//Work around libraries that don't put time_t and time in namespace std
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std { using ::time_t; using ::time; using ::localtime;
+                using ::tm;  using ::gmtime; }
+#endif // BOOST_NO_STDC_NAMESPACE
+
+//The following is used to support high precision time clocks
+#ifdef BOOST_HAS_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+#ifdef BOOST_HAS_FTIME
+#include <time.h>
+#endif
+
+namespace boost {
+namespace date_time {
+  //! Provides a uniform interface to some 'ctime' functions
+  /*! Provides a uniform interface to some ctime functions and 
+   * their '_r' counterparts. The '_r' functions require a pointer to a 
+   * user created std::tm struct whereas the regular functions use a 
+   * staticly created struct and return a pointer to that. These wrapper 
+   * functions require the user to create a std::tm struct and send in a 
+   * pointer to it. A pointer to the user created struct will be returned.
+   * All functions do proper checking of the C function results and throw
+   * exceptions on error. Therefore the functions will never return NULL.
+   */
+  struct c_time {
+    public:
+#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS)
+      //! requires a pointer to a user created std::tm struct
+      inline
+      static std::tm* localtime(const std::time_t* t, std::tm* result)
+      {
+        // localtime_r() not in namespace std???
+        result = localtime_r(t, result);
+        if (!result)
+          boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
+        return result;
+      }
+      //! requires a pointer to a user created std::tm struct
+      inline
+      static std::tm* gmtime(const std::time_t* t, std::tm* result)
+      {
+        // gmtime_r() not in namespace std???
+        result = gmtime_r(t, result);
+        if (!result)
+          boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
+        return result;
+      }
+#else // BOOST_HAS_THREADS
+
+#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
+#pragma warning(push) // preserve warning settings
+#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8
+#endif // _MSC_VER >= 1400
+      //! requires a pointer to a user created std::tm struct
+      inline
+      static std::tm* localtime(const std::time_t* t, std::tm* result)
+      {
+        result = std::localtime(t);
+        if (!result)
+          boost::throw_exception(std::runtime_error("could not convert calendar time to local time"));
+        return result;
+      }
+      //! requires a pointer to a user created std::tm struct
+      inline
+      static std::tm* gmtime(const std::time_t* t, std::tm* result)
+      {
+        result = std::gmtime(t);
+        if (!result)
+          boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time"));
+        return result;
+      }
+#if (defined(_MSC_VER) && (_MSC_VER >= 1400))
+#pragma warning(pop) // restore warnings to previous state
+#endif // _MSC_VER >= 1400
+
+#endif // BOOST_HAS_THREADS
+  };
+}} // namespaces
+                
+#endif // DATE_TIME_C_TIME_HPP___

+ 171 - 0
ext/boost/date_time/compiler_config.hpp

@@ -0,0 +1,171 @@
+#ifndef DATE_TIME_COMPILER_CONFIG_HPP___
+#define DATE_TIME_COMPILER_CONFIG_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <cstdlib>
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+// With boost release 1.33, date_time will be using a different,
+// more flexible, IO system. This new system is not compatible with
+// old compilers. The original date_time IO system remains for those
+// compilers. They must define this macro to use the legacy IO.
+//     (defined(__BORLANDC__) && (__BORLANDC__ <= 0x0581) ) )   &&
+ #if(  BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) ) \
+    || BOOST_WORKAROUND( __GNUC__, < 3)                         \
+    || (BOOST_WORKAROUND( _MSC_VER, <= 1300) )                  \
+    )                                                           \
+    && !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+# define USE_DATE_TIME_PRE_1_33_FACET_IO
+#endif
+
+
+// This file performs some local compiler configurations
+
+#include <boost/date_time/locale_config.hpp> //set up locale configurations
+
+//Set up a configuration parameter for platforms that have 
+//GetTimeOfDay
+#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME)
+#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+#endif
+
+// To Force no default constructors for date & ptime, un-comment following
+//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+
+// Include extensions to date_duration - comment out to remove this feature
+#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+// these extensions are known to cause problems with gcc295
+#if defined(__GNUC__) && (__GNUC__ < 3)
+#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+#endif
+
+#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( __BORLANDC__,  BOOST_TESTED_AT(0x581) ) )
+#define BOOST_DATE_TIME_NO_MEMBER_INIT
+#endif
+
+// include these types before we try to re-define them
+#include <boost/cstdint.hpp>
+
+//Define INT64_C for compilers that don't have it
+#if (!defined(INT64_C))
+#define INT64_C(value)  int64_t(value)
+#endif
+
+
+/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */
+#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_RW_LIB)
+#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR
+#endif
+
+
+// Borland v5.64 does not have the following in std namespace; v5.5.1 does
+#if defined(__BORLANDC__) && defined(BOOST_BCB_WITH_STLPORT)
+#include <locale>
+namespace std {
+  using stlport::tolower;
+  using stlport::ctype;
+  using stlport::use_facet;
+}
+#endif
+
+// workaround for errors associated with output for date classes 
+// modifications and input streaming for time classes. 
+// Compilers affected are:
+// gcc295, msvc (neither with STLPort), any borland
+// 
+#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \
+      (defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \
+      !defined(_STLP_OWN_IOSTREAMS) ) || \
+      BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
+#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
+#endif
+
+// The macro marks up places where compiler complains for missing return statement or
+// uninitialized variables after calling to boost::throw_exception.
+// BOOST_UNREACHABLE_RETURN doesn't work since even compilers that support
+// unreachable statements detection emit such warnings.
+#if defined(_MSC_VER)
+// Use special MSVC extension to markup unreachable code
+#  define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) __assume(false)
+#elif !defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION)
+// Call to a non-returning function should suppress the warning
+#  if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std {
+    using ::abort;
+}
+#  endif // defined(BOOST_NO_STDC_NAMESPACE)
+#  define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) std::abort()
+#else
+// For other poor compilers the specified expression is compiled. Usually, this would be a return statement.
+#  define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) x
+#endif
+
+/* The following handles the definition of the necessary macros
+ * for dll building on Win32 platforms.
+ * 
+ * For code that will be placed in the date_time .dll, 
+ * it must be properly prefixed with BOOST_DATE_TIME_DECL.
+ * The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE
+ * defined before including its header. For examples see:
+ * greg_month.hpp & greg_month.cpp
+ * 
+ */
+
+#ifdef BOOST_HAS_DECLSPEC // defined in config system
+   // we need to import/export our code only if the user has specifically
+   // asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
+   // libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK
+   // if they want just this one to be dynamically liked:
+#  if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
+      // export if this is our own source, otherwise import:
+#     ifdef BOOST_DATE_TIME_SOURCE
+#       define BOOST_DATE_TIME_DECL __declspec(dllexport)
+#     else
+#       define BOOST_DATE_TIME_DECL __declspec(dllimport)
+#     endif  // BOOST_DATE_TIME_SOURCE
+#  endif  // DYN_LINK
+#endif  // BOOST_HAS_DECLSPEC
+//
+// if BOOST_WHATEVER_DECL isn't defined yet define it now:
+#ifndef BOOST_DATE_TIME_DECL
+#  define BOOST_DATE_TIME_DECL
+#endif
+
+//
+// Automatically link to the correct build variant where possible. 
+// 
+#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE)
+//
+// Set the name of our library, this will get undef'ed by auto_link.hpp
+// once it's done with it:
+//
+#define BOOST_LIB_NAME boost_date_time
+//
+// If we're importing code from a dll, then tell auto_link.hpp about it:
+//
+#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK)
+#  define BOOST_DYN_LINK
+#endif
+//
+// And include the header that does the work:
+//
+#include <boost/config/auto_link.hpp>
+#endif  // auto-linking disabled
+
+#if defined(BOOST_HAS_THREADS) 
+#  if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) ||  defined(__BORLANDC__)
+     //no reentrant posix functions (eg: localtime_r)
+#  elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT)))
+#   define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS
+#  endif
+#endif
+
+
+#endif

+ 121 - 0
ext/boost/date_time/constrained_value.hpp

@@ -0,0 +1,121 @@
+#ifndef CONSTRAINED_VALUE_HPP___
+#define CONSTRAINED_VALUE_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <exception>
+#include <stdexcept>
+#include <boost/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost {
+
+//! Namespace containing constrained_value template and types
+namespace CV {
+  //! Represent a min or max violation type
+  enum violation_enum {min_violation, max_violation};
+  
+  //! A template to specify a constrained basic value type
+  /*! This template provides a quick way to generate
+   *  an integer type with a constrained range.  The type
+   *  provides for the ability to specify the min, max, and
+   *  and error handling policy.
+   *  
+   *  <b>value policies</b>
+   *  A class that provides the range limits via the min and
+   *  max functions as well as a function on_error that 
+   *  determines how errors are handled.  A common strategy
+   *  would be to assert or throw and exception.  The on_error
+   *  is passed both the current value and the new value that
+   *  is in error.
+   *
+   */
+  template<class value_policies>
+  class constrained_value {
+  public:
+    typedef typename value_policies::value_type value_type;
+    //    typedef except_type exception_type;
+    constrained_value(value_type value) : value_((min)())
+    {
+      assign(value);
+    }
+    constrained_value& operator=(value_type v)
+    {
+      assign(v); 
+      return *this;
+    }
+    //! Return the max allowed value (traits method)
+    static value_type max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();}
+    //! Return the min allowed value (traits method)
+    static value_type min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();}
+    //! Coerce into the representation type
+    operator value_type() const {return value_;}
+  protected:
+    value_type value_;
+  private:
+    void assign(value_type value)
+    {
+      //adding 1 below gets rid of a compiler warning which occurs when the 
+      //min_value is 0 and the type is unsigned....
+      if (value+1 < (min)()+1) {
+        value_policies::on_error(value_, value, min_violation);
+        return;
+      }
+      if (value > (max)()) {
+        value_policies::on_error(value_, value, max_violation);
+        return;
+      }
+      value_ = value;
+    }
+};
+
+  //! Template to shortcut the constrained_value policy creation process
+  template<typename rep_type, rep_type min_value, 
+           rep_type max_value, class exception_type>
+  class simple_exception_policy
+  {
+    struct exception_wrapper : public exception_type
+    {
+      // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode,
+      // we'll have to provide a way to acquire std::exception from the exception being thrown.
+      // However, we cannot derive from it, since it would make it interceptable by this class,
+      // which might not be what the user wanted.
+      operator std::out_of_range () const
+      {
+        // TODO: Make the message more descriptive by using arguments to on_error
+        return std::out_of_range("constrained value boundary has been violated");
+      }
+    };
+
+    typedef typename mpl::if_<
+      is_base_of< std::exception, exception_type >,
+      exception_type,
+      exception_wrapper
+    >::type actual_exception_type;
+
+  public:
+    typedef rep_type value_type;
+    static rep_type min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; }
+    static rep_type max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; }
+    static void on_error(rep_type, rep_type, violation_enum)
+    {
+      boost::throw_exception(actual_exception_type());
+    }
+  };
+
+
+
+} } //namespace CV
+
+
+
+
+#endif

+ 197 - 0
ext/boost/date_time/date.hpp

@@ -0,0 +1,197 @@
+#ifndef DATE_TIME_DATE_HPP___
+#define DATE_TIME_DATE_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/year_month_day.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include "boost/operators.hpp"
+
+namespace boost {
+namespace date_time {
+
+  //!Representation of timepoint at the one day level resolution.
+  /*! 
+    The date template represents an interface shell for a date class
+    that is based on a year-month-day system such as the gregorian
+    or iso systems.  It provides basic operations to enable calculation
+    and comparisons.  
+
+    <b>Theory</b>
+
+    This date representation fundamentally departs from the C tm struct 
+    approach.  The goal for this type is to provide efficient date
+    operations (add, subtract) and storage (minimize space to represent)
+    in a concrete class.  Thus, the date uses a count internally to
+    represent a particular date.  The calendar parameter defines 
+    the policies for converting the the year-month-day and internal
+    counted form here.  Applications that need to perform heavy
+    formatting of the same date repeatedly will perform better
+    by using the year-month-day representation.
+    
+    Internally the date uses a day number to represent the date.
+    This is a monotonic time representation. This representation 
+    allows for fast comparison as well as simplifying
+    the creation of writing numeric operations.  Essentially, the 
+    internal day number is like adjusted julian day.  The adjustment
+    is determined by the Epoch date which is represented as day 1 of
+    the calendar.  Day 0 is reserved for negative infinity so that
+    any actual date is automatically greater than negative infinity.
+    When a date is constructed from a date or formatted for output,
+    the appropriate conversions are applied to create the year, month,
+    day representations.
+  */
+
+  
+  template<class T, class calendar, class duration_type_> 
+  class date : private 
+       boost::less_than_comparable<T 
+     , boost::equality_comparable<T 
+    > >
+  {
+  public:
+    typedef T date_type;
+    typedef calendar calendar_type;
+    typedef typename calendar::date_traits_type traits_type;
+    typedef duration_type_ duration_type;
+    typedef typename calendar::year_type year_type;
+    typedef typename calendar::month_type month_type;
+    typedef typename calendar::day_type day_type;
+    typedef typename calendar::ymd_type ymd_type;
+    typedef typename calendar::date_rep_type date_rep_type;
+    typedef typename calendar::date_int_type date_int_type;
+    typedef typename calendar::day_of_week_type day_of_week_type;
+    date(year_type y, month_type m, day_type d) 
+      : days_(calendar::day_number(ymd_type(y, m, d)))
+    {}
+    date(const ymd_type& ymd) 
+      : days_(calendar::day_number(ymd))
+      {}
+    //let the compiler write copy, assignment, and destructor
+    year_type        year() const
+    {
+      ymd_type ymd = calendar::from_day_number(days_); 
+      return ymd.year;
+    }
+    month_type       month() const
+    {
+      ymd_type ymd = calendar::from_day_number(days_); 
+      return ymd.month;
+    }
+    day_type         day() const
+    {
+      ymd_type ymd = calendar::from_day_number(days_); 
+      return ymd.day;
+    }
+    day_of_week_type day_of_week() const
+    {
+      ymd_type ymd = calendar::from_day_number(days_);
+      return calendar::day_of_week(ymd);
+    }
+    ymd_type         year_month_day() const
+    {
+      return calendar::from_day_number(days_);
+    }
+    bool operator<(const date_type& rhs)  const
+    {
+      return days_ < rhs.days_;
+    }
+    bool operator==(const date_type& rhs) const
+    {
+      return days_ == rhs.days_;
+    }
+    //! check to see if date is a special value
+    bool is_special()const
+    {
+      return(is_not_a_date() || is_infinity());
+    }
+    //! check to see if date is not a value
+    bool is_not_a_date()  const
+    {
+      return traits_type::is_not_a_number(days_);
+    }
+    //! check to see if date is one of the infinity values
+    bool is_infinity()  const
+    {
+      return traits_type::is_inf(days_);
+    }
+    //! check to see if date is greater than all possible dates
+    bool is_pos_infinity()  const
+    {
+      return traits_type::is_pos_inf(days_);
+    }
+    //! check to see if date is greater than all possible dates
+    bool is_neg_infinity()  const
+    {
+      return traits_type::is_neg_inf(days_);
+    }
+    //! return as a special value or a not_special if a normal date
+    special_values as_special()  const
+    {
+      return traits_type::to_special(days_);
+    }
+    duration_type operator-(const date_type& d) const
+    {
+      date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_);
+      return duration_type(val.as_number());
+    }
+    
+    date_type operator-(const duration_type& dd) const
+    {
+      if(dd.is_special())
+      {
+        return date_type(date_rep_type(days_) - dd.get_rep());
+      }
+      return date_type(date_rep_type(days_) - dd.days());
+    }
+    date_type operator-=(const duration_type& dd)
+    {
+      *this = *this - dd;
+      return date_type(days_);
+    }
+    date_rep_type day_count() const 
+    {
+      return days_;
+    };
+    //allow internal access from operators
+    date_type operator+(const duration_type& dd) const
+    {
+      if(dd.is_special())
+      {
+        return date_type(date_rep_type(days_) + dd.get_rep());
+      }
+      return date_type(date_rep_type(days_) + dd.days());
+    }
+    date_type operator+=(const duration_type& dd)
+    {
+      *this = *this + dd; 
+      return date_type(days_);
+    }
+
+    //see reference
+  protected:
+    /*! This is a private constructor which allows for the creation of new 
+      dates.  It is not exposed to users since that would require class 
+      users to understand the inner workings of the date class.
+    */
+    explicit date(date_int_type days) : days_(days) {};
+    explicit date(date_rep_type days) : days_(days.as_number()) {};
+    date_int_type days_;
+    
+  };
+
+
+
+  
+} } // namespace date_time
+
+
+
+
+#endif

+ 77 - 0
ext/boost/date_time/date_clock_device.hpp

@@ -0,0 +1,77 @@
+#ifndef DATE_CLOCK_DEVICE_HPP___
+#define DATE_CLOCK_DEVICE_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/c_time.hpp"
+
+
+namespace boost {
+namespace date_time {
+
+  //! A clock providing day level services based on C time_t capabilities
+  /*! This clock uses Posix interfaces as its implementation and hence
+   *  uses the timezone settings of the operating system.  Incorrect
+   *  user settings will result in incorrect results for the calls
+   *  to local_day.
+   */
+  template<class date_type> 
+  class day_clock
+  {
+  public:
+    typedef typename date_type::ymd_type ymd_type;
+    //! Get the local day as a date type
+    static date_type local_day() 
+    {
+      return date_type(local_day_ymd());
+    }
+    //! Get the local day as a ymd_type
+    static typename date_type::ymd_type local_day_ymd() 
+    {
+      ::std::tm result;
+      ::std::tm* curr = get_local_time(result);
+      return ymd_type(curr->tm_year + 1900, 
+                      curr->tm_mon + 1, 
+                      curr->tm_mday);
+    }
+    //! Get the current day in universal date as a ymd_type
+    static typename date_type::ymd_type universal_day_ymd() 
+    {
+      ::std::tm result;
+      ::std::tm* curr = get_universal_time(result);
+      return ymd_type(curr->tm_year + 1900, 
+                      curr->tm_mon + 1, 
+                      curr->tm_mday);
+    }
+    //! Get the UTC day as a date type
+    static date_type universal_day() 
+    {
+      return date_type(universal_day_ymd());
+    }
+
+  private:
+    static ::std::tm* get_local_time(std::tm& result) 
+    {
+      ::std::time_t t;
+      ::std::time(&t);
+      return c_time::localtime(&t, &result);
+    }
+    static ::std::tm* get_universal_time(std::tm& result) 
+    {
+      ::std::time_t t;
+      ::std::time(&t);
+      return c_time::gmtime(&t, &result);
+    }
+
+  };
+
+} } //namespace date_time
+
+
+#endif

+ 26 - 0
ext/boost/date_time/date_defs.hpp

@@ -0,0 +1,26 @@
+#ifndef DATE_TIME_DATE_DEFS_HPP
+#define DATE_TIME_DATE_DEFS_HPP
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+  //! An enumeration of weekday names
+  enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
+
+  //! Simple enum to allow for nice programming with Jan, Feb, etc
+  enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths};
+
+} } //namespace date_time
+
+
+
+#endif

+ 146 - 0
ext/boost/date_time/date_duration.hpp

@@ -0,0 +1,146 @@
+#ifndef DATE_TIME_DATE_DURATION__
+#define DATE_TIME_DATE_DURATION__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include <boost/operators.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+  //! Duration type with date level resolution
+  template<class duration_rep_traits>
+  class date_duration : private
+              boost::less_than_comparable1< date_duration< duration_rep_traits >
+            , boost::equality_comparable1< date_duration< duration_rep_traits >
+            , boost::addable1< date_duration< duration_rep_traits >
+            , boost::subtractable1< date_duration< duration_rep_traits >
+            , boost::dividable2< date_duration< duration_rep_traits >, int
+            > > > > >
+  { 
+  public:
+    typedef typename duration_rep_traits::int_type duration_rep_type;
+    typedef typename duration_rep_traits::impl_type duration_rep;
+    
+    //! Construct from a day count
+    explicit date_duration(duration_rep day_count) : days_(day_count) {};
+    
+    /*! construct from special_values - only works when
+     * instantiated with duration_traits_adapted */
+    date_duration(special_values sv) :
+            days_(duration_rep::from_special(sv))
+    {}
+
+    // copy constructor required for addable<> & subtractable<>
+    //! Construct from another date_duration (Copy Constructor)
+    date_duration(const date_duration<duration_rep_traits>& other) :
+            days_(other.days_)
+    {}
+
+    //! returns days_ as it's instantiated type - used for streaming
+    duration_rep get_rep()const
+    {
+        return days_;
+    }
+    bool is_special()const
+    {
+        return days_.is_special();
+    }
+    //! returns days as value, not object.
+    duration_rep_type days() const
+    {
+        return duration_rep_traits::as_number(days_);
+    }
+    //! Returns the smallest duration -- used by to calculate 'end'
+    static date_duration unit()
+    {
+        return date_duration<duration_rep_traits>(1);
+    }
+    //! Equality
+    bool operator==(const date_duration& rhs) const
+    {
+        return days_ == rhs.days_;
+    }
+    //! Less
+    bool operator<(const date_duration& rhs) const
+    {
+        return days_ < rhs.days_;
+    }
+
+    /* For shortcut operators (+=, -=, etc) simply using
+     * "days_ += days_" may not work. If instantiated with
+     * an int_adapter, shortcut operators are not present,
+     * so this will not compile */
+
+    //! Subtract another duration -- result is signed
+    date_duration& operator-=(const date_duration& rhs)
+    {
+        //days_ -= rhs.days_;
+        days_ = days_ - rhs.days_;
+        return *this;
+    }
+    //! Add a duration -- result is signed
+    date_duration& operator+=(const date_duration& rhs)
+    {
+        days_ = days_ + rhs.days_;
+        return *this;
+    }
+
+    //! unary- Allows for dd = -date_duration(2); -> dd == -2
+    date_duration operator-() const
+    {
+        return date_duration<duration_rep_traits>(get_rep() * (-1));
+    }
+    //! Division operations on a duration with an integer.
+    date_duration& operator/=(int divisor)
+    {
+        days_ = days_ / divisor;
+        return *this;
+    }
+
+    //! return sign information
+    bool is_negative() const
+    {
+        return days_ < 0;
+    }
+
+  private:
+    duration_rep days_;
+  };
+
+
+  /*! Struct for instantiating date_duration with <b>NO</b> special values
+   * functionality. Allows for transparent implementation of either
+   * date_duration<long> or date_duration<int_adapter<long> > */
+  struct duration_traits_long
+  {
+    typedef long int_type;
+    typedef long impl_type;
+    static int_type as_number(impl_type i) { return i; };
+  };
+
+  /*! Struct for instantiating date_duration <b>WITH</b> special values
+   * functionality. Allows for transparent implementation of either
+   * date_duration<long> or date_duration<int_adapter<long> > */
+  struct duration_traits_adapted
+  {
+    typedef long int_type;
+    typedef boost::date_time::int_adapter<long> impl_type;
+    static int_type as_number(impl_type i) { return i.as_number(); };
+  };
+  
+
+} } //namspace date_time
+
+
+#endif
+

+ 269 - 0
ext/boost/date_time/date_duration_types.hpp

@@ -0,0 +1,269 @@
+#ifndef DATE_DURATION_TYPES_HPP___
+#define DATE_DURATION_TYPES_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or 
+ * http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+                                                                                
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/date_duration.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+  //! Additional duration type that represents a number of n*7 days
+  template <class duration_config>
+  class weeks_duration : public date_duration<duration_config> {
+  public:
+    weeks_duration(typename duration_config::impl_type w) 
+      : date_duration<duration_config>(w * 7) {}
+    weeks_duration(special_values sv) 
+      : date_duration<duration_config>(sv) {}
+  };
+
+  // predeclare
+  template<class t>
+  class years_duration;
+
+  //! additional duration type that represents a logical month
+  /*! A logical month enables things like: "date(2002,Mar,2) + months(2) -> 
+   * 2002-May2". If the date is a last day-of-the-month, the result will 
+   * also be a last-day-of-the-month.
+   */
+  template<class base_config>
+  class months_duration 
+  {
+    private:
+      typedef typename base_config::int_rep int_rep;
+      typedef typename int_rep::int_type int_type;
+      typedef typename base_config::date_type date_type;
+      typedef typename date_type::duration_type duration_type;
+      typedef typename base_config::month_adjustor_type month_adjustor_type;
+      typedef months_duration<base_config> months_type;
+      typedef years_duration<base_config> years_type;
+    public:
+      months_duration(int_rep num) : _m(num) {}
+      months_duration(special_values sv) : _m(sv) 
+      {
+        _m = int_rep::from_special(sv);
+      }
+      int_rep number_of_months() const { return _m; }
+      //! returns a negative duration
+      duration_type get_neg_offset(const date_type& d) const
+      {
+        month_adjustor_type m_adj(_m.as_number());
+        return duration_type(m_adj.get_neg_offset(d));
+      }
+      duration_type get_offset(const date_type& d) const
+      {
+        month_adjustor_type m_adj(_m.as_number());
+        return duration_type(m_adj.get_offset(d));
+      }
+      bool operator==(const months_type& rhs) const
+      {
+        return(_m == rhs._m);
+      }
+      bool operator!=(const months_type& rhs) const
+      {
+        return(_m != rhs._m);
+      }
+      months_type operator+(const months_type& rhs)const
+      {
+        return months_type(_m + rhs._m);
+      }
+      months_type& operator+=(const months_type& rhs)
+      {
+        _m = _m + rhs._m;
+        return *this;
+      }
+      months_type operator-(const months_type& rhs)const
+      {
+        return months_type(_m - rhs._m);
+      }
+      months_type& operator-=(const months_type& rhs)
+      {
+        _m = _m - rhs._m;
+        return *this;
+      }
+      months_type operator*(const int_type rhs)const
+      {
+        return months_type(_m * rhs);
+      }
+      months_type& operator*=(const int_type rhs)
+      {
+        _m = _m * rhs;
+        return *this;
+      }
+      months_type operator/(const int_type rhs)const
+      {
+        return months_type(_m / rhs);
+      }
+      months_type& operator/=(const int_type rhs)
+      {
+        _m = _m / rhs;
+        return *this;
+      }
+      months_type operator+(const years_type& y)const
+      {
+        return months_type(y.number_of_years() * 12 + _m);
+      }
+      months_type& operator+=(const years_type& y)
+      {
+        _m = y.number_of_years() * 12 + _m;
+        return *this;
+      }
+      months_type operator-(const years_type& y) const
+      {
+        return months_type(_m - y.number_of_years() * 12);
+      }
+      months_type& operator-=(const years_type& y)
+      {
+        _m = _m - y.number_of_years() * 12;
+        return *this;
+      }
+
+      //
+      friend date_type operator+(const date_type& d, const months_type& m)
+      {
+        return d + m.get_offset(d);
+      }
+      friend date_type operator+=(date_type& d, const months_type& m)
+      {
+        return d += m.get_offset(d);
+      }
+      friend date_type operator-(const date_type& d, const months_type& m)
+      {
+        // get_neg_offset returns a negative duration, so we add
+        return d + m.get_neg_offset(d);
+      }
+      friend date_type operator-=(date_type& d, const months_type& m)
+      {
+        // get_neg_offset returns a negative duration, so we add
+        return d += m.get_neg_offset(d);
+      }
+        
+    private:
+      int_rep _m;
+  };
+
+  //! additional duration type that represents a logical year
+  /*! A logical year enables things like: "date(2002,Mar,2) + years(2) -> 
+   * 2004-Mar-2". If the date is a last day-of-the-month, the result will 
+   * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) ->
+   * 2004-Feb-29).
+   */
+  template<class base_config>
+  class years_duration 
+  {
+    private:
+      typedef typename base_config::int_rep int_rep;
+      typedef typename int_rep::int_type int_type;
+      typedef typename base_config::date_type date_type;
+      typedef typename date_type::duration_type duration_type;
+      typedef typename base_config::month_adjustor_type month_adjustor_type;
+      typedef years_duration<base_config> years_type;
+      typedef months_duration<base_config> months_type;
+    public:
+      years_duration(int_rep num) : _y(num) {}
+      years_duration(special_values sv) : _y(sv) 
+      {
+        _y = int_rep::from_special(sv);
+      }
+      int_rep number_of_years() const { return _y; }
+      //! returns a negative duration
+      duration_type get_neg_offset(const date_type& d) const
+      {
+        month_adjustor_type m_adj(_y.as_number() * 12);
+        return duration_type(m_adj.get_neg_offset(d));
+      }
+      duration_type get_offset(const date_type& d) const
+      {
+        month_adjustor_type m_adj(_y.as_number() * 12);
+        return duration_type(m_adj.get_offset(d));
+      }
+      bool operator==(const years_type& rhs) const
+      {
+        return(_y == rhs._y);
+      }
+      bool operator!=(const years_type& rhs) const
+      {
+        return(_y != rhs._y);
+      }
+      years_type operator+(const years_type& rhs)const
+      {
+        return years_type(_y + rhs._y);
+      }
+      years_type& operator+=(const years_type& rhs)
+      {
+        _y = _y + rhs._y;
+        return *this;
+      }
+      years_type operator-(const years_type& rhs)const
+      {
+        return years_type(_y - rhs._y);
+      }
+      years_type& operator-=(const years_type& rhs)
+      {
+        _y = _y - rhs._y;
+        return *this;
+      }
+      years_type operator*(const int_type rhs)const
+      {
+        return years_type(_y * rhs);
+      }
+      years_type& operator*=(const int_type rhs)
+      {
+        _y = _y * rhs;
+        return *this;
+      }
+      years_type operator/(const int_type rhs)const
+      {
+        return years_type(_y / rhs);
+      }
+      years_type& operator/=(const int_type rhs)
+      {
+        _y = _y / rhs;
+        return *this;
+      }
+      months_type operator+(const months_type& m) const
+      {
+        return(months_type(_y * 12 + m.number_of_months()));
+      }
+      months_type operator-(const months_type& m) const
+      {
+        return(months_type(_y * 12 - m.number_of_months()));
+      }
+
+      //
+      friend date_type operator+(const date_type& d, const years_type& y)
+      {
+        return d + y.get_offset(d);
+      }
+      friend date_type operator+=(date_type& d, const years_type& y)
+      {
+        return d += y.get_offset(d);
+      }
+      friend date_type operator-(const date_type& d, const years_type& y)
+      {
+        // get_neg_offset returns a negative duration, so we add
+        return d + y.get_neg_offset(d);
+      }
+      friend date_type operator-=(date_type& d, const years_type& y)
+      {
+        // get_neg_offset returns a negative duration, so we add
+        return d += y.get_neg_offset(d);
+      }
+
+    private:
+      int_rep _y;
+  };
+
+}} // namespace boost::date_time
+
+#endif // DATE_DURATION_TYPES_HPP___

+ 764 - 0
ext/boost/date_time/date_facet.hpp

@@ -0,0 +1,764 @@
+#ifndef _DATE_TIME_DATE_FACET__HPP___
+#define _DATE_TIME_DATE_FACET__HPP___
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author:  Martin Andrian, Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 07:40:18 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <locale>
+#include <string>
+#include <vector>
+#include <iterator> // ostreambuf_iterator
+#include <boost/throw_exception.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/period.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/special_values_formatter.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/period_parser.hpp>
+#include <boost/date_time/date_generator_formatter.hpp>
+#include <boost/date_time/date_generator_parser.hpp>
+#include <boost/date_time/format_date_parser.hpp>
+
+namespace boost { namespace date_time {
+
+
+  /*! Class that provides format based I/O facet for date types.
+   *
+   * This class allows the formatting of dates by using format string.
+   * Format strings are:
+   *
+   *  - %A => long_weekday_format - Full name Ex: Tuesday
+   *  - %a => short_weekday_format - Three letter abbreviation Ex: Tue
+   *  - %B => long_month_format - Full name Ex: October
+   *  - %b => short_month_format - Three letter abbreviation Ex: Oct
+   *  - %x => standard_format_specifier - defined by the locale
+   *  - %Y-%b-%d => default_date_format - YYYY-Mon-dd
+   *
+   * Default month format == %b
+   * Default weekday format == %a
+   */
+  template <class date_type,
+            class CharT,
+            class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+  class date_facet : public std::locale::facet {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    // greg_weekday is gregorian_calendar::day_of_week_type
+    typedef typename date_type::day_of_week_type day_of_week_type;
+    typedef typename date_type::day_type day_type;
+    typedef typename date_type::month_type month_type;
+    typedef boost::date_time::period<date_type,duration_type> period_type;
+    typedef std::basic_string<CharT> string_type;
+    typedef CharT                    char_type;
+    typedef boost::date_time::period_formatter<CharT>  period_formatter_type;
+    typedef boost::date_time::special_values_formatter<CharT>  special_values_formatter_type;
+    typedef std::vector<std::basic_string<CharT> > input_collection_type;
+    // used for the output of the date_generators
+    typedef date_generator_formatter<date_type, CharT> date_gen_formatter_type;
+    typedef partial_date<date_type>          partial_date_type;
+    typedef nth_kday_of_month<date_type>     nth_kday_type;
+    typedef first_kday_of_month<date_type>   first_kday_type;
+    typedef last_kday_of_month<date_type>    last_kday_type;
+    typedef first_kday_after<date_type>      kday_after_type;
+    typedef first_kday_before<date_type>     kday_before_type;
+    static const char_type long_weekday_format[3];
+    static const char_type short_weekday_format[3];
+    static const char_type long_month_format[3];
+    static const char_type short_month_format[3];
+    static const char_type default_period_separator[4];
+    static const char_type standard_format_specifier[3];
+    static const char_type iso_format_specifier[7];
+    static const char_type iso_format_extended_specifier[9];
+    static const char_type default_date_format[9]; // YYYY-Mon-DD
+    static std::locale::id id;
+
+#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
+      std::locale::id& __get_id (void) const { return id; }
+#endif
+
+    explicit date_facet(::size_t a_ref = 0)
+      : std::locale::facet(a_ref),
+        //m_format(standard_format_specifier)
+        m_format(default_date_format),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format)
+    {}
+
+    explicit date_facet(const char_type* format_str,
+                        const input_collection_type& short_names,
+                        ::size_t ref_count = 0)
+      : std::locale::facet(ref_count),
+        m_format(format_str),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format),
+        m_month_short_names(short_names)
+    {}
+
+
+    explicit date_facet(const char_type* format_str,
+                        period_formatter_type per_formatter = period_formatter_type(),
+                        special_values_formatter_type sv_formatter = special_values_formatter_type(),
+                        date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
+                        ::size_t ref_count = 0)
+      : std::locale::facet(ref_count),
+        m_format(format_str),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format),
+        m_period_formatter(per_formatter),
+        m_date_gen_formatter(dg_formatter),
+        m_special_values_formatter(sv_formatter)
+     {}
+    void format(const char_type* const format_str) {
+      m_format = format_str;
+    }
+    virtual void set_iso_format()
+    {
+      m_format = iso_format_specifier;
+    }
+    virtual void set_iso_extended_format()
+    {
+      m_format = iso_format_extended_specifier;
+    }
+    void month_format(const char_type* const format_str) {
+      m_month_format = format_str;
+    }
+    void weekday_format(const char_type* const format_str) {
+      m_weekday_format = format_str;
+    }
+
+    void period_formatter(period_formatter_type per_formatter) {
+      m_period_formatter= per_formatter;
+    }
+    void special_values_formatter(const special_values_formatter_type& svf)
+    {
+      m_special_values_formatter = svf;
+    }
+    void short_weekday_names(const input_collection_type& short_names)
+    {
+      m_weekday_short_names = short_names;
+    }
+    void long_weekday_names(const input_collection_type& long_names)
+    {
+      m_weekday_long_names = long_names;
+    }
+
+    void short_month_names(const input_collection_type& short_names)
+    {
+      m_month_short_names = short_names;
+    }
+
+    void long_month_names(const input_collection_type& long_names)
+    {
+      m_month_long_names = long_names;
+    }
+
+    void date_gen_phrase_strings(const input_collection_type& new_strings,
+                           typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first)
+    {
+      m_date_gen_formatter.elements(new_strings, beg_pos);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const date_type& d) const
+    {
+      if (d.is_special()) {
+        return do_put_special(next, a_ios, fill_char, d.as_special());
+      }
+      //The following line of code required the date to support a to_tm function
+      return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const duration_type& dd) const
+    {
+      if (dd.is_special()) {
+        return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special());
+      }
+
+      typedef std::num_put<CharT, OutItrT> num_put;
+      if (std::has_facet<num_put>(a_ios.getloc())) {
+        return std::use_facet<num_put>(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number());
+      }
+      else {
+        num_put* f = new num_put();
+        std::locale l = std::locale(a_ios.getloc(), f);
+        a_ios.imbue(l);
+        return f->put(next, a_ios, fill_char, dd.get_rep().as_number());
+      }
+
+    }
+
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const month_type& m) const
+    {
+      //if (d.is_special()) {
+      //  return do_put_special(next, a_ios, fill_char, d.as_special());
+      //}
+      //The following line of code required the date to support a to_tm function
+      std::tm dtm = {};
+      dtm.tm_mon = m - 1;
+      return do_put_tm(next, a_ios, fill_char, dtm, m_month_format);
+    }
+
+    //! puts the day of month
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const day_type& day) const
+    {
+      std::tm dtm = {};
+      dtm.tm_mday = day.as_number();
+      char_type tmp[3] = {'%','d'};
+      string_type temp_format(tmp);
+      return do_put_tm(next, a_ios, fill_char, dtm, temp_format);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const day_of_week_type& dow) const
+    {
+      //if (d.is_special()) {
+      //  return do_put_special(next, a_ios, fill_char, d.as_special());
+      //}
+      //The following line of code required the date to support a to_tm function
+      std::tm dtm = {};
+      dtm.tm_wday = dow;
+      return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format);
+    }
+
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const period_type& p) const
+    {
+      return m_period_formatter.put_period(next, a_ios, fill_char, p, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const partial_date_type& pd) const
+    {
+      return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const nth_kday_type& nkd) const
+    {
+      return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const first_kday_type& fkd) const
+    {
+      return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const last_kday_type& lkd) const
+    {
+      return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const kday_before_type& fkb) const
+    {
+      return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this);
+    }
+
+    OutItrT put(OutItrT next,
+                std::ios_base& a_ios,
+                char_type fill_char,
+                const kday_after_type& fka) const
+    {
+      return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this);
+    }
+
+  protected:
+    virtual OutItrT do_put_special(OutItrT next,
+                                   std::ios_base& /*a_ios*/,
+                                   char_type /*fill_char*/,
+                                   const boost::date_time::special_values sv) const
+    {
+      m_special_values_formatter.put_special(next, sv);
+      return next;
+    }
+    virtual OutItrT do_put_tm(OutItrT next,
+                              std::ios_base& a_ios,
+                              char_type fill_char,
+                              const tm& tm_value,
+                              string_type a_format) const
+    {
+      // update format string with custom names
+      if (m_weekday_long_names.size()) {
+        boost::algorithm::replace_all(a_format,
+                                      long_weekday_format,
+                                      m_weekday_long_names[tm_value.tm_wday]);
+      }
+      if (m_weekday_short_names.size()) {
+        boost::algorithm::replace_all(a_format,
+                                      short_weekday_format,
+                                      m_weekday_short_names[tm_value.tm_wday]);
+
+      }
+      if (m_month_long_names.size()) {
+        boost::algorithm::replace_all(a_format,
+                                      long_month_format,
+                                      m_month_long_names[tm_value.tm_mon]);
+      }
+      if (m_month_short_names.size()) {
+        boost::algorithm::replace_all(a_format,
+                                      short_month_format,
+                                      m_month_short_names[tm_value.tm_mon]);
+      }
+      // use time_put facet to create final string
+      const char_type* p_format = a_format.c_str();
+      return std::use_facet<std::time_put<CharT> >(a_ios.getloc()).put(next, a_ios,
+                                                                       fill_char,
+                                                                       &tm_value,
+                                                                       p_format,
+                                                                       p_format + a_format.size());
+    }
+  protected:
+    string_type                   m_format;
+    string_type                   m_month_format;
+    string_type                   m_weekday_format;
+    period_formatter_type         m_period_formatter;
+    date_gen_formatter_type       m_date_gen_formatter;
+    special_values_formatter_type m_special_values_formatter;
+    input_collection_type         m_month_short_names;
+    input_collection_type         m_month_long_names;
+    input_collection_type         m_weekday_short_names;
+    input_collection_type         m_weekday_long_names;
+  private:
+  };
+
+  template <class date_type, class CharT, class OutItrT>
+  std::locale::id date_facet<date_type, CharT, OutItrT>::id;
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
+    {'%', 'x' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
+    {'%', 'Y', '%', 'm', '%', 'd' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
+    {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_facet<date_type, CharT, OutItrT>::char_type
+  date_facet<date_type, CharT, OutItrT>::default_date_format[9] =
+    {'%','Y','-','%','b','-','%','d'};
+
+
+
+  //! Input facet
+  template <class date_type,
+            class CharT,
+            class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
+  class date_input_facet : public std::locale::facet {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    // greg_weekday is gregorian_calendar::day_of_week_type
+    typedef typename date_type::day_of_week_type day_of_week_type;
+    typedef typename date_type::day_type day_type;
+    typedef typename date_type::month_type month_type;
+    typedef typename date_type::year_type year_type;
+    typedef boost::date_time::period<date_type,duration_type> period_type;
+    typedef std::basic_string<CharT> string_type;
+    typedef CharT                    char_type;
+    typedef boost::date_time::period_parser<date_type, CharT>  period_parser_type;
+    typedef boost::date_time::special_values_parser<date_type,CharT> special_values_parser_type;
+    typedef std::vector<std::basic_string<CharT> > input_collection_type;
+    typedef format_date_parser<date_type, CharT> format_date_parser_type;
+    // date_generators stuff goes here
+    typedef date_generator_parser<date_type, CharT> date_gen_parser_type;
+    typedef partial_date<date_type>          partial_date_type;
+    typedef nth_kday_of_month<date_type>     nth_kday_type;
+    typedef first_kday_of_month<date_type>   first_kday_type;
+    typedef last_kday_of_month<date_type>    last_kday_type;
+    typedef first_kday_after<date_type>      kday_after_type;
+    typedef first_kday_before<date_type>     kday_before_type;
+
+    static const char_type long_weekday_format[3];
+    static const char_type short_weekday_format[3];
+    static const char_type long_month_format[3];
+    static const char_type short_month_format[3];
+    static const char_type four_digit_year_format[3];
+    static const char_type two_digit_year_format[3];
+    static const char_type default_period_separator[4];
+    static const char_type standard_format_specifier[3];
+    static const char_type iso_format_specifier[7];
+    static const char_type iso_format_extended_specifier[9];
+    static const char_type default_date_format[9]; // YYYY-Mon-DD
+    static std::locale::id id;
+
+    explicit date_input_facet(::size_t a_ref = 0)
+      : std::locale::facet(a_ref),
+        m_format(default_date_format),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format),
+        m_year_format(four_digit_year_format),
+        m_parser(m_format, std::locale::classic())
+        // default period_parser & special_values_parser used
+    {}
+
+    explicit date_input_facet(const string_type& format_str,
+                              ::size_t a_ref = 0)
+      : std::locale::facet(a_ref),
+        m_format(format_str),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format),
+        m_year_format(four_digit_year_format),
+        m_parser(m_format, std::locale::classic())
+        // default period_parser & special_values_parser used
+    {}
+
+    explicit date_input_facet(const string_type& format_str,
+                              const format_date_parser_type& date_parser,
+                              const special_values_parser_type& sv_parser,
+                              const period_parser_type& per_parser,
+                              const date_gen_parser_type& date_gen_parser,
+                              ::size_t ref_count = 0)
+      : std::locale::facet(ref_count),
+        m_format(format_str),
+        m_month_format(short_month_format),
+        m_weekday_format(short_weekday_format),
+        m_year_format(four_digit_year_format),
+        m_parser(date_parser),
+        m_date_gen_parser(date_gen_parser),
+        m_period_parser(per_parser),
+        m_sv_parser(sv_parser)
+    {}
+
+
+    void format(const char_type* const format_str) {
+      m_format = format_str;
+    }
+    virtual void set_iso_format()
+    {
+      m_format = iso_format_specifier;
+    }
+    virtual void set_iso_extended_format()
+    {
+      m_format = iso_format_extended_specifier;
+    }
+    void month_format(const char_type* const format_str) {
+      m_month_format = format_str;
+    }
+    void weekday_format(const char_type* const format_str) {
+      m_weekday_format = format_str;
+    }
+    void year_format(const char_type* const format_str) {
+      m_year_format = format_str;
+    }
+
+    void period_parser(period_parser_type per_parser) {
+      m_period_parser = per_parser;
+    }
+    void short_weekday_names(const input_collection_type& weekday_names)
+    {
+      m_parser.short_weekday_names(weekday_names);
+    }
+    void long_weekday_names(const input_collection_type& weekday_names)
+    {
+      m_parser.long_weekday_names(weekday_names);
+    }
+
+    void short_month_names(const input_collection_type& month_names)
+    {
+      m_parser.short_month_names(month_names);
+    }
+
+    void long_month_names(const input_collection_type& month_names)
+    {
+      m_parser.long_month_names(month_names);
+    }
+
+    void date_gen_element_strings(const input_collection_type& col)
+    {
+      m_date_gen_parser.element_strings(col);
+    }
+    void date_gen_element_strings(const string_type& first,
+                                  const string_type& second,
+                                  const string_type& third,
+                                  const string_type& fourth,
+                                  const string_type& fifth,
+                                  const string_type& last,
+                                  const string_type& before,
+                                  const string_type& after,
+                                  const string_type& of)
+
+    {
+      m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of);
+    }
+
+    void special_values_parser(special_values_parser_type sv_parser)
+    {
+      m_sv_parser = sv_parser;
+    }
+
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& /*a_ios*/,
+               date_type& d) const
+    {
+      d = m_parser.parse_date(from, to, m_format, m_sv_parser);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& /*a_ios*/,
+               month_type& m) const
+    {
+      m = m_parser.parse_month(from, to, m_month_format);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& /*a_ios*/,
+               day_of_week_type& wd) const
+    {
+      wd = m_parser.parse_weekday(from, to, m_weekday_format);
+      return from;
+    }
+    //! Expects 1 or 2 digit day range: 1-31
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& /*a_ios*/,
+               day_type& d) const
+    {
+      d = m_parser.parse_var_day_of_month(from, to);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& /*a_ios*/,
+               year_type& y) const
+    {
+      y = m_parser.parse_year(from, to, m_year_format);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               duration_type& dd) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*from) && from != to) { ++from; }
+
+      /* num_get.get() will always consume the first character if it
+       * is a sign indicator (+/-). Special value strings may begin
+       * with one of these signs so we'll need a copy of it
+       * in case num_get.get() fails. */
+      char_type c = '\0';
+      // TODO Are these characters somewhere in the locale?
+      if(*from == '-' || *from == '+') {
+        c = *from;
+      }
+      typedef std::num_get<CharT, InItrT> num_get;
+      typename duration_type::duration_rep_type val = 0;
+      std::ios_base::iostate err = std::ios_base::goodbit;
+
+      if (std::has_facet<num_get>(a_ios.getloc())) {
+        from = std::use_facet<num_get>(a_ios.getloc()).get(from, to, a_ios, err, val);
+      }
+      else {
+        num_get* ng = new num_get();
+        std::locale l = std::locale(a_ios.getloc(), ng);
+        a_ios.imbue(l);
+        from = ng->get(from, to, a_ios, err, val);
+      }
+      if(err & std::ios_base::failbit){
+        typedef typename special_values_parser_type::match_results match_results;
+        match_results mr;
+        if(c == '-' || c == '+') { // was the first character consumed?
+          mr.cache += c;
+        }
+        m_sv_parser.match(from, to, mr);
+        if(mr.current_match == match_results::PARSE_ERROR) {
+          boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+          BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return from); // should never reach
+        }
+        dd = duration_type(static_cast<special_values>(mr.current_match));
+      }
+      else {
+        dd = duration_type(val);
+      }
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               period_type& p) const
+    {
+      p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               nth_kday_type& nkd) const
+    {
+      nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               partial_date_type& pd) const
+    {
+
+      pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               first_kday_type& fkd) const
+    {
+      fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               last_kday_type& lkd) const
+    {
+      lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               kday_before_type& fkb) const
+    {
+      fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this);
+      return from;
+    }
+    InItrT get(InItrT& from,
+               InItrT& to,
+               std::ios_base& a_ios,
+               kday_after_type& fka) const
+    {
+      fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this);
+      return from;
+    }
+
+  protected:
+    string_type                   m_format;
+    string_type                   m_month_format;
+    string_type                   m_weekday_format;
+    string_type                   m_year_format;
+    format_date_parser_type       m_parser;
+    date_gen_parser_type          m_date_gen_parser;
+    period_parser_type            m_period_parser;
+    special_values_parser_type    m_sv_parser;
+  private:
+  };
+
+
+  template <class date_type, class CharT, class OutItrT>
+  std::locale::id date_input_facet<date_type, CharT, OutItrT>::id;
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::long_weekday_format[3] = {'%','A'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::short_weekday_format[3] = {'%','a'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::long_month_format[3] = {'%','B'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::short_month_format[3] = {'%','b'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::four_digit_year_format[3] = {'%','Y'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::two_digit_year_format[3] = {'%','y'};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::default_period_separator[4] = { ' ', '/', ' '};
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::standard_format_specifier[3] =
+    {'%', 'x' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::iso_format_specifier[7] =
+    {'%', 'Y', '%', 'm', '%', 'd' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::iso_format_extended_specifier[9] =
+    {'%', 'Y', '-', '%', 'm', '-', '%', 'd' };
+
+  template <class date_type, class CharT, class OutItrT>
+  const typename date_input_facet<date_type, CharT, OutItrT>::char_type
+  date_input_facet<date_type, CharT, OutItrT>::default_date_format[9] =
+    {'%','Y','-','%','b','-','%','d'};
+
+} } // namespaces
+
+
+#endif

+ 159 - 0
ext/boost/date_time/date_format_simple.hpp

@@ -0,0 +1,159 @@
+#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___
+#define DATE_TIME_SIMPLE_FORMAT_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/parse_format_base.hpp"
+
+namespace boost {
+namespace date_time {
+
+//! Class to provide simple basic formatting rules
+template<class charT>
+class simple_format {
+public:
+
+  //! String used printed is date is invalid
+  static const charT* not_a_date()
+  {
+    return "not-a-date-time";
+  }
+  //! String used to for positive infinity value
+  static const charT* pos_infinity()
+  {  
+    return "+infinity";
+  }
+  //! String used to for positive infinity value
+  static const charT* neg_infinity()
+  {
+    return "-infinity";
+  }
+  //! Describe month format
+  static month_format_spec month_format()
+  {
+    return month_as_short_string;
+  }
+  static ymd_order_spec date_order()
+  {
+    return ymd_order_iso; //YYYY-MM-DD
+  }
+  //! This format uses '-' to separate date elements
+  static bool has_date_sep_chars()
+  {
+    return true;
+  }
+  //! Char to sep?
+  static charT year_sep_char()
+  {
+    return '-';
+  }
+  //! char between year-month
+  static charT month_sep_char()
+  {
+    return '-';
+  }
+  //! Char to separate month-day
+  static charT day_sep_char()
+  {
+    return '-';
+  }
+  //! char between date-hours
+  static charT hour_sep_char()
+  {
+    return ' ';
+  }
+  //! char between hour and minute
+  static charT minute_sep_char()
+  {
+    return ':';
+  }
+  //! char for second
+  static charT second_sep_char()
+  {
+    return ':';
+  }
+
+};
+
+#ifndef BOOST_NO_STD_WSTRING
+
+//! Specialization of formmating rules for wchar_t
+template<>
+class simple_format<wchar_t> {
+public:
+
+  //! String used printed is date is invalid
+  static const wchar_t* not_a_date()
+  {
+    return L"not-a-date-time";
+  }
+  //! String used to for positive infinity value
+  static const wchar_t* pos_infinity()
+  {   
+    return L"+infinity";
+  }
+  //! String used to for positive infinity value
+  static const wchar_t* neg_infinity()
+  {
+    return L"-infinity";
+  }
+  //! Describe month format
+  static month_format_spec month_format()
+  {
+    return month_as_short_string;
+  }
+  static ymd_order_spec date_order()
+  {
+    return ymd_order_iso; //YYYY-MM-DD
+  }
+  //! This format uses '-' to separate date elements
+  static bool has_date_sep_chars()
+  {
+    return true;
+  }
+  //! Char to sep?
+  static wchar_t year_sep_char()
+  {
+    return '-';
+  }
+  //! char between year-month
+  static wchar_t month_sep_char()
+  {
+    return '-';
+  }
+  //! Char to separate month-day
+  static wchar_t day_sep_char()
+  {
+    return '-';
+  }
+  //! char between date-hours
+  static wchar_t hour_sep_char()
+  {
+    return ' ';
+  }
+  //! char between hour and minute
+  static wchar_t minute_sep_char()
+  {
+    return ':';
+  }
+  //! char for second
+  static wchar_t second_sep_char()
+  {
+    return ':';
+  }
+
+};
+
+#endif // BOOST_NO_STD_WSTRING
+} } //namespace date_time
+
+
+
+
+#endif

+ 127 - 0
ext/boost/date_time/date_formatting.hpp

@@ -0,0 +1,127 @@
+#ifndef DATE_TIME_DATE_FORMATTING_HPP___
+#define DATE_TIME_DATE_FORMATTING_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+/* NOTE: "formatter" code for older compilers, ones that define 
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in  
+ * date_formatting_limited.hpp
+ */
+
+namespace boost {
+namespace date_time {
+
+  //! Formats a month as as string into an ostream
+  template<class month_type, class format_type, class charT=char>
+  class month_formatter
+  {
+    typedef std::basic_ostream<charT> ostream_type;
+  public:
+    //! Formats a month as as string into an ostream
+    /*! This function demands that month_type provide
+     *  functions for converting to short and long strings
+     *  if that capability is used.
+     */
+    static ostream_type& format_month(const month_type& month,
+                                      ostream_type &os)
+    {
+      switch (format_type::month_format()) 
+      {
+        case month_as_short_string: 
+        { 
+          os << month.as_short_string(); 
+          break;
+        }
+        case month_as_long_string: 
+        { 
+          os << month.as_long_string(); 
+          break;
+        }
+        case month_as_integer: 
+        { 
+          os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number();
+          break;
+        }
+     
+      }
+      return os;
+    } // format_month
+  };
+
+
+  //! Convert ymd to a standard string formatting policies
+  template<class ymd_type, class format_type, class charT=char>
+  class ymd_formatter
+  {
+  public:
+    //! Convert ymd to a standard string formatting policies
+    /*! This is standard code for handling date formatting with
+     *  year-month-day based date information.  This function 
+     *  uses the format_type to control whether the string will
+     *  contain separator characters, and if so what the character
+     *  will be.  In addtion, it can format the month as either
+     *  an integer or a string as controled by the formatting 
+     *  policy
+     */ 
+    static std::basic_string<charT> ymd_to_string(ymd_type ymd)
+    {
+      typedef typename ymd_type::month_type month_type;
+      std::basic_ostringstream<charT> ss;
+      ss << ymd.year;
+      if (format_type::has_date_sep_chars()) {
+        ss << format_type::month_sep_char();
+      }
+      //this name is a bit ugly, oh well....
+      month_formatter<month_type,format_type,charT>::format_month(ymd.month, ss);
+      if (format_type::has_date_sep_chars()) {
+        ss << format_type::day_sep_char();
+      }
+      ss  << std::setw(2) << std::setfill(ss.widen('0')) 
+          << ymd.day;
+      return ss.str();
+    }
+  };
+
+
+  //! Convert a date to string using format policies
+  template<class date_type, class format_type, class charT=char>
+  class date_formatter
+  {
+  public:
+    typedef std::basic_string<charT> string_type;
+    //! Convert to a date to standard string using format policies
+    static string_type date_to_string(date_type d)
+    {
+      typedef typename date_type::ymd_type ymd_type;
+      if (d.is_not_a_date()) {
+        return string_type(format_type::not_a_date());
+      }
+      if (d.is_neg_infinity()) {
+        return string_type(format_type::neg_infinity());
+      }
+      if (d.is_pos_infinity()) {
+        return string_type(format_type::pos_infinity());
+      }
+      ymd_type ymd = d.year_month_day();
+      return ymd_formatter<ymd_type, format_type, charT>::ymd_to_string(ymd);
+    }    
+  };
+
+
+} } //namespace date_time
+
+
+#endif
+

+ 121 - 0
ext/boost/date_time/date_formatting_limited.hpp

@@ -0,0 +1,121 @@
+#ifndef DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
+#define DATE_TIME_DATE_FORMATTING_LIMITED_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+
+namespace boost {
+namespace date_time {
+
+  //! Formats a month as as string into an ostream
+  template<class month_type, class format_type>
+  class month_formatter
+  {
+  public:
+    //! Formats a month as as string into an ostream
+    /*! This function demands that month_type provide
+     *  functions for converting to short and long strings
+     *  if that capability is used.
+     */
+    static std::ostream& format_month(const month_type& month,
+                                      std::ostream& os)
+    {
+      switch (format_type::month_format()) 
+      {
+        case month_as_short_string: 
+        { 
+          os << month.as_short_string(); 
+          break;
+        }
+        case month_as_long_string: 
+        { 
+          os << month.as_long_string(); 
+          break;
+        }
+        case month_as_integer: 
+        { 
+          os << std::setw(2) << std::setfill('0') << month.as_number();
+          break;
+        }
+     
+      }
+      return os;
+    } // format_month
+  };
+
+
+  //! Convert ymd to a standard string formatting policies
+  template<class ymd_type, class format_type>
+  class ymd_formatter
+  {
+  public:
+    //! Convert ymd to a standard string formatting policies
+    /*! This is standard code for handling date formatting with
+     *  year-month-day based date information.  This function 
+     *  uses the format_type to control whether the string will
+     *  contain separator characters, and if so what the character
+     *  will be.  In addtion, it can format the month as either
+     *  an integer or a string as controled by the formatting 
+     *  policy
+     */ 
+    static std::string ymd_to_string(ymd_type ymd)
+    {
+      typedef typename ymd_type::month_type month_type;
+      std::ostringstream ss;
+      ss << ymd.year;
+      if (format_type::has_date_sep_chars()) {
+        ss << format_type::month_sep_char();
+      }
+      //this name is a bit ugly, oh well....
+      month_formatter<month_type,format_type>::format_month(ymd.month, ss);
+      if (format_type::has_date_sep_chars()) {
+        ss << format_type::day_sep_char();
+      }
+      ss  << std::setw(2) << std::setfill('0') 
+          << ymd.day;
+      return ss.str();
+    }
+  };
+
+
+  //! Convert a date to string using format policies
+  template<class date_type, class format_type>
+  class date_formatter
+  {
+  public:
+    //! Convert to a date to standard string using format policies
+    static std::string date_to_string(date_type d)
+    {
+      typedef typename date_type::ymd_type ymd_type;
+      if (d.is_not_a_date()) {
+        return format_type::not_a_date();
+      }
+      if (d.is_neg_infinity()) {
+        return format_type::neg_infinity();
+      }
+      if (d.is_pos_infinity()) {
+        return format_type::pos_infinity();
+      }
+      ymd_type ymd = d.year_month_day();
+      return ymd_formatter<ymd_type, format_type>::ymd_to_string(ymd);
+    }    
+  };
+
+
+} } //namespace date_time
+
+
+#endif
+

+ 233 - 0
ext/boost/date_time/date_formatting_locales.hpp

@@ -0,0 +1,233 @@
+#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
+#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_names_put.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+//#include <string>
+#include <sstream>
+#include <iomanip>
+
+
+namespace boost {
+namespace date_time {
+
+  //! Formats a month as as string into an ostream
+  template<class facet_type,
+           class charT = char>
+  class ostream_month_formatter
+  {
+  public:
+    typedef typename facet_type::month_type month_type;
+    typedef std::basic_ostream<charT> ostream_type;
+
+    //! Formats a month as as string into an output iterator
+    static void format_month(const month_type& month,
+                             ostream_type& os,
+                             const facet_type& f)
+    {
+
+      switch (f.month_format())
+      {
+        case month_as_short_string:
+        {
+          std::ostreambuf_iterator<charT> oitr(os);
+          f.put_month_short(oitr, month.as_enum());
+          break;
+        }
+        case month_as_long_string:
+        {
+          std::ostreambuf_iterator<charT> oitr(os);
+          f.put_month_long(oitr, month.as_enum());
+          break;
+        }
+        case month_as_integer:
+        {
+          charT fill_char = '0';
+          os << std::setw(2) << std::setfill(fill_char) << month.as_number();
+          break;
+        }
+
+      }
+    } // format_month
+
+  };
+
+
+  //! Formats a weekday
+  template<class weekday_type,
+           class facet_type,
+           class charT = char>
+  class ostream_weekday_formatter
+  {
+  public:
+    typedef typename facet_type::month_type month_type;
+    typedef std::basic_ostream<charT> ostream_type;
+
+    //! Formats a month as as string into an output iterator
+    static void format_weekday(const weekday_type& wd,
+                               ostream_type& os,
+                               const facet_type& f,
+                               bool  as_long_string)
+    {
+
+      std::ostreambuf_iterator<charT> oitr(os);
+      if (as_long_string) {
+        f.put_weekday_long(oitr, wd.as_enum());
+      }
+      else {
+        f.put_weekday_short(oitr, wd.as_enum());
+      }
+
+    } // format_weekday
+
+  };
+
+
+  //! Convert ymd to a standard string formatting policies
+  template<class ymd_type,
+           class facet_type,
+           class charT = char>
+  class ostream_ymd_formatter
+  {
+  public:
+    typedef typename ymd_type::month_type month_type;
+    typedef ostream_month_formatter<facet_type, charT> month_formatter_type;
+    typedef std::basic_ostream<charT> ostream_type;
+    typedef std::basic_string<charT> foo_type;
+
+    //! Convert ymd to a standard string formatting policies
+    /*! This is standard code for handling date formatting with
+     *  year-month-day based date information.  This function
+     *  uses the format_type to control whether the string will
+     *  contain separator characters, and if so what the character
+     *  will be.  In addtion, it can format the month as either
+     *  an integer or a string as controled by the formatting
+     *  policy
+     */
+    //     static string_type ymd_to_string(ymd_type ymd)
+//     {
+//       std::ostringstream ss;
+//       facet_type dnp;
+//       ymd_put(ymd, ss, dnp);
+//       return ss.str();
+//       }
+
+
+    // Put ymd to ostream -- part of ostream refactor
+    static void ymd_put(ymd_type ymd,
+                        ostream_type& os,
+                        const facet_type& f)
+    {
+      std::ostreambuf_iterator<charT> oitr(os);
+      charT fill_char = '0';
+      switch (f.date_order()) {
+        case ymd_order_iso: {
+          os << ymd.year;
+          if (f.has_date_sep_chars()) {
+            f.month_sep_char(oitr);
+          }
+          month_formatter_type::format_month(ymd.month, os, f);
+          if (f.has_date_sep_chars()) {
+            f.day_sep_char(oitr);
+          }
+          os  << std::setw(2) << std::setfill(fill_char)
+              << ymd.day;
+          break;
+        }
+        case ymd_order_us: {
+          month_formatter_type::format_month(ymd.month, os, f);
+          if (f.has_date_sep_chars()) {
+          f.day_sep_char(oitr);
+          }
+          os  << std::setw(2) << std::setfill(fill_char)
+            << ymd.day;
+          if (f.has_date_sep_chars()) {
+            f.month_sep_char(oitr);
+          }
+          os << ymd.year;
+          break;
+        }
+        case ymd_order_dmy: {
+          os  << std::setw(2) << std::setfill(fill_char)
+              << ymd.day;
+          if (f.has_date_sep_chars()) {
+            f.day_sep_char(oitr);
+          }
+          month_formatter_type::format_month(ymd.month, os, f);
+          if (f.has_date_sep_chars()) {
+            f.month_sep_char(oitr);
+          }
+          os << ymd.year;
+          break;
+        }
+      }
+    }
+  };
+
+
+  //! Convert a date to string using format policies
+  template<class date_type,
+           class facet_type,
+           class charT = char>
+  class ostream_date_formatter
+  {
+  public:
+    typedef std::basic_ostream<charT> ostream_type;
+    typedef typename date_type::ymd_type ymd_type;
+
+    //! Put date into an ostream
+    static void date_put(const date_type& d,
+                         ostream_type& os,
+                         const facet_type& f)
+    {
+      special_values sv = d.as_special();
+      if (sv == not_special) {
+        ymd_type ymd = d.year_month_day();
+        ostream_ymd_formatter<ymd_type, facet_type, charT>::ymd_put(ymd, os, f);
+      }
+      else { // output a special value
+        std::ostreambuf_iterator<charT> coi(os);
+        f.put_special_value(coi, sv);
+      }
+    }
+
+
+    //! Put date into an ostream
+    static void date_put(const date_type& d,
+                         ostream_type& os)
+    {
+      //retrieve the local from the ostream
+      std::locale locale = os.getloc();
+      if (std::has_facet<facet_type>(locale)) {
+        const facet_type& f = std::use_facet<facet_type>(locale);
+        date_put(d, os, f);
+      }
+      else {
+        //default to something sensible if no facet installed
+        facet_type default_facet;
+        date_put(d, os, default_facet);
+      }
+    } // date_to_ostream 
+  }; //class date_formatter
+
+
+} } //namespace date_time
+
+#endif
+
+#endif
+

+ 265 - 0
ext/boost/date_time/date_generator_formatter.hpp

@@ -0,0 +1,265 @@
+#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
+#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include "boost/date_time/date_generators.hpp"
+
+namespace boost {
+namespace date_time {
+
+  //! Formats date_generators for output
+  /*! Formatting of date_generators follows specific orders for the 
+   * various types of date_generators.
+   * - partial_date                     => "dd Month"
+   * - nth_day_of_the_week_in_month     => "nth weekday of month"
+   * - first_day_of_the_week_in_month   => "first weekday of month"
+   * - last_day_of_the_week_in_month    => "last weekday of month"
+   * - first_day_of_the_week_after      => "weekday after"
+   * - first_day_of_the_week_before     => "weekday before"
+   * While the order of the elements in these phrases cannot be changed, 
+   * the elements themselves can be. Weekday and Month get their formats
+   * and names from the date_facet. The remaining elements are stored in 
+   * the date_generator_formatter and can be customized upon construction
+   * or via a member function. The default elements are those shown in the 
+   * examples above.
+   */
+  template <class date_type, class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+  class date_generator_formatter {
+    public:
+      typedef partial_date<date_type>          partial_date_type;
+      typedef nth_kday_of_month<date_type>     nth_kday_type;
+      typedef first_kday_of_month<date_type>   first_kday_type;
+      typedef last_kday_of_month<date_type>    last_kday_type;
+      typedef first_kday_after<date_type>      kday_after_type;
+      typedef first_kday_before<date_type>     kday_before_type;
+
+      typedef CharT char_type;
+      typedef std::basic_string<char_type> string_type;
+      typedef std::vector<string_type> collection_type;
+      static const char_type first_string[6];
+      static const char_type second_string[7];
+      static const char_type third_string[6];
+      static const char_type fourth_string[7];
+      static const char_type fifth_string[6];
+      static const char_type last_string[5];
+      static const char_type before_string[8];
+      static const char_type after_string[6];
+      static const char_type of_string[3];
+
+      enum phrase_elements {first=0, second, third, fourth, fifth, last,
+                         before, after, of, number_of_phrase_elements};
+
+      //! Default format elements used
+      date_generator_formatter()
+      {
+        phrase_strings.reserve(number_of_phrase_elements);
+        phrase_strings.push_back(string_type(first_string));
+        phrase_strings.push_back(string_type(second_string));
+        phrase_strings.push_back(string_type(third_string));
+        phrase_strings.push_back(string_type(fourth_string));
+        phrase_strings.push_back(string_type(fifth_string));
+        phrase_strings.push_back(string_type(last_string));
+        phrase_strings.push_back(string_type(before_string));
+        phrase_strings.push_back(string_type(after_string));
+        phrase_strings.push_back(string_type(of_string));
+      }
+
+      //! Constructor that allows for a custom set of phrase elements
+      date_generator_formatter(const string_type& first_str,
+                               const string_type& second_str,
+                               const string_type& third_str,
+                               const string_type& fourth_str,
+                               const string_type& fifth_str,
+                               const string_type& last_str,
+                               const string_type& before_str,
+                               const string_type& after_str,
+                               const string_type& of_str)
+      {
+        phrase_strings.reserve(number_of_phrase_elements);
+        phrase_strings.push_back(first_str);
+        phrase_strings.push_back(second_str);
+        phrase_strings.push_back(third_str);
+        phrase_strings.push_back(fourth_str);
+        phrase_strings.push_back(fifth_str);
+        phrase_strings.push_back(last_str);
+        phrase_strings.push_back(before_str);
+        phrase_strings.push_back(after_str);
+        phrase_strings.push_back(of_str);
+      }
+
+      //! Replace the set of phrase elements with those contained in new_strings
+      /*! The order of the strings in the given collection is important.
+       * They must follow: 
+       *  - first, second, third, fourth, fifth, last, before, after, of. 
+       *
+       * It is not necessary to send in a complete set if only a few 
+       * elements are to be replaced as long as the correct beg_pos is used.
+       *
+       * Ex: To keep the default first through fifth elements, but replace 
+       * the rest with a collection of: 
+       *  - "final", "prior", "following", "in". 
+       * The beg_pos of date_generator_formatter::last would be used.
+       */
+      void elements(const collection_type& new_strings,
+                    phrase_elements beg_pos=first)
+      {
+        if(beg_pos < number_of_phrase_elements) {
+          typename collection_type::iterator itr = phrase_strings.begin();
+          itr += beg_pos;
+          std::copy(new_strings.begin(), new_strings.end(),
+                    itr);
+                    //phrase_strings.begin());
+        }
+      }
+
+      //!Put a partial_date => "dd Month"
+      template<class facet_type>
+      OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios,
+                               CharT a_fill, const partial_date_type& pd,
+                               const facet_type& facet) const
+      {
+        facet.put(next, a_ios, a_fill, pd.day());
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, pd.month());
+        return next;
+      }
+
+      //! Put an nth_day_of_the_week_in_month => "nth weekday of month"
+      template<class facet_type>
+      OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios,
+                           CharT a_fill, const nth_kday_type& nkd,
+                           const facet_type& facet) const
+      {
+        put_string(next, phrase_strings[nkd.nth_week() -1]);
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, nkd.day_of_week());
+        next = a_fill; //TODO change this ???
+        put_string(next, string_type(of_string));
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, nkd.month());
+        return next;
+      }
+
+      //! Put a first_day_of_the_week_in_month => "first weekday of month"
+      template<class facet_type>
+      OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios,
+                             CharT a_fill, const first_kday_type& fkd,
+                             const facet_type& facet) const
+      {
+        put_string(next, phrase_strings[first]);
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, fkd.day_of_week());
+        next = a_fill; //TODO change this ???
+        put_string(next, string_type(of_string));
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, fkd.month());
+        return next;
+      }
+
+      //! Put a last_day_of_the_week_in_month => "last weekday of month"
+      template<class facet_type>
+      OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios,
+                           CharT a_fill, const last_kday_type& lkd,
+                           const facet_type& facet) const
+      {
+        put_string(next, phrase_strings[last]);
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, lkd.day_of_week());
+        next = a_fill; //TODO change this ???
+        put_string(next, string_type(of_string));
+        next = a_fill; //TODO change this ???
+        facet.put(next, a_ios, a_fill, lkd.month());
+        return next;
+      }
+
+      //! Put a first_day_of_the_week_before => "weekday before"
+      template<class facet_type>
+      OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios,
+                              CharT a_fill, const kday_before_type& fkb,
+                              const facet_type& facet) const
+      {
+        facet.put(next, a_ios, a_fill, fkb.day_of_week());
+        next = a_fill; //TODO change this ???
+        put_string(next, phrase_strings[before]);
+        return next;
+      }
+
+      //! Put a first_day_of_the_week_after => "weekday after"
+      template<class facet_type>
+      OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios,
+                             CharT a_fill, const kday_after_type& fka,
+                             const facet_type& facet) const
+      {
+        facet.put(next, a_ios, a_fill, fka.day_of_week());
+        next = a_fill; //TODO change this ???
+        put_string(next, phrase_strings[after]);
+        return next;
+      }
+
+
+    private:
+      collection_type phrase_strings;
+
+      //! helper function to put the various member string into stream
+      OutItrT put_string(OutItrT next, const string_type& str) const
+      {
+        typename string_type::const_iterator itr = str.begin();
+        while(itr != str.end()) {
+          *next = *itr;
+          ++itr;
+          ++next;
+        }
+        return next;
+      }
+  };
+
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::first_string[6] = 
+    {'f','i','r','s','t'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::second_string[7] = 
+    {'s','e','c','o','n','d'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::third_string[6] = 
+    {'t','h','i','r','d'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::fourth_string[7] = 
+    {'f','o','u','r','t','h'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::fifth_string[6] = 
+    {'f','i','f','t','h'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::last_string[5] = 
+    {'l','a','s','t'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::before_string[8] = 
+    {'b','e','f','o','r','e'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::after_string[6] = 
+    {'a','f','t','e','r'};
+  template<class date_type, class CharT, class OutItrT>
+  const typename date_generator_formatter<date_type, CharT, OutItrT>::char_type
+  date_generator_formatter<date_type, CharT, OutItrT>::of_string[3] = 
+    {'o','f'};
+} } // namespaces
+
+#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___

+ 330 - 0
ext/boost/date_time/date_generator_parser.hpp

@@ -0,0 +1,330 @@
+
+#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+
+/* Copyright (c) 2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <string>
+#include <vector>
+#include <iterator> // istreambuf_iterator
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/string_parse_tree.hpp>
+#include <boost/date_time/date_generators.hpp>
+#include <boost/date_time/format_date_parser.hpp>
+
+namespace boost { namespace date_time {
+
+  //! Class for date_generator parsing 
+  /*! The elements of a date_generator "phrase" are parsed from the input stream in a 
+   *  particular order. All elements are required and the order in which they appear 
+   *  cannot change, however, the elements themselves can be changed. The default 
+   *  elements and their order are as follows:
+   *
+   * - partial_date                     => "dd Month"
+   * - nth_day_of_the_week_in_month     => "nth weekday of month"
+   * - first_day_of_the_week_in_month   => "first weekday of month"
+   * - last_day_of_the_week_in_month    => "last weekday of month"
+   * - first_day_of_the_week_after      => "weekday after"
+   * - first_day_of_the_week_before     => "weekday before"
+   *
+   * Weekday and Month names and formats are handled via the date_input_facet. 
+   *
+   */
+  template<class date_type, typename charT>
+  class date_generator_parser
+  {
+   public:
+    typedef std::basic_string<charT>        string_type;
+    typedef std::istreambuf_iterator<charT> stream_itr_type;
+
+    typedef typename date_type::month_type       month_type;
+    typedef typename date_type::day_of_week_type day_of_week_type;
+    typedef typename date_type::day_type         day_type;
+
+    typedef string_parse_tree<charT>                          parse_tree_type;
+    typedef typename parse_tree_type::parse_match_result_type match_results;
+    typedef std::vector<std::basic_string<charT> >            collection_type;
+
+    typedef partial_date<date_type>          partial_date_type;
+    typedef nth_kday_of_month<date_type>     nth_kday_type;
+    typedef first_kday_of_month<date_type>   first_kday_type;
+    typedef last_kday_of_month<date_type>    last_kday_type;
+    typedef first_kday_after<date_type>      kday_after_type;
+    typedef first_kday_before<date_type>     kday_before_type;
+
+    typedef charT char_type;
+    static const char_type first_string[6];
+    static const char_type second_string[7];
+    static const char_type third_string[6];
+    static const char_type fourth_string[7];
+    static const char_type fifth_string[6];
+    static const char_type last_string[5];
+    static const char_type before_string[8];
+    static const char_type after_string[6];
+    static const char_type of_string[3];
+
+    enum phrase_elements {first=0, second, third, fourth, fifth, last,
+                          before, after, of, number_of_phrase_elements};
+
+    //! Creates a date_generator_parser with the default set of "element_strings"
+    date_generator_parser()
+    {
+      element_strings(string_type(first_string),
+                      string_type(second_string),
+                      string_type(third_string),
+                      string_type(fourth_string),
+                      string_type(fifth_string),
+                      string_type(last_string),
+                      string_type(before_string),
+                      string_type(after_string),
+                      string_type(of_string));
+    }
+
+    //! Creates a date_generator_parser using a user defined set of element strings
+    date_generator_parser(const string_type& first_str,
+                          const string_type& second_str,
+                          const string_type& third_str,
+                          const string_type& fourth_str,
+                          const string_type& fifth_str,
+                          const string_type& last_str,
+                          const string_type& before_str,
+                          const string_type& after_str,
+                          const string_type& of_str)
+    {
+      element_strings(first_str, second_str, third_str, fourth_str, fifth_str,
+                      last_str, before_str, after_str, of_str);
+    }
+
+    //! Replace strings that determine nth week for generator
+    void element_strings(const string_type& first_str,
+                         const string_type& second_str,
+                         const string_type& third_str,
+                         const string_type& fourth_str,
+                         const string_type& fifth_str,
+                         const string_type& last_str,
+                         const string_type& before_str,
+                         const string_type& after_str,
+                         const string_type& of_str)
+    {
+      collection_type phrases;
+      phrases.push_back(first_str);
+      phrases.push_back(second_str);
+      phrases.push_back(third_str);
+      phrases.push_back(fourth_str);
+      phrases.push_back(fifth_str);
+      phrases.push_back(last_str);
+      phrases.push_back(before_str);
+      phrases.push_back(after_str);
+      phrases.push_back(of_str);
+      m_element_strings = parse_tree_type(phrases, this->first); // enum first
+    }
+
+    void element_strings(const collection_type& col)
+    {
+      m_element_strings = parse_tree_type(col, this->first); // enum first
+    }
+
+    //! returns partial_date parsed from stream
+    template<class facet_type>
+    partial_date_type
+    get_partial_date_type(stream_itr_type& sitr,
+                          stream_itr_type& stream_end,
+                          std::ios_base& a_ios,
+                          const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+      day_type d(1);
+      month_type m(1);
+      facet.get(sitr, stream_end, a_ios, d);
+      facet.get(sitr, stream_end, a_ios, m);
+
+      return partial_date_type(d,m);
+    }
+
+    //! returns nth_kday_of_week parsed from stream
+    template<class facet_type>
+    nth_kday_type
+    get_nth_kday_type(stream_itr_type& sitr,
+                      stream_itr_type& stream_end,
+                      std::ios_base& a_ios,
+                      const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+ 
+      typename nth_kday_type::week_num wn;
+      day_of_week_type wd(0); // no default constructor
+      month_type m(1);        // no default constructor
+
+      match_results mr = m_element_strings.match(sitr, stream_end);
+      switch(mr.current_match) {
+        case first  : { wn = nth_kday_type::first; break; }
+        case second : { wn = nth_kday_type::second; break; }
+        case third  : { wn = nth_kday_type::third; break; }
+        case fourth : { wn = nth_kday_type::fourth; break; }
+        case fifth  : { wn = nth_kday_type::fifth; break; }
+        default:
+        {
+          boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+          BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(wn = nth_kday_type::first);
+        }
+      }                                         // week num
+      facet.get(sitr, stream_end, a_ios, wd);   // day_of_week
+      extract_element(sitr, stream_end, of);    // "of" element
+      facet.get(sitr, stream_end, a_ios, m);    // month
+
+      return nth_kday_type(wn, wd, m);
+    }
+
+    //! returns first_kday_of_week parsed from stream
+    template<class facet_type>
+    first_kday_type
+    get_first_kday_type(stream_itr_type& sitr,
+                        stream_itr_type& stream_end,
+                        std::ios_base& a_ios,
+                        const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+      day_of_week_type wd(0); // no default constructor
+      month_type m(1);        // no default constructor
+
+      extract_element(sitr, stream_end, first); // "first" element
+      facet.get(sitr, stream_end, a_ios, wd);   // day_of_week
+      extract_element(sitr, stream_end, of);    // "of" element
+      facet.get(sitr, stream_end, a_ios, m);    // month
+
+
+      return first_kday_type(wd, m);
+    }
+
+    //! returns last_kday_of_week parsed from stream
+    template<class facet_type>
+    last_kday_type
+    get_last_kday_type(stream_itr_type& sitr,
+                       stream_itr_type& stream_end,
+                       std::ios_base& a_ios,
+                       const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+      day_of_week_type wd(0); // no default constructor
+      month_type m(1);        // no default constructor
+ 
+      extract_element(sitr, stream_end, last); // "last" element
+      facet.get(sitr, stream_end, a_ios, wd);  // day_of_week
+      extract_element(sitr, stream_end, of);   // "of" element
+      facet.get(sitr, stream_end, a_ios, m);   // month
+
+
+      return last_kday_type(wd, m);
+    }
+
+    //! returns first_kday_of_week parsed from stream
+    template<class facet_type>
+    kday_before_type
+    get_kday_before_type(stream_itr_type& sitr,
+                         stream_itr_type& stream_end,
+                         std::ios_base& a_ios,
+                         const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+      day_of_week_type wd(0); // no default constructor
+
+      facet.get(sitr, stream_end, a_ios, wd);   // day_of_week
+      extract_element(sitr, stream_end, before);// "before" element
+
+      return kday_before_type(wd);
+    }
+
+    //! returns first_kday_of_week parsed from stream
+    template<class facet_type>
+    kday_after_type
+    get_kday_after_type(stream_itr_type& sitr,
+                        stream_itr_type& stream_end,
+                        std::ios_base& a_ios,
+                        const facet_type& facet) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+
+      day_of_week_type wd(0); // no default constructor
+
+      facet.get(sitr, stream_end, a_ios, wd);   // day_of_week
+      extract_element(sitr, stream_end, after); // "after" element
+
+      return kday_after_type(wd);
+    }
+
+   private:
+    parse_tree_type m_element_strings;
+
+    //! Extracts phrase element from input. Throws ios_base::failure on error.
+    void extract_element(stream_itr_type& sitr,
+                         stream_itr_type& stream_end,
+                         typename date_generator_parser::phrase_elements ele) const
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; }
+      match_results mr = m_element_strings.match(sitr, stream_end);
+      if(mr.current_match != ele) {
+        boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'"));
+      }
+    }
+
+  };
+
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::first_string[6] =
+    {'f','i','r','s','t'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::second_string[7] =
+    {'s','e','c','o','n','d'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::third_string[6] =
+    {'t','h','i','r','d'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::fourth_string[7] =
+    {'f','o','u','r','t','h'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::fifth_string[6] =
+    {'f','i','f','t','h'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::last_string[5] =
+    {'l','a','s','t'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::before_string[8] =
+    {'b','e','f','o','r','e'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::after_string[6] =
+    {'a','f','t','e','r'};
+  template<class date_type, class CharT>
+  const typename date_generator_parser<date_type, CharT>::char_type
+  date_generator_parser<date_type, CharT>::of_string[3] =
+    {'o','f'};
+
+} } //namespace
+
+#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__
+

+ 509 - 0
ext/boost/date_time/date_generators.hpp

@@ -0,0 +1,509 @@
+#ifndef DATE_TIME_DATE_GENERATORS_HPP__
+#define DATE_TIME_DATE_GENERATORS_HPP__
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file date_generators.hpp
+  Definition and implementation of date algorithm templates
+*/
+
+#include <stdexcept>
+#include <sstream>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/date.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+  //! Base class for all generators that take a year and produce a date.
+  /*! This class is a base class for polymorphic function objects that take
+    a year and produce a concrete date.
+    @param date_type The type representing a date.  This type must
+    export a calender_type which defines a year_type.
+  */
+  template<class date_type>
+  class year_based_generator
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::year_type        year_type;
+    year_based_generator() {};
+    virtual ~year_based_generator() {};
+    virtual date_type get_date(year_type y) const = 0;
+    //! Returns a string for use in a POSIX time_zone string
+    virtual std::string to_string() const =0;
+  };
+  
+  //! Generates a date by applying the year to the given month and day.
+  /*!
+    Example usage: 
+    @code
+    partial_date pd(1, Jan);
+    partial_date pd2(70);
+    date d = pd.get_date(2002); //2002-Jan-01
+    date d2 = pd2.get_date(2002); //2002-Mar-10
+    @endcode
+    \ingroup date_alg
+  */
+  template<class date_type>
+ class partial_date : public year_based_generator<date_type>
+ {
+ public:
+   typedef typename date_type::calendar_type calendar_type;
+   typedef typename calendar_type::day_type         day_type;
+   typedef typename calendar_type::month_type       month_type;
+   typedef typename calendar_type::year_type        year_type;
+   typedef typename date_type::duration_type        duration_type;
+   typedef typename duration_type::duration_rep     duration_rep;
+   partial_date(day_type d, month_type m) :
+     day_(d),
+     month_(m)
+   {}
+   //! Partial date created from number of days into year. Range 1-366
+   /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument
+    * exceeds range, partial_date will be created with closest in-range value.
+    * 60 will always be Feb29, if get_date() is called with a non-leap year
+    * an exception will be thrown */
+   partial_date(duration_rep days) :
+     day_(1), // default values
+     month_(1)
+   {
+     date_type d1(2000,1,1);
+     if(days > 1) {
+       if(days > 366) // prevents wrapping
+       {
+         days = 366;
+       }
+       days = days - 1;
+       duration_type dd(days);
+       d1 = d1 + dd;
+     }
+     day_ = d1.day();
+     month_ = d1.month();
+   }
+   //! Return a concrete date when provided with a year specific year.
+   /*! Will throw an 'invalid_argument' exception if a partial_date object,
+    * instantiated with Feb-29, has get_date called with a non-leap year.
+    * Example:
+    * @code
+    * partial_date pd(29, Feb);
+    * pd.get_date(2003); // throws invalid_argument exception
+    * pg.get_date(2000); // returns 2000-2-29
+    * @endcode
+         */
+   date_type get_date(year_type y) const
+   {
+     if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) {
+       std::ostringstream ss;
+       ss << "No Feb 29th in given year of " << y << ".";
+       boost::throw_exception(std::invalid_argument(ss.str()));
+     }
+     return date_type(y, month_, day_);
+   }
+   date_type operator()(year_type y) const
+   {
+     return get_date(y);
+     //return date_type(y, month_, day_);
+   }
+   bool operator==(const partial_date& rhs) const
+   {
+     return (month_ == rhs.month_) && (day_ == rhs.day_);
+   }
+   bool operator<(const partial_date& rhs) const
+   {
+     if (month_ < rhs.month_) return true;
+     if (month_ > rhs.month_) return false;
+     //months are equal
+     return (day_ < rhs.day_);
+   }
+   
+   // added for streaming purposes
+   month_type month() const 
+   {
+     return month_;
+   }
+   day_type day() const
+   {
+     return day_;
+   }
+
+   //! Returns string suitable for use in POSIX time zone string
+   /*! Returns string formatted with up to 3 digits: 
+    * Jan-01 == "0" 
+    * Feb-29 == "58"
+    * Dec-31 == "365" */
+   virtual std::string to_string() const
+   {
+     std::ostringstream ss;
+     date_type d(2004, month_, day_);
+     unsigned short c = d.day_of_year();     
+     c--; // numbered 0-365 while day_of_year is 1 based...
+     ss << c;
+     return ss.str();
+   }
+ private:
+   day_type day_;
+   month_type month_;
+ };
+
+
+  //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5.
+  BOOST_DATE_TIME_DECL const char* nth_as_str(int n);
+
+  //! Useful generator functor for finding holidays
+  /*! Based on the idea in Cal. Calc. for finding holidays that are
+   *  the 'first Monday of September'. When instantiated with
+   *  'fifth' kday of month, the result will be the last kday of month
+   *  which can be the fourth or fifth depending on the structure of 
+   *  the month.
+   *
+   *  The algorithm here basically guesses for the first
+   *  day of the month.  Then finds the first day of the correct
+   *  type.  That is, if the first of the month is a Tuesday
+   *  and it needs Wenesday then we simply increment by a day
+   *  and then we can add the length of a week until we get
+   *  to the 'nth kday'.  There are probably more efficient 
+   *  algorithms based on using a mod 7, but this one works 
+   *  reasonably well for basic applications.
+   *  \ingroup date_alg
+   */
+  template<class date_type>
+  class nth_kday_of_month : public year_based_generator<date_type>
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::day_of_week_type  day_of_week_type;
+    typedef typename calendar_type::month_type        month_type;
+    typedef typename calendar_type::year_type         year_type;
+    typedef typename date_type::duration_type        duration_type;
+    enum week_num {first=1, second, third, fourth, fifth};
+    nth_kday_of_month(week_num week_no,
+                      day_of_week_type dow,
+                      month_type m) :
+      month_(m),
+      wn_(week_no),
+      dow_(dow)
+    {}
+    //! Return a concrete date when provided with a year specific year.
+    date_type get_date(year_type y) const
+    {
+      date_type d(y, month_, 1); //first day of month
+      duration_type one_day(1);
+      duration_type one_week(7);
+      while (dow_ != d.day_of_week()) {
+        d = d + one_day;
+      }
+      int week = 1;
+      while (week < wn_) {
+        d = d + one_week;
+        week++;
+      }
+      // remove wrapping to next month behavior
+      if(d.month() != month_) {
+        d = d - one_week;
+      }
+      return d;
+    }
+    // added for streaming
+    month_type month() const
+    {
+      return month_;
+    }
+    week_num nth_week() const
+    {
+      return wn_;
+    }
+    day_of_week_type day_of_week() const
+    {
+      return dow_;
+    }
+    const char* nth_week_as_str() const
+    {
+      return nth_as_str(wn_);
+    }
+    //! Returns string suitable for use in POSIX time zone string
+    /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */
+    virtual std::string to_string() const
+    {
+     std::ostringstream ss;
+     ss << 'M' 
+       << static_cast<int>(month_) << '.'
+       << static_cast<int>(wn_) << '.'
+       << static_cast<int>(dow_);
+     return ss.str();
+    }
+  private:
+    month_type month_;
+    week_num wn_;
+    day_of_week_type dow_;
+  };
+  
+  //! Useful generator functor for finding holidays and daylight savings
+  /*! Similar to nth_kday_of_month, but requires less paramters
+   *  \ingroup date_alg
+   */
+  template<class date_type>
+  class first_kday_of_month : public year_based_generator<date_type>
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::day_of_week_type  day_of_week_type;
+    typedef typename calendar_type::month_type        month_type;
+    typedef typename calendar_type::year_type         year_type;
+    typedef typename date_type::duration_type        duration_type;
+    //!Specify the first 'Sunday' in 'April' spec
+    /*!@param dow The day of week, eg: Sunday, Monday, etc
+     * @param m The month of the year, eg: Jan, Feb, Mar, etc
+     */
+    first_kday_of_month(day_of_week_type dow, month_type m) :
+      month_(m),
+      dow_(dow)
+    {}
+    //! Return a concrete date when provided with a year specific year.
+    date_type get_date(year_type year) const
+    {
+      date_type d(year, month_,1);
+      duration_type one_day(1);
+      while (dow_ != d.day_of_week()) {
+        d = d + one_day;
+      }
+      return d;
+    }
+    // added for streaming
+    month_type month() const
+    {
+      return month_;
+    }
+    day_of_week_type day_of_week() const
+    {
+      return dow_;
+    }
+    //! Returns string suitable for use in POSIX time zone string
+    /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */
+    virtual std::string to_string() const
+    {
+     std::ostringstream ss;
+     ss << 'M' 
+       << static_cast<int>(month_) << '.'
+       << 1 << '.'
+       << static_cast<int>(dow_);
+     return ss.str();
+    }
+  private:
+    month_type month_;
+    day_of_week_type dow_;
+  };
+  
+  
+  
+  //! Calculate something like Last Sunday of January
+  /*! Useful generator functor for finding holidays and daylight savings
+   *  Get the last day of the month and then calculate the difference
+   *  to the last previous day.
+   *  @param date_type A date class that exports day_of_week, month_type, etc.
+   *  \ingroup date_alg
+   */
+  template<class date_type>
+  class last_kday_of_month : public year_based_generator<date_type>
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::day_of_week_type  day_of_week_type;
+    typedef typename calendar_type::month_type        month_type;
+    typedef typename calendar_type::year_type         year_type;
+    typedef typename date_type::duration_type        duration_type;
+    //!Specify the date spec like last 'Sunday' in 'April' spec
+    /*!@param dow The day of week, eg: Sunday, Monday, etc
+     * @param m The month of the year, eg: Jan, Feb, Mar, etc
+     */
+    last_kday_of_month(day_of_week_type dow, month_type m) :
+      month_(m),
+      dow_(dow)
+    {}
+    //! Return a concrete date when provided with a year specific year.
+    date_type get_date(year_type year) const
+    {
+      date_type d(year, month_, calendar_type::end_of_month_day(year,month_));
+      duration_type one_day(1);
+      while (dow_ != d.day_of_week()) {
+        d = d - one_day;
+      }
+      return d;
+    }
+    // added for streaming
+    month_type month() const
+    {
+      return month_;
+    }
+    day_of_week_type day_of_week() const
+    {
+      return dow_;
+    }
+    //! Returns string suitable for use in POSIX time zone string
+    /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */
+    virtual std::string to_string() const
+    {
+      std::ostringstream ss;
+      ss << 'M' 
+         << static_cast<int>(month_) << '.'
+         << 5 << '.'
+         << static_cast<int>(dow_);
+      return ss.str();
+    }
+  private:
+    month_type month_;
+    day_of_week_type dow_;
+   };
+  
+  
+  //! Calculate something like "First Sunday after Jan 1,2002
+  /*! Date generator that takes a date and finds kday after
+   *@code
+     typedef boost::date_time::first_kday_after<date> firstkdayafter;
+     firstkdayafter fkaf(Monday);
+     fkaf.get_date(date(2002,Feb,1));
+   @endcode
+   *  \ingroup date_alg
+   */
+  template<class date_type>
+  class first_kday_after
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::day_of_week_type day_of_week_type;
+    typedef typename date_type::duration_type        duration_type;
+    first_kday_after(day_of_week_type dow) :
+      dow_(dow)
+    {}
+    //! Return next kday given.
+    date_type get_date(date_type start_day) const
+    {
+      duration_type one_day(1);
+      date_type d = start_day + one_day;
+      while (dow_ != d.day_of_week()) {
+        d = d + one_day;
+      }
+      return d;
+    }
+    // added for streaming
+    day_of_week_type day_of_week() const
+    {
+      return dow_;
+    }
+  private:
+    day_of_week_type dow_;
+  };
+  
+  //! Calculate something like "First Sunday before Jan 1,2002
+  /*! Date generator that takes a date and finds kday after
+   *@code
+     typedef boost::date_time::first_kday_before<date> firstkdaybefore;
+     firstkdaybefore fkbf(Monday);
+     fkbf.get_date(date(2002,Feb,1));
+   @endcode
+   *  \ingroup date_alg
+   */
+  template<class date_type>
+  class first_kday_before
+  {
+  public:
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename calendar_type::day_of_week_type day_of_week_type;
+    typedef typename date_type::duration_type        duration_type;
+    first_kday_before(day_of_week_type dow) :
+      dow_(dow)
+    {}
+    //! Return next kday given.
+    date_type get_date(date_type start_day) const
+    {
+      duration_type one_day(1);
+      date_type d = start_day - one_day;
+      while (dow_ != d.day_of_week()) {
+        d = d - one_day;
+      }
+      return d;
+    }
+    // added for streaming
+    day_of_week_type day_of_week() const
+    {
+      return dow_;
+    }
+  private:
+    day_of_week_type dow_;
+  };
+  
+  //! Calculates the number of days until the next weekday
+  /*! Calculates the number of days until the next weekday.
+   * If the date given falls on a Sunday and the given weekday 
+   * is Tuesday the result will be 2 days */
+  template<typename date_type, class weekday_type>
+  inline
+  typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd)
+  {
+    typedef typename date_type::duration_type duration_type;
+    duration_type wks(0);
+    duration_type dd(wd.as_number() - d.day_of_week().as_number());
+    if(dd.is_negative()){
+      wks = duration_type(7);
+    }
+    return dd + wks;
+  }
+
+  //! Calculates the number of days since the previous weekday
+  /*! Calculates the number of days since the previous weekday
+   * If the date given falls on a Sunday and the given weekday 
+   * is Tuesday the result will be 5 days. The answer will be a positive 
+   * number because Tuesday is 5 days before Sunday, not -5 days before. */
+  template<typename date_type, class weekday_type>
+  inline
+  typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd)
+  {
+    typedef typename date_type::duration_type duration_type;
+    duration_type wks(0);
+    duration_type dd(wd.as_number() - d.day_of_week().as_number());
+    if(dd.days() > 0){
+      wks = duration_type(7);
+    }
+    // we want a number of days, not an offset. The value returned must
+    // be zero or larger.
+    return (-dd + wks);
+  }
+
+  //! Generates a date object representing the date of the following weekday from the given date
+  /*! Generates a date object representing the date of the following 
+   * weekday from the given date. If the date given is 2004-May-9 
+   * (a Sunday) and the given weekday is Tuesday then the resulting date 
+   * will be 2004-May-11. */
+  template<class date_type, class weekday_type>
+  inline
+  date_type next_weekday(const date_type& d, const weekday_type& wd)
+  {
+    return d + days_until_weekday(d, wd);
+  }
+
+  //! Generates a date object representing the date of the previous weekday from the given date
+  /*! Generates a date object representing the date of the previous 
+   * weekday from the given date. If the date given is 2004-May-9 
+   * (a Sunday) and the given weekday is Tuesday then the resulting date 
+   * will be 2004-May-4. */
+  template<class date_type, class weekday_type>
+  inline
+  date_type previous_weekday(const date_type& d, const weekday_type& wd)
+  {
+    return d - days_before_weekday(d, wd);
+  }
+
+} } //namespace date_time
+
+
+
+
+#endif
+

+ 101 - 0
ext/boost/date_time/date_iterator.hpp

@@ -0,0 +1,101 @@
+#ifndef DATE_ITERATOR_HPP___
+#define DATE_ITERATOR_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include <iterator>
+
+namespace boost {
+namespace date_time {
+  //! An iterator over dates with varying resolution (day, week, month, year, etc)
+  enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions};
+
+  //! Base date iterator type
+  /*! This class provides the skeleton for the creation of iterators.
+   *  New and interesting interators can be created by plugging in a new
+   *  function that derives the next value from the current state.
+   *  generation of various types of -based information.
+   *
+   *  <b>Template Parameters</b>
+   *
+   *  <b>date_type</b>
+   *
+   *  The date_type is a concrete date_type. The date_type must
+   *  define a duration_type and a calendar_type.
+   */
+  template<class date_type>
+  class date_itr_base {
+  // works, but benefit unclear at the moment
+  //   class date_itr_base : public std::iterator<std::input_iterator_tag, 
+  //                                             date_type, void, void, void>{
+  public:
+    typedef typename date_type::duration_type duration_type;
+    typedef date_type value_type;
+    typedef std::input_iterator_tag iterator_category;
+
+    date_itr_base(date_type d) : current_(d) {}
+    virtual ~date_itr_base() {};
+    date_itr_base& operator++() 
+    {
+      current_ = current_ + get_offset(current_);
+      return *this;
+    }
+    date_itr_base& operator--() 
+    {
+      current_ = current_ + get_neg_offset(current_);
+      return *this;
+    }
+    virtual duration_type get_offset(const date_type& current) const=0;
+    virtual duration_type get_neg_offset(const date_type& current) const=0;
+    date_type operator*() {return current_;};
+    date_type* operator->() {return &current_;};
+    bool operator<  (const date_type& d) {return current_ < d;}
+    bool operator<= (const date_type& d) {return current_ <= d;}
+    bool operator>  (const date_type& d) {return current_ > d;}
+    bool operator>= (const date_type& d) {return current_ >= d;}
+    bool operator== (const date_type& d) {return current_ == d;}
+    bool operator!= (const date_type& d) {return current_ != d;}    
+  private:
+    date_type current_;
+  };
+  
+  //! Overrides the base date iterator providing hook for functors
+  /*
+   *  <b>offset_functor</b>
+   *
+   *  The offset functor must define a get_offset function that takes the
+   *  current point in time and calculates and offset.
+   *
+   */
+  template<class offset_functor, class date_type>
+  class date_itr : public date_itr_base<date_type> {
+  public:
+    typedef typename date_type::duration_type duration_type;
+    date_itr(date_type d, int factor=1) : 
+      date_itr_base<date_type>(d), 
+      of_(factor) 
+    {}
+  private:
+    virtual duration_type get_offset(const date_type& current) const
+    {
+      return of_.get_offset(current);
+    }
+    virtual duration_type get_neg_offset(const date_type& current) const
+    {
+      return of_.get_neg_offset(current);
+    }
+    offset_functor of_;
+  };
+  
+
+  
+} } //namespace date_time
+
+
+#endif

+ 320 - 0
ext/boost/date_time/date_names_put.hpp

@@ -0,0 +1,320 @@
+#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___
+#define DATE_TIME_DATE_NAMES_PUT_HPP___
+
+/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+#include "boost/lexical_cast.hpp"
+#include <locale>
+
+
+namespace boost {
+namespace date_time {
+
+    //! Output facet base class for gregorian dates.
+    /*! This class is a base class for date facets used to localize the
+     *  names of months and the names of days in the week.
+     * 
+     * Requirements of Config
+     *  - define an enumeration month_enum that enumerates the months. 
+     *    The enumeration should be '1' based eg: Jan==1
+     *  - define as_short_string and as_long_string
+     *
+     * (see langer & kreft p334).
+     * 
+     */
+    template<class Config,
+             class charT = char, 
+             class OutputIterator = std::ostreambuf_iterator<charT> >
+    class date_names_put : public std::locale::facet
+    {
+    public:
+      date_names_put() {};
+      typedef OutputIterator iter_type;
+      typedef typename Config::month_type month_type;
+      typedef typename Config::month_enum month_enum;
+      typedef typename Config::weekday_enum weekday_enum;
+      typedef typename Config::special_value_enum special_value_enum;
+      //typedef typename Config::format_type format_type;
+      typedef std::basic_string<charT> string_type;
+      typedef charT char_type;
+      static const char_type default_special_value_names[3][17];
+      static const char_type separator[2];
+
+      static std::locale::id id;
+
+#if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
+      std::locale::id& __get_id (void) const { return id; }
+#endif
+
+      void put_special_value(iter_type& oitr, special_value_enum sv) const
+      {
+        do_put_special_value(oitr, sv);
+      }
+      void put_month_short(iter_type& oitr, month_enum moy) const
+      {
+        do_put_month_short(oitr, moy);
+      }
+      void put_month_long(iter_type& oitr, month_enum moy) const
+      {
+        do_put_month_long(oitr, moy);
+      }
+      void put_weekday_short(iter_type& oitr, weekday_enum wd) const
+      {
+        do_put_weekday_short(oitr, wd);
+      }
+      void put_weekday_long(iter_type& oitr, weekday_enum wd) const
+      {
+        do_put_weekday_long(oitr, wd);
+      }
+      bool has_date_sep_chars() const
+      {
+        return do_has_date_sep_chars();
+      }
+      void year_sep_char(iter_type& oitr) const
+      {
+        do_year_sep_char(oitr);
+      }
+      //! char between year-month
+      void month_sep_char(iter_type& oitr) const
+      {
+        do_month_sep_char(oitr);
+      }
+      //! Char to separate month-day
+      void day_sep_char(iter_type& oitr) const
+      {
+        do_day_sep_char(oitr);
+      }
+      //! Determines the order to put the date elements
+      ymd_order_spec date_order() const
+      {
+        return do_date_order();
+      }
+      //! Determines if month is displayed as integer, short or long string
+      month_format_spec month_format() const
+      {
+        return do_month_format();
+      }
+
+    protected:
+      //! Default facet implementation uses month_type defaults
+      virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
+      {
+        month_type gm(moy);
+        charT c = '\0';
+        put_string(oitr, gm.as_short_string(c));
+      }
+      //! Default facet implementation uses month_type defaults
+      virtual void do_put_month_long(iter_type& oitr, 
+                                     month_enum moy) const
+      {
+        month_type gm(moy);
+        charT c = '\0';
+        put_string(oitr, gm.as_long_string(c));
+      }
+      //! Default facet implementation for special value types
+      virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
+      {
+        if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin
+          string_type s(default_special_value_names[sv]);
+          put_string(oitr, s);
+        }
+      }
+      virtual void do_put_weekday_short(iter_type&, weekday_enum) const
+      {
+      }
+      virtual void do_put_weekday_long(iter_type&, weekday_enum) const
+      {
+      }
+      virtual bool do_has_date_sep_chars() const
+      {
+        return true;
+      }
+      virtual void do_year_sep_char(iter_type& oitr) const
+      {
+        string_type s(separator);
+        put_string(oitr, s);
+      }
+      //! char between year-month
+      virtual void do_month_sep_char(iter_type& oitr) const
+      {
+        string_type s(separator);
+        put_string(oitr, s);
+      }
+      //! Char to separate month-day
+      virtual void do_day_sep_char(iter_type& oitr) const
+      {
+        string_type s(separator); //put in '-'
+        put_string(oitr, s);
+      }
+      //! Default for date order 
+      virtual ymd_order_spec do_date_order() const
+      {
+        return ymd_order_iso;
+      }
+      //! Default month format
+      virtual month_format_spec do_month_format() const
+      {
+        return month_as_short_string;
+      }
+      void put_string(iter_type& oi, const charT* const s) const
+      {
+        string_type s1(boost::lexical_cast<string_type>(s));
+        typename string_type::iterator si,end;
+        for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
+          *oi = *si;
+        }
+      }
+      void put_string(iter_type& oi, const string_type& s1) const
+      {
+        typename string_type::const_iterator si,end;
+        for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) {
+          *oi = *si;
+        }
+      }
+    };
+    
+    template<class Config, class charT, class OutputIterator>
+    const typename date_names_put<Config, charT, OutputIterator>::char_type 
+    date_names_put<Config, charT, OutputIterator>::default_special_value_names[3][17] = { 
+      {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
+      {'-','i','n','f','i','n','i','t','y'},
+      {'+','i','n','f','i','n','i','t','y'} };
+
+    template<class Config, class charT, class OutputIterator>
+    const typename date_names_put<Config, charT, OutputIterator>::char_type 
+    date_names_put<Config, charT, OutputIterator>::separator[2] = 
+      {'-', '\0'} ;
+    
+
+    //! Generate storage location for a std::locale::id 
+    template<class Config, class charT, class OutputIterator>
+    std::locale::id date_names_put<Config, charT, OutputIterator>::id;
+
+    //! A date name output facet that takes an array of char* to define strings
+    template<class Config,
+             class charT = char, 
+             class OutputIterator = std::ostreambuf_iterator<charT> >
+    class all_date_names_put : public date_names_put<Config, charT, OutputIterator>
+    {
+    public:
+      all_date_names_put(const charT* const month_short_names[],
+                         const charT* const month_long_names[],
+                         const charT* const special_value_names[],
+                         const charT* const weekday_short_names[],
+                         const charT* const weekday_long_names[],
+                         charT separator_char = '-',
+                         ymd_order_spec order_spec = ymd_order_iso,
+                         month_format_spec month_format = month_as_short_string) :
+        month_short_names_(month_short_names),
+        month_long_names_(month_long_names),
+        special_value_names_(special_value_names),
+        weekday_short_names_(weekday_short_names),
+        weekday_long_names_(weekday_long_names),
+        order_spec_(order_spec),
+        month_format_spec_(month_format)
+      {
+        separator_char_[0] = separator_char;
+        separator_char_[1] = '\0';
+
+      };
+      typedef OutputIterator iter_type;
+      typedef typename Config::month_enum month_enum;
+      typedef typename Config::weekday_enum weekday_enum;
+      typedef typename Config::special_value_enum special_value_enum;
+
+      const charT* const* get_short_month_names() const 
+      {
+        return month_short_names_;
+      }
+      const charT* const* get_long_month_names() const 
+      {
+        return month_long_names_;
+      }
+      const charT* const* get_special_value_names() const 
+      {
+        return special_value_names_;
+      }
+      const charT* const* get_short_weekday_names()const  
+      {
+        return weekday_short_names_;
+      }
+      const charT* const* get_long_weekday_names()const 
+      {
+        return weekday_long_names_;
+      }
+
+    protected:
+      //! Generic facet that takes array of chars
+      virtual void do_put_month_short(iter_type& oitr, month_enum moy) const
+      {
+        this->put_string(oitr, month_short_names_[moy-1]);
+      }
+      //! Long month names 
+      virtual void do_put_month_long(iter_type& oitr, month_enum moy) const
+      {
+        this->put_string(oitr, month_long_names_[moy-1]);
+      }
+      //! Special values names
+      virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const
+      {
+        this->put_string(oitr, special_value_names_[sv]);
+      }
+      virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const
+      {
+        this->put_string(oitr, weekday_short_names_[wd]);
+      }
+      virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const
+      {
+        this->put_string(oitr, weekday_long_names_[wd]);
+      }
+      //! char between year-month
+      virtual void do_month_sep_char(iter_type& oitr) const
+      {
+        this->put_string(oitr, separator_char_);
+      }
+      //! Char to separate month-day
+      virtual void do_day_sep_char(iter_type& oitr) const
+      {
+        this->put_string(oitr, separator_char_);
+      }
+      //! Set the date ordering
+      virtual ymd_order_spec do_date_order() const
+      {
+        return order_spec_;
+      }
+      //! Set the date ordering
+      virtual month_format_spec do_month_format() const
+      {
+        return month_format_spec_;
+      }
+
+    private:
+      const charT* const* month_short_names_;
+      const charT* const* month_long_names_;
+      const charT* const* special_value_names_;
+      const charT* const* weekday_short_names_;
+      const charT* const* weekday_long_names_;
+      charT separator_char_[2];
+      ymd_order_spec order_spec_;
+      month_format_spec month_format_spec_;      
+    };
+
+} } //namespace boost::date_time
+
+#endif //BOOST_NO_STD_LOCALE
+
+#endif

+ 316 - 0
ext/boost/date_time/date_parsing.hpp

@@ -0,0 +1,316 @@
+#ifndef _DATE_TIME_DATE_PARSING_HPP___
+#define _DATE_TIME_DATE_PARSING_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <string>
+#include <iterator>
+#include <algorithm>
+#include <boost/tokenizer.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/parse_format_base.hpp>
+
+#if defined(BOOST_DATE_TIME_NO_LOCALE)
+#include <cctype> // ::tolower(int)
+#else
+#include <locale> // std::tolower(char, locale)
+#endif
+
+namespace boost {
+namespace date_time {
+
+  //! A function to replace the std::transform( , , ,tolower) construct
+  /*! This function simply takes a string, and changes all the characters
+   * in that string to lowercase (according to the default system locale).
+   * In the event that a compiler does not support locales, the old
+   * C style tolower() is used.
+   */
+  inline
+  std::string
+  convert_to_lower(std::string inp)
+  {
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+    const std::locale loc(std::locale::classic());
+#endif
+    std::string::size_type i = 0, n = inp.length();
+    for (; i < n; ++i) {
+      inp[i] =
+#if defined(BOOST_DATE_TIME_NO_LOCALE)
+        static_cast<char>(std::tolower(inp[i]));
+#else
+        // tolower and others were brought in to std for borland >= v564
+        // in compiler_config.hpp
+        std::tolower(inp[i], loc);
+#endif
+    }
+    return inp;
+  }
+
+    //! Helper function for parse_date.
+    /* Used by-value parameter because we change the string and may
+     * want to preserve the original argument */
+    template<class month_type>
+    inline unsigned short
+    month_str_to_ushort(std::string const& s) {
+      if((s.at(0) >= '0') && (s.at(0) <= '9')) {
+        return boost::lexical_cast<unsigned short>(s);
+      }
+      else {
+        std::string str = convert_to_lower(s);
+        typename month_type::month_map_ptr_type ptr = month_type::get_month_map_ptr();
+        typename month_type::month_map_type::iterator iter = ptr->find(str);
+        if(iter != ptr->end()) { // required for STLport
+          return iter->second;
+        }
+      }
+      return 13; // intentionally out of range - name not found
+    }
+ 
+    //! Find index of a string in either of 2 arrays
+    /*! find_match searches both arrays for a match to 's'. Both arrays
+     * must contain 'size' elements. The index of the match is returned.
+     * If no match is found, 'size' is returned.
+     * Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2.
+     * 'size' can be sent in with: (greg_month::max)() (which 12),
+     * (greg_weekday::max)() + 1 (which is 7) or date_time::NumSpecialValues */
+    template<class charT>
+    short find_match(const charT* const* short_names,
+                     const charT* const* long_names,
+                     short size,
+                     const std::basic_string<charT>& s) {
+      for(short i = 0; i < size; ++i){
+        if(short_names[i] == s || long_names[i] == s){
+          return i;
+        }
+      }
+      return size; // not-found, return a value out of range
+    }
+
+    //! Generic function to parse a delimited date (eg: 2002-02-10)
+    /*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or
+     * "2003-Feburary-10"
+     * The order in which the Month, Day, & Year appear in the argument
+     * string can be accomodated by passing in the appropriate ymd_order_spec
+     */
+    template<class date_type>
+    date_type
+    parse_date(const std::string& s, int order_spec = ymd_order_iso) {
+      std::string spec_str;
+      if(order_spec == ymd_order_iso) {
+        spec_str = "ymd";
+      }
+      else if(order_spec == ymd_order_dmy) {
+        spec_str = "dmy";
+      }
+      else { // (order_spec == ymd_order_us)
+        spec_str = "mdy";
+      }
+
+      typedef typename date_type::year_type year_type;
+      typedef typename date_type::month_type month_type;
+      unsigned pos = 0;
+      unsigned short year(0), month(0), day(0);
+      typedef typename std::basic_string<char>::traits_type traits_type;
+      typedef boost::char_separator<char, traits_type> char_separator_type;
+      typedef boost::tokenizer<char_separator_type,
+                               std::basic_string<char>::const_iterator,
+                               std::basic_string<char> > tokenizer;
+      typedef boost::tokenizer<char_separator_type,
+                               std::basic_string<char>::const_iterator,
+                               std::basic_string<char> >::iterator tokenizer_iterator;
+      // may need more delimiters, these work for the regression tests
+      const char sep_char[] = {',','-','.',' ','/','\0'};
+      char_separator_type sep(sep_char);
+      tokenizer tok(s,sep);
+      for(tokenizer_iterator beg=tok.begin();
+          beg!=tok.end() && pos < spec_str.size();
+          ++beg, ++pos) {
+        switch(spec_str.at(pos)) {
+          case 'y':
+          {
+            year = boost::lexical_cast<unsigned short>(*beg);
+            break;
+          }
+          case 'm':
+          {
+            month = month_str_to_ushort<month_type>(*beg);
+            break;
+          }
+          case 'd':
+          {
+            day = boost::lexical_cast<unsigned short>(*beg);
+            break;
+          }
+        } //switch
+      }
+      return date_type(year, month, day);
+    }
+
+    //! Generic function to parse undelimited date (eg: 20020201)
+    template<class date_type>
+    date_type
+    parse_undelimited_date(const std::string& s) {
+      int offsets[] = {4,2,2};
+      int pos = 0;
+      typedef typename date_type::year_type year_type;
+      //typename date_type::ymd_type ymd((year_type::min)(),1,1);
+      unsigned short y = 0, m = 0, d = 0;
+
+      /* The two bool arguments state that parsing will not wrap
+       * (only the first 8 characters will be parsed) and partial
+       * strings will not be parsed.
+       * Ex:
+       * "2005121" will parse 2005 & 12, but not the "1" */
+      boost::offset_separator osf(offsets, offsets+3, false, false);
+
+      typedef typename boost::tokenizer<boost::offset_separator,
+                                        std::basic_string<char>::const_iterator,
+                                        std::basic_string<char> > tokenizer_type;
+      tokenizer_type tok(s, osf);
+      for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) {
+        unsigned short i = boost::lexical_cast<unsigned short>(*ti);
+        switch(pos) {
+        case 0: y = i; break;
+        case 1: m = i; break;
+        case 2: d = i; break;
+        }
+        pos++;
+      }
+      return date_type(y,m,d);
+    }
+
+    //! Helper function for 'date gregorian::from_stream()'
+    /*! Creates a string from the iterators that reference the
+     * begining & end of a char[] or string. All elements are
+     * used in output string */
+    template<class date_type, class iterator_type>
+    inline
+    date_type
+    from_stream_type(iterator_type& beg,
+                     iterator_type const& end,
+                     char)
+    {
+      std::ostringstream ss;
+      while(beg != end) {
+        ss << *beg++;
+      }
+      return parse_date<date_type>(ss.str());
+    }
+
+    //! Helper function for 'date gregorian::from_stream()'
+    /*! Returns the first string found in the stream referenced by the
+     * begining & end iterators */
+    template<class date_type, class iterator_type>
+    inline
+    date_type
+    from_stream_type(iterator_type& beg,
+                     iterator_type const& /* end */,
+                     std::string const&)
+    {
+      return parse_date<date_type>(*beg);
+    }
+
+    /* I believe the wchar stuff would be best elsewhere, perhaps in
+     * parse_date<>()? In the mean time this gets us started... */
+    //! Helper function for 'date gregorian::from_stream()'
+    /*! Creates a string from the iterators that reference the
+     * begining & end of a wstring. All elements are
+     * used in output string */
+    template<class date_type, class iterator_type>
+    inline
+    date_type from_stream_type(iterator_type& beg,
+                               iterator_type const& end,
+                               wchar_t)
+    {
+      std::ostringstream ss;
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+      std::locale loc;
+      std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
+      while(beg != end) {
+        ss << fac.narrow(*beg++, 'X'); // 'X' will cause exception to be thrown
+      }
+#else
+      while(beg != end) {
+        char c = 'X'; // 'X' will cause exception to be thrown
+        const wchar_t wc = *beg++;
+        if (wc >= 0 && wc <= 127)
+          c = static_cast< char >(wc);
+        ss << c;
+      }
+#endif
+      return parse_date<date_type>(ss.str());
+    }
+#ifndef BOOST_NO_STD_WSTRING
+    //! Helper function for 'date gregorian::from_stream()'
+    /*! Creates a string from the first wstring found in the stream
+     * referenced by the begining & end iterators */
+    template<class date_type, class iterator_type>
+    inline
+    date_type
+    from_stream_type(iterator_type& beg,
+                     iterator_type const& /* end */,
+                     std::wstring const&) {
+      std::wstring ws = *beg;
+      std::ostringstream ss;
+      std::wstring::iterator wsb = ws.begin(), wse = ws.end();
+#if !defined(BOOST_DATE_TIME_NO_LOCALE)
+      std::locale loc;
+      std::ctype<wchar_t> const& fac = std::use_facet<std::ctype<wchar_t> >(loc);
+      while(wsb != wse) {
+        ss << fac.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown
+      }
+#else
+      while(wsb != wse) {
+        char c = 'X'; // 'X' will cause exception to be thrown
+        const wchar_t wc = *wsb++;
+        if (wc >= 0 && wc <= 127)
+          c = static_cast< char >(wc);
+        ss << c;
+      }
+#endif
+      return parse_date<date_type>(ss.str());
+    }
+#endif // BOOST_NO_STD_WSTRING
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+    // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
+#else
+    //! function called by wrapper functions: date_period_from_(w)string()
+    template<class date_type, class charT>
+    period<date_type, typename date_type::duration_type>
+    from_simple_string_type(const std::basic_string<charT>& s){
+      typedef typename std::basic_string<charT>::traits_type traits_type;
+      typedef typename boost::char_separator<charT, traits_type> char_separator;
+      typedef typename boost::tokenizer<char_separator,
+                                        typename std::basic_string<charT>::const_iterator,
+                                        std::basic_string<charT> > tokenizer;
+      const charT sep_list[4] = {'[','/',']','\0'};
+      char_separator sep(sep_list);
+      tokenizer tokens(s, sep);
+      typename tokenizer::iterator tok_it = tokens.begin();
+      std::basic_string<charT> date_string = *tok_it;
+      // get 2 string iterators and generate a date from them
+      typename std::basic_string<charT>::iterator date_string_start = date_string.begin(),
+                                                  date_string_end = date_string.end();
+      typedef typename std::iterator_traits<typename std::basic_string<charT>::iterator>::value_type value_type;
+      date_type d1 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
+      date_string = *(++tok_it); // next token
+      date_string_start = date_string.begin(), date_string_end = date_string.end();
+      date_type d2 = from_stream_type<date_type>(date_string_start, date_string_end, value_type());
+      return period<date_type, typename date_type::duration_type>(d1, d2);
+    }
+#endif
+
+} } //namespace date_time
+
+
+
+
+#endif
+

+ 391 - 0
ext/boost/date_time/dst_rules.hpp

@@ -0,0 +1,391 @@
+#ifndef DATE_TIME_DST_RULES_HPP__
+#define DATE_TIME_DST_RULES_HPP__
+
+/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file dst_rules.hpp
+  Contains template class to provide static dst rule calculations
+*/
+
+#include "boost/date_time/date_generators.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include <stdexcept>
+
+namespace boost {
+  namespace date_time {
+
+    enum time_is_dst_result {is_not_in_dst, is_in_dst, 
+                             ambiguous, invalid_time_label};
+
+
+    //! Dynamic class used to caluclate dst transition information
+    template<class date_type_, 
+             class time_duration_type_>
+    class dst_calculator
+    {
+    public:
+      typedef time_duration_type_ time_duration_type;
+      typedef date_type_ date_type;
+
+      //! Check the local time offset when on dst start day
+      /*! On this dst transition, the time label between
+       *  the transition boundary and the boudary + the offset
+       *  are invalid times.  If before the boundary then still 
+       *  not in dst.  
+       *@param time_of_day Time offset in the day for the local time
+       *@param dst_start_offset_minutes Local day offset for start of dst
+       *@param dst_length_minutes Number of minutes to adjust clock forward
+       *@retval status of time label w.r.t. dst
+       */
+      static time_is_dst_result 
+      process_local_dst_start_day(const time_duration_type& time_of_day,
+                                  unsigned int dst_start_offset_minutes,
+                                  long dst_length_minutes)
+      {
+        //std::cout << "here" << std::endl;
+        if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) {
+          return is_not_in_dst;
+        }
+        long offset = dst_start_offset_minutes + dst_length_minutes;
+        if (time_of_day >= time_duration_type(0,offset,0)) {
+          return is_in_dst;
+        }
+        return invalid_time_label; 
+      }
+
+      //! Check the local time offset when on the last day of dst
+      /*! This is the calculation for the DST end day.  On that day times
+       *  prior to the conversion time - dst_length (1 am in US) are still 
+       *  in dst.  Times between the above and the switch time are 
+       *  ambiguous.  Times after the start_offset are not in dst.
+       *@param time_of_day Time offset in the day for the local time
+       *@param dst_end_offset_minutes Local time of day for end of dst
+       *@retval status of time label w.r.t. dst
+       */
+      static time_is_dst_result 
+      process_local_dst_end_day(const time_duration_type& time_of_day,
+                                unsigned int dst_end_offset_minutes,
+                                long dst_length_minutes)
+      {
+        //in US this will be 60 so offset in day is 1,0,0
+        int offset = dst_end_offset_minutes-dst_length_minutes;
+        if (time_of_day < time_duration_type(0,offset,0)) {
+          return is_in_dst;
+        }
+        if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) {
+          return is_not_in_dst;
+        }
+        return ambiguous;
+      }
+
+      //! Calculates if the given local time is dst or not
+      /*! Determines if the time is really in DST or not.  Also checks for 
+       *  invalid and ambiguous.
+       *  @param current_day The day to check for dst
+       *  @param time_of_day Time offset within the day to check 
+       *  @param dst_start_day  Starting day of dst for the given locality
+       *  @param dst_start_offset Time offset within day for dst boundary
+       *  @param dst_end_day    Ending day of dst for the given locality
+       *  @param dst_end_offset Time offset within day given in dst for dst boundary
+       *  @param dst_length lenght of dst adjusment
+       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
+       */
+      static time_is_dst_result 
+      local_is_dst(const date_type& current_day,
+                   const time_duration_type& time_of_day,
+                   const date_type& dst_start_day,
+                   const time_duration_type& dst_start_offset,
+                   const date_type& dst_end_day,
+                   const time_duration_type& dst_end_offset,
+                   const time_duration_type& dst_length_minutes)
+      {
+        unsigned int start_minutes = 
+          dst_start_offset.hours() * 60 + dst_start_offset.minutes();
+        unsigned int end_minutes = 
+          dst_end_offset.hours() * 60 + dst_end_offset.minutes();
+        long length_minutes =  
+          dst_length_minutes.hours() * 60 + dst_length_minutes.minutes();
+
+        return local_is_dst(current_day, time_of_day,
+                            dst_start_day, start_minutes,
+                            dst_end_day, end_minutes,
+                            length_minutes);
+      }
+
+      //! Calculates if the given local time is dst or not
+      /*! Determines if the time is really in DST or not.  Also checks for 
+       *  invalid and ambiguous.
+       *  @param current_day The day to check for dst
+       *  @param time_of_day Time offset within the day to check 
+       *  @param dst_start_day  Starting day of dst for the given locality
+       *  @param dst_start_offset_minutes Offset within day for dst 
+       *         boundary (eg 120 for US which is 02:00:00)
+       *  @param dst_end_day    Ending day of dst for the given locality
+       *  @param dst_end_offset_minutes Offset within day given in dst for dst 
+       *         boundary (eg 120 for US which is 02:00:00)
+       *  @param dst_length_minutes Length of dst adjusment (eg: 60 for US)
+       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
+       */
+      static time_is_dst_result 
+      local_is_dst(const date_type& current_day,
+                   const time_duration_type& time_of_day,
+                   const date_type& dst_start_day,
+                   unsigned int dst_start_offset_minutes,
+                   const date_type& dst_end_day,
+                   unsigned int dst_end_offset_minutes,
+                   long dst_length_minutes)
+      {
+        //in northern hemisphere dst is in the middle of the year
+        if (dst_start_day < dst_end_day) {
+          if ((current_day > dst_start_day) && (current_day < dst_end_day)) {
+            return is_in_dst;
+          }
+          if ((current_day < dst_start_day) || (current_day > dst_end_day)) {
+            return is_not_in_dst;
+          }
+        }
+        else {//southern hemisphere dst is at begining /end of year
+          if ((current_day < dst_start_day) && (current_day > dst_end_day)) {
+            return is_not_in_dst;
+          }
+          if ((current_day > dst_start_day) || (current_day < dst_end_day)) {
+            return is_in_dst;
+          }
+        }
+
+        if (current_day == dst_start_day) {
+          return process_local_dst_start_day(time_of_day,
+                                             dst_start_offset_minutes,
+                                             dst_length_minutes);
+        }
+      
+        if (current_day == dst_end_day) {
+          return process_local_dst_end_day(time_of_day,
+                                           dst_end_offset_minutes,
+                                           dst_length_minutes);
+        }
+        //you should never reach this statement
+        return invalid_time_label;
+      }
+
+    };
+
+
+    //! Compile-time configurable daylight savings time calculation engine
+    /* This template provides the ability to configure a daylight savings
+     * calculation at compile time covering all the cases.  Unfortunately
+     * because of the number of dimensions related to daylight savings
+     * calculation the number of parameters is high.  In addition, the
+     * start and end transition rules are complex types that specify 
+     * an algorithm for calculation of the starting day and ending
+     * day of daylight savings time including the month and day 
+     * specifications (eg: last sunday in October).
+     *
+     * @param date_type A type that represents dates, typically gregorian::date
+     * @param time_duration_type Used for the offset in the day calculations
+     * @param dst_traits A set of traits that define the rules of dst 
+     *        calculation.  The dst_trait must include the following:
+     * start_rule_functor - Rule to calculate the starting date of a
+     *                      dst transition (eg: last_kday_of_month).
+     * start_day - static function that returns month of dst start for 
+     *             start_rule_functor
+     * start_month -static function that returns day or day of week for 
+     *              dst start of dst
+     * end_rule_functor - Rule to calculate the end of dst day.
+     * end_day - static fucntion that returns end day for end_rule_functor
+     * end_month - static function that returns end month for end_rule_functor
+     * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U.
+     * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U. 
+     * dst_length_minutes - number of minutes that dst shifts clock
+     */
+    template<class date_type, 
+             class time_duration_type,
+             class dst_traits>
+    class dst_calc_engine
+    {
+    public:
+      typedef typename date_type::year_type year_type;
+      typedef typename date_type::calendar_type calendar_type;
+      typedef dst_calculator<date_type, time_duration_type> dstcalc;
+
+      //! Calculates if the given local time is dst or not
+      /*! Determines if the time is really in DST or not.  Also checks for 
+       *  invalid and ambiguous.
+       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
+       */
+      static time_is_dst_result local_is_dst(const date_type& d,
+                                             const time_duration_type& td) 
+      {
+
+        year_type y = d.year();
+        date_type dst_start = local_dst_start_day(y);
+        date_type dst_end   = local_dst_end_day(y);
+        return dstcalc::local_is_dst(d,td,
+                                     dst_start,
+                                     dst_traits::dst_start_offset_minutes(),
+                                     dst_end, 
+                                     dst_traits::dst_end_offset_minutes(), 
+                                     dst_traits::dst_shift_length_minutes());
+      
+      }
+
+      static bool is_dst_boundary_day(date_type d)
+      {
+        year_type y = d.year();
+        return ((d == local_dst_start_day(y)) ||
+                (d == local_dst_end_day(y)));
+      }
+
+      //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00)
+      static time_duration_type dst_offset() 
+      {
+        return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0);
+      }
+
+      static date_type local_dst_start_day(year_type year)
+      {
+        return dst_traits::local_dst_start_day(year);      
+      }
+
+      static date_type local_dst_end_day(year_type year)
+      {
+        return dst_traits::local_dst_end_day(year);
+      }
+
+
+    };
+
+    //! Depricated: Class to calculate dst boundaries for US time zones
+    /* Use dst_calc_engine instead.
+     * In 2007 US/Canada DST rules changed
+     * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time).
+     */
+    template<class date_type_, 
+             class time_duration_type_,
+             unsigned int dst_start_offset_minutes=120, //from start of day 
+             short dst_length_minutes=60>  //1 hour == 60 min in US
+    class us_dst_rules 
+    {
+    public:
+      typedef time_duration_type_ time_duration_type;
+      typedef date_type_ date_type;
+      typedef typename date_type::year_type year_type;
+      typedef typename date_type::calendar_type calendar_type;
+      typedef date_time::last_kday_of_month<date_type> lkday;
+      typedef date_time::first_kday_of_month<date_type> fkday;
+      typedef date_time::nth_kday_of_month<date_type> nkday;
+      typedef dst_calculator<date_type, time_duration_type> dstcalc;
+
+      //! Calculates if the given local time is dst or not
+      /*! Determines if the time is really in DST or not.  Also checks for 
+       *  invalid and ambiguous.
+       *  @retval The time is either ambiguous, invalid, in dst, or not in dst
+       */
+      static time_is_dst_result local_is_dst(const date_type& d,
+                                             const time_duration_type& td) 
+      {
+
+        year_type y = d.year();
+        date_type dst_start = local_dst_start_day(y);
+        date_type dst_end   = local_dst_end_day(y);
+        return dstcalc::local_is_dst(d,td,
+                                     dst_start,dst_start_offset_minutes,
+                                     dst_end, dst_start_offset_minutes, 
+                                     dst_length_minutes);
+      
+      }
+
+
+      static bool is_dst_boundary_day(date_type d)
+      {
+        year_type y = d.year();
+        return ((d == local_dst_start_day(y)) ||
+                (d == local_dst_end_day(y)));
+      }
+
+      static date_type local_dst_start_day(year_type year)
+      {
+        if (year >= year_type(2007)) {
+          //second sunday in march
+          nkday ssim(nkday::second, Sunday, gregorian::Mar);
+          return ssim.get_date(year);      
+        } else {
+          //first sunday in april
+          fkday fsia(Sunday, gregorian::Apr);
+          return fsia.get_date(year);      
+        }
+      }
+
+      static date_type local_dst_end_day(year_type year)
+      {
+        if (year >= year_type(2007)) {
+          //first sunday in november
+          fkday fsin(Sunday, gregorian::Nov);
+          return fsin.get_date(year);      
+        } else {
+          //last sunday in october
+          lkday lsio(Sunday, gregorian::Oct);
+          return lsio.get_date(year);
+        }
+      }
+
+      static time_duration_type dst_offset()
+      {
+        return time_duration_type(0,dst_length_minutes,0);
+      }
+
+     private:
+
+
+    };
+
+    //! Used for local time adjustments in places that don't use dst
+    template<class date_type_, class time_duration_type_>
+    class null_dst_rules
+    {
+    public:
+      typedef time_duration_type_ time_duration_type;
+      typedef date_type_ date_type;
+
+
+      //! Calculates if the given local time is dst or not
+      /*! @retval Always is_not_in_dst since this is for zones without dst
+       */
+      static time_is_dst_result local_is_dst(const date_type&, 
+                                             const time_duration_type&) 
+      {
+        return is_not_in_dst;
+      }
+    
+      //! Calculates if the given utc time is in dst
+      static time_is_dst_result utc_is_dst(const date_type&, 
+                                           const time_duration_type&) 
+      {
+        return is_not_in_dst;
+      }
+
+      static bool is_dst_boundary_day(date_type d)
+      {
+        return false;
+      }
+
+      static time_duration_type dst_offset() 
+      {
+        return time_duration_type(0,0,0);
+      }
+
+    };
+
+
+  } } //namespace date_time
+
+
+
+#endif

+ 75 - 0
ext/boost/date_time/dst_transition_generators.hpp

@@ -0,0 +1,75 @@
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ */
+#ifndef DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
+#define DATE_TIME_DATE_DST_TRANSITION_DAY_GEN_HPP__
+
+
+
+namespace boost {
+namespace date_time {
+
+    //! Defines base interface for calculating start and end date of daylight savings 
+    template<class date_type>
+    class dst_day_calc_rule 
+    {
+    public:
+      typedef typename date_type::year_type year_type;
+      virtual ~dst_day_calc_rule() {};
+      virtual date_type start_day(year_type y) const=0;
+      virtual std::string start_rule_as_string() const=0;
+      virtual date_type end_day(year_type y) const=0;
+      virtual std::string end_rule_as_string() const=0;
+
+    };
+
+    //! Canonical form for a class that provides day rule calculation
+    /*! This class is used to generate specific sets of dst rules
+     *  
+     *@param spec Provides a specifiction of the function object types used
+     *            to generate start and end days of daylight savings as well
+     *            as the date type.
+     */
+    template<class spec>
+    class day_calc_dst_rule : public dst_day_calc_rule<typename spec::date_type>
+    {
+    public:
+      typedef typename spec::date_type date_type;
+      typedef typename date_type::year_type year_type;
+      typedef typename spec::start_rule start_rule;
+      typedef typename spec::end_rule  end_rule;
+      day_calc_dst_rule(start_rule dst_start,
+                        end_rule dst_end) :
+        dst_start_(dst_start),
+        dst_end_(dst_end)
+      {}
+      virtual date_type start_day(year_type y) const
+      {
+        return dst_start_.get_date(y);
+      }
+      virtual std::string start_rule_as_string() const
+      {
+        return dst_start_.to_string();
+      }
+      virtual date_type end_day(year_type y) const
+      {
+        return dst_end_.get_date(y);
+      }
+      virtual std::string end_rule_as_string() const
+      {
+        return dst_end_.to_string();
+      }
+    private:
+      start_rule dst_start_;
+      end_rule dst_end_;
+    };
+
+
+} }//namespace
+
+
+
+#endif

+ 170 - 0
ext/boost/date_time/filetime_functions.hpp

@@ -0,0 +1,170 @@
+#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__
+#define DATE_TIME_FILETIME_FUNCTIONS_HPP__
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-06 07:24:09 -0400 (Sat, 06 Jun 2009) $
+ */
+
+/*! @file filetime_functions.hpp
+ * Function(s) for converting between a FILETIME structure and a
+ * time object. This file is only available on systems that have
+ * BOOST_HAS_FTIME defined.
+ */
+
+#include <boost/date_time/compiler_config.hpp>
+
+#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME
+
+#if defined(BOOST_USE_WINDOWS_H)
+#  include <windows.h>
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/date_time/time.hpp>
+#include <boost/date_time/date_defs.hpp>
+
+namespace boost {
+
+namespace date_time {
+
+namespace winapi {
+
+#if !defined(BOOST_USE_WINDOWS_H)
+
+    extern "C" {
+
+        struct FILETIME
+        {
+            boost::uint32_t dwLowDateTime;
+            boost::uint32_t dwHighDateTime;
+        };
+        struct SYSTEMTIME
+        {
+            boost::uint16_t wYear;
+            boost::uint16_t wMonth;
+            boost::uint16_t wDayOfWeek;
+            boost::uint16_t wDay;
+            boost::uint16_t wHour;
+            boost::uint16_t wMinute;
+            boost::uint16_t wSecond;
+            boost::uint16_t wMilliseconds;
+        };
+
+        __declspec(dllimport) void __stdcall GetSystemTimeAsFileTime(FILETIME* lpFileTime);
+        __declspec(dllimport) int __stdcall FileTimeToLocalFileTime(const FILETIME* lpFileTime, FILETIME* lpLocalFileTime);
+        __declspec(dllimport) void __stdcall GetSystemTime(SYSTEMTIME* lpSystemTime);
+        __declspec(dllimport) int __stdcall SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime);
+
+    } // extern "C"
+
+#endif // defined(BOOST_USE_WINDOWS_H)
+
+    typedef FILETIME file_time;
+    typedef SYSTEMTIME system_time;
+
+    inline void get_system_time_as_file_time(file_time& ft)
+    {
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205))
+        // Some runtime library implementations expect local times as the norm for ctime.
+        file_time ft_utc;
+        GetSystemTimeAsFileTime(&ft_utc);
+        FileTimeToLocalFileTime(&ft_utc, &ft);
+#elif defined(BOOST_NO_GETSYSTEMTIMEASFILETIME)
+        system_time st;
+        GetSystemTime(&st);
+        SystemTimeToFileTime(&st, &ft);
+#else
+        GetSystemTimeAsFileTime(&ft);
+#endif
+    }
+
+    /*!
+     * The function converts file_time into number of microseconds elapsed since 1970-Jan-01
+     *
+     * \note Only dates after 1970-Jan-01 are supported. Dates before will be wrapped.
+     *
+     * \note The function is templated on the FILETIME type, so that
+     *       it can be used with both native FILETIME and the ad-hoc
+     *       boost::date_time::winapi::file_time type.
+     */
+    template< typename FileTimeT >
+    inline boost::uint64_t file_time_to_microseconds(FileTimeT const& ft)
+    {
+        /* shift is difference between 1970-Jan-01 & 1601-Jan-01
+        * in 100-nanosecond intervals */
+        const uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008
+
+        union {
+            FileTimeT as_file_time;
+            uint64_t as_integer; // 100-nanos since 1601-Jan-01
+        } caster;
+        caster.as_file_time = ft;
+
+        caster.as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01
+        return (caster.as_integer / 10); // truncate to microseconds
+    }
+
+} // namespace winapi
+
+//! Create a time object from an initialized FILETIME struct.
+/*!
+ * Create a time object from an initialized FILETIME struct.
+ * A FILETIME struct holds 100-nanosecond units (0.0000001). When
+ * built with microsecond resolution the file_time's sub second value
+ * will be truncated. Nanosecond resolution has no truncation.
+ *
+ * \note The function is templated on the FILETIME type, so that
+ *       it can be used with both native FILETIME and the ad-hoc
+ *       boost::date_time::winapi::file_time type.
+ */
+template< typename TimeT, typename FileTimeT >
+inline
+TimeT time_from_ftime(const FileTimeT& ft)
+{
+    typedef typename TimeT::date_type date_type;
+    typedef typename TimeT::date_duration_type date_duration_type;
+    typedef typename TimeT::time_duration_type time_duration_type;
+
+    // https://svn.boost.org/trac/boost/ticket/2523
+    // Since this function can be called with arbitrary times, including ones that
+    // are before 1970-Jan-01, we'll have to cast the time a bit differently,
+    // than it is done in the file_time_to_microseconds function. This allows to
+    // avoid integer wrapping for dates before 1970-Jan-01.
+    union {
+        FileTimeT as_file_time;
+        uint64_t as_integer; // 100-nanos since 1601-Jan-01
+    } caster;
+    caster.as_file_time = ft;
+
+    uint64_t sec = caster.as_integer / 10000000UL;
+    uint32_t sub_sec = (caster.as_integer % 10000000UL) // 100-nanoseconds since the last second
+#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG)
+        / 10; // microseconds since the last second
+#else
+        * 100; // nanoseconds since the last second
+#endif
+
+    // split sec into usable chunks: days, hours, minutes, & seconds
+    const uint32_t sec_per_day = 86400; // seconds per day
+    uint32_t days = static_cast< uint32_t >(sec / sec_per_day);
+    uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day);
+    uint32_t hours = tmp / 3600; // sec_per_hour
+    tmp %= 3600;
+    uint32_t minutes = tmp / 60; // sec_per_min
+    tmp %= 60;
+    uint32_t seconds = tmp; // seconds
+
+    date_duration_type dd(days);
+    date_type d = date_type(1601, Jan, 01) + dd;
+    return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec));
+}
+
+}} // boost::date_time
+
+#endif // BOOST_HAS_FTIME
+
+#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__

+ 743 - 0
ext/boost/date_time/format_date_parser.hpp

@@ -0,0 +1,743 @@
+
+#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__
+#define DATE_TIME_FORMAT_DATE_PARSER_HPP__
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+#include "boost/lexical_cast.hpp"
+#include "boost/date_time/string_parse_tree.hpp"
+#include "boost/date_time/strings_from_facet.hpp"
+#include "boost/date_time/special_values_parser.hpp"
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iterator>
+#ifndef BOOST_NO_STDC_NAMESPACE
+#  include <cctype>
+#else
+#  include <ctype.h>
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+  using ::isspace;
+  using ::isdigit;
+}
+#endif
+namespace boost { namespace date_time {
+  
+//! Helper function for parsing fixed length strings into integers
+/*! Will consume 'length' number of characters from stream. Consumed 
+ * character are transfered to parse_match_result struct. 
+ * Returns '-1' if no number can be parsed or incorrect number of 
+ * digits in stream. */
+template<typename int_type, typename charT>
+inline
+int_type
+fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
+                    std::istreambuf_iterator<charT>& stream_end,
+                    parse_match_result<charT>& mr,
+                    unsigned int length,
+                    const charT& fill_char)
+{
+  //typedef std::basic_string<charT>  string_type;
+  unsigned int j = 0;
+  //string_type s;
+  while (j < length && itr != stream_end && 
+      (std::isdigit(*itr) || *itr == fill_char)) {
+    if(*itr == fill_char) {
+      /* Since a fill_char can be anything, we convert it to a zero. 
+       * lexical_cast will behave predictably when zero is used as fill. */
+      mr.cache += ('0'); 
+    }
+    else {
+      mr.cache += (*itr);
+    }
+    itr++;
+    j++;
+  }
+  int_type i = -1;
+  // mr.cache will hold leading zeros. size() tells us when input is too short.
+  if(mr.cache.size() < length) {
+    return i;
+  }
+  try {
+    i = boost::lexical_cast<int_type>(mr.cache);
+  }catch(bad_lexical_cast&){
+    // we want to return -1 if the cast fails so nothing to do here
+  }
+  return i;
+}
+
+//! Helper function for parsing fixed length strings into integers
+/*! Will consume 'length' number of characters from stream. Consumed 
+ * character are transfered to parse_match_result struct. 
+ * Returns '-1' if no number can be parsed or incorrect number of 
+ * digits in stream. */
+template<typename int_type, typename charT>
+inline
+int_type
+fixed_string_to_int(std::istreambuf_iterator<charT>& itr,
+                    std::istreambuf_iterator<charT>& stream_end,
+                    parse_match_result<charT>& mr,
+                    unsigned int length)
+{
+  return fixed_string_to_int<int_type, charT>(itr, stream_end, mr, length, '0');
+}
+
+//! Helper function for parsing varied length strings into integers
+/*! Will consume 'max_length' characters from stream only if those 
+ * characters are digits. Returns '-1' if no number can be parsed. 
+ * Will not parse a number preceeded by a '+' or '-'. */
+template<typename int_type, typename charT>
+inline
+int_type
+var_string_to_int(std::istreambuf_iterator<charT>& itr,
+                  const std::istreambuf_iterator<charT>& stream_end,
+                  unsigned int max_length)
+{
+  typedef std::basic_string<charT>  string_type;
+  unsigned int j = 0;
+  string_type s;
+  while (itr != stream_end && (j < max_length) && std::isdigit(*itr)) {
+    s += (*itr);
+    ++itr;
+    ++j;
+  }
+  int_type i = -1;
+  if(!s.empty()) {
+    i = boost::lexical_cast<int_type>(s);
+  }
+  return i;
+}
+
+
+//! Class with generic date parsing using a format string
+/*! The following is the set of recognized format specifiers
+ -  %a - Short weekday name
+ -  %A - Long weekday name
+ -  %b - Abbreviated month name
+ -  %B - Full month name
+ -  %d - Day of the month as decimal 01 to 31
+ -  %j - Day of year as decimal from 001 to 366
+ -  %m - Month name as a decimal 01 to 12
+ -  %U - Week number 00 to 53 with first Sunday as the first day of week 1?
+ -  %w - Weekday as decimal number 0 to 6 where Sunday == 0
+ -  %W - Week number 00 to 53 where Monday is first day of week 1
+ -  %x - facet default date representation
+ -  %y - Year without the century - eg: 04 for 2004
+ -  %Y - Year with century 
+
+ The weekday specifiers (%a and %A) do not add to the date construction,
+ but they provide a way to skip over the weekday names for formats that
+ provide them.
+
+ todo -- Another interesting feature that this approach could provide is
+         an option to fill in any missing fields with the current values
+         from the clock.  So if you have %m-%d the parser would detect
+         the missing year value and fill it in using the clock. 
+
+ todo -- What to do with the %x.  %x in the classic facet is just bad...
+
+ */
+template<class date_type, typename charT>
+class format_date_parser
+{
+ public:
+  typedef std::basic_string<charT>        string_type;
+  typedef std::basic_istringstream<charT>  stringstream_type;
+  typedef std::istreambuf_iterator<charT> stream_itr_type;
+  typedef typename string_type::const_iterator const_itr;
+  typedef typename date_type::year_type  year_type;
+  typedef typename date_type::month_type month_type;
+  typedef typename date_type::day_type day_type;
+  typedef typename date_type::duration_type duration_type;
+  typedef typename date_type::day_of_week_type day_of_week_type;
+  typedef typename date_type::day_of_year_type day_of_year_type;
+  typedef string_parse_tree<charT> parse_tree_type;
+  typedef typename parse_tree_type::parse_match_result_type match_results;
+  typedef std::vector<std::basic_string<charT> > input_collection_type;
+
+  // TODO sv_parser uses its default constructor - write the others
+  
+  format_date_parser(const string_type& format_str,
+                     const input_collection_type& month_short_names,
+                     const input_collection_type& month_long_names,
+                     const input_collection_type& weekday_short_names,
+                     const input_collection_type& weekday_long_names) :
+    m_format(format_str),
+    m_month_short_names(month_short_names, 1),
+    m_month_long_names(month_long_names, 1),
+    m_weekday_short_names(weekday_short_names),
+    m_weekday_long_names(weekday_long_names)
+  {}
+  
+  format_date_parser(const string_type& format_str,
+                     const std::locale& locale) :
+    m_format(format_str),
+    m_month_short_names(gather_month_strings<charT>(locale), 1),
+    m_month_long_names(gather_month_strings<charT>(locale, false), 1),
+    m_weekday_short_names(gather_weekday_strings<charT>(locale)),
+    m_weekday_long_names(gather_weekday_strings<charT>(locale, false))
+  {}
+
+  format_date_parser(const format_date_parser<date_type,charT>& fdp)
+  {
+    this->m_format = fdp.m_format;
+    this->m_month_short_names = fdp.m_month_short_names;
+    this->m_month_long_names = fdp.m_month_long_names;
+    this->m_weekday_short_names = fdp.m_weekday_short_names;
+    this->m_weekday_long_names = fdp.m_weekday_long_names;
+  }
+  
+  string_type format() const
+  {
+    return m_format;
+  }
+
+  void format(string_type format_str)
+  {
+    m_format = format_str;
+  }
+
+  void short_month_names(const input_collection_type& month_names)
+  {
+    m_month_short_names = parse_tree_type(month_names, 1);
+  }
+  void long_month_names(const input_collection_type& month_names)
+  {
+    m_month_long_names = parse_tree_type(month_names, 1);
+  }
+  void short_weekday_names(const input_collection_type& weekday_names)
+  {
+    m_weekday_short_names = parse_tree_type(weekday_names);
+  }
+  void long_weekday_names(const input_collection_type& weekday_names)
+  {
+    m_weekday_long_names = parse_tree_type(weekday_names);
+  }
+
+  date_type
+  parse_date(const string_type& value, 
+             const string_type& format_str,
+             const special_values_parser<date_type,charT>& sv_parser) const
+  {
+    stringstream_type ss(value);
+    stream_itr_type sitr(ss);
+    stream_itr_type stream_end;
+    return parse_date(sitr, stream_end, format_str, sv_parser);
+  }
+
+  date_type
+  parse_date(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             const special_values_parser<date_type,charT>& sv_parser) const
+  {
+    return parse_date(sitr, stream_end, m_format, sv_parser);
+  }
+
+  /*! Of all the objects that the format_date_parser can parse, only a 
+   * date can be a special value. Therefore, only parse_date checks 
+   * for special_values. */
+  date_type
+  parse_date(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str,
+             const special_values_parser<date_type,charT>& sv_parser) const
+  {
+    bool use_current_char = false;
+    
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+    charT current_char = *sitr;
+
+    short year(0), month(0), day(0), day_of_year(0);// wkday(0); 
+    /* Initialized the following to their minimum values. These intermediate 
+     * objects are used so we get specific exceptions when part of the input 
+     * is unparsable. 
+     * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/
+    year_type t_year(1400);
+    month_type t_month(1);
+    day_type t_day(1);
+    day_of_week_type wkday(0);
+    
+    
+    const_itr itr(format_str.begin());
+    while (itr != format_str.end() && (sitr != stream_end)) {
+      if (*itr == '%') {
+        itr++;
+        if (*itr != '%') {
+          switch(*itr) {
+          case 'a': 
+            {
+              //this value is just throw away.  It could be used for
+              //error checking potentially, but it isn't helpful in 
+              //actually constructing the date - we just need to get it
+              //out of the stream
+              match_results mr = m_weekday_short_names.match(sitr, stream_end);
+              if(mr.current_match == match_results::PARSE_ERROR) {
+                // check special_values
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              wkday = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'A': 
+            {
+              //this value is just throw away.  It could be used for
+              //error checking potentially, but it isn't helpful in 
+              //actually constructing the date - we just need to get it
+              //out of the stream
+              match_results mr = m_weekday_long_names.match(sitr, stream_end);
+              if(mr.current_match == match_results::PARSE_ERROR) {
+                // check special_values
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              wkday = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'b': 
+            {
+              match_results mr = m_month_short_names.match(sitr, stream_end);
+              if(mr.current_match == match_results::PARSE_ERROR) {
+                // check special_values
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_month = month_type(mr.current_match);
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'B': 
+            {
+              match_results mr = m_month_long_names.match(sitr, stream_end);
+              if(mr.current_match == match_results::PARSE_ERROR) {
+                // check special_values
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_month = month_type(mr.current_match);
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'd': 
+            {
+              match_results mr;
+              day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+              if(day == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_day = day_type(day);
+              break;
+            }
+          case 'e': 
+            {
+              match_results mr;
+              day = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2, ' ');
+              if(day == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_day = day_type(day);
+              break;
+            }
+          case 'j': 
+            {
+              match_results mr;
+              day_of_year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 3);
+              if(day_of_year == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              // these next two lines are so we get an exception with bad input
+              day_of_year_type t_day_of_year(1);
+              t_day_of_year = day_of_year_type(day_of_year);
+              break;
+            }
+          case 'm': 
+            {
+              match_results mr;
+              month = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+              if(month == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_month = month_type(month);
+              break;
+            }
+          case 'Y': 
+            {
+              match_results mr;
+              year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
+              if(year == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              t_year = year_type(year);
+              break;
+            }
+          case 'y': 
+            {
+              match_results mr;
+              year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+              if(year == -1) {
+                if(sv_parser.match(sitr, stream_end, mr)) {
+                  return date_type(static_cast<special_values>(mr.current_match));
+                }
+              }
+              year += 2000; //make 2 digit years in this century
+              t_year = year_type(year);
+              break;
+            }
+          default:
+            {} //ignore those we don't understand
+            
+          }//switch
+          
+        }
+        else { // itr == '%', second consecutive
+          sitr++;
+        }
+        
+        itr++; //advance past format specifier
+      }
+      else {  //skip past chars in format and in buffer
+        itr++;
+        if (use_current_char) {
+          use_current_char = false;
+          current_char = *sitr;
+        }
+        else {
+          sitr++;
+        }
+      }
+    }
+    
+    if (day_of_year > 0) {
+      date_type d(static_cast<unsigned short>(year-1),12,31); //end of prior year
+      return d + duration_type(day_of_year);
+    }
+    
+    return date_type(t_year, t_month, t_day); // exceptions were thrown earlier 
+                                        // if input was no good 
+  }
+ 
+  //! Throws bad_month if unable to parse
+  month_type
+  parse_month(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str) const
+  {
+    match_results mr;
+    return parse_month(sitr, stream_end, format_str, mr);
+  }
+ 
+  //! Throws bad_month if unable to parse
+  month_type
+  parse_month(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str,
+             match_results& mr) const
+  {
+    bool use_current_char = false;
+    
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+    charT current_char = *sitr;
+
+    short month(0);
+    
+    const_itr itr(format_str.begin());
+    while (itr != format_str.end() && (sitr != stream_end)) {
+      if (*itr == '%') {
+        itr++;
+        if (*itr != '%') {
+          switch(*itr) {
+          case 'b': 
+            {
+              mr = m_month_short_names.match(sitr, stream_end);
+              month = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'B': 
+            {
+              mr = m_month_long_names.match(sitr, stream_end);
+              month = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'm': 
+            {
+              month = var_string_to_int<short, charT>(sitr, stream_end, 2);
+              // var_string_to_int returns -1 if parse failed. That will 
+              // cause a bad_month exception to be thrown so we do nothing here
+              break;
+            }
+          default:
+            {} //ignore those we don't understand
+            
+          }//switch
+          
+        }
+        else { // itr == '%', second consecutive
+          sitr++;
+        }
+        
+        itr++; //advance past format specifier
+      }
+      else {  //skip past chars in format and in buffer
+        itr++;
+        if (use_current_char) {
+          use_current_char = false;
+          current_char = *sitr;
+        }
+        else {
+          sitr++;
+        }
+      }
+    }
+    
+    return month_type(month); // throws bad_month exception when values are zero
+  }
+
+  //! Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse
+  day_type
+  parse_var_day_of_month(std::istreambuf_iterator<charT>& sitr, 
+                         std::istreambuf_iterator<charT>& stream_end) const
+  {
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+
+    return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
+  }
+  //! Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse
+  day_type
+  parse_day_of_month(std::istreambuf_iterator<charT>& sitr, 
+                     std::istreambuf_iterator<charT>& stream_end) const
+  {
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+
+    //return day_type(var_string_to_int<short, charT>(sitr, stream_end, 2));
+    match_results mr;
+    return day_type(fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2));
+  }
+
+  day_of_week_type
+  parse_weekday(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str) const
+  {
+    match_results mr;
+    return parse_weekday(sitr, stream_end, format_str, mr);
+  }
+  day_of_week_type
+  parse_weekday(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str,
+             match_results& mr) const
+  {
+    bool use_current_char = false;
+    
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+    charT current_char = *sitr;
+
+    short wkday(0);
+    
+    const_itr itr(format_str.begin());
+    while (itr != format_str.end() && (sitr != stream_end)) {
+      if (*itr == '%') {
+        itr++;
+        if (*itr != '%') {
+          switch(*itr) {
+          case 'a': 
+            {
+              //this value is just throw away.  It could be used for
+              //error checking potentially, but it isn't helpful in 
+              //actually constructing the date - we just need to get it
+              //out of the stream
+              mr = m_weekday_short_names.match(sitr, stream_end);
+              wkday = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'A': 
+            {
+              //this value is just throw away.  It could be used for
+              //error checking potentially, but it isn't helpful in 
+              //actually constructing the date - we just need to get it
+              //out of the stream
+              mr = m_weekday_long_names.match(sitr, stream_end);
+              wkday = mr.current_match;
+              if (mr.has_remaining()) {
+                current_char = mr.last_char();
+                use_current_char = true;
+              }
+              break;
+            }
+          case 'w':
+            {
+              // weekday as number 0-6, Sunday == 0
+              wkday = var_string_to_int<short, charT>(sitr, stream_end, 2);
+              break;
+            }
+          default:
+            {} //ignore those we don't understand
+            
+          }//switch
+          
+        }
+        else { // itr == '%', second consecutive
+          sitr++;
+        }
+        
+        itr++; //advance past format specifier
+      }
+      else {  //skip past chars in format and in buffer
+        itr++;
+        if (use_current_char) {
+          use_current_char = false;
+          current_char = *sitr;
+        }
+        else {
+          sitr++;
+        }
+      }
+    }
+    
+    return day_of_week_type(wkday); // throws bad_day_of_month exception 
+                                    // when values are zero
+  }
+  
+  //! throws bad_year if unable to parse
+  year_type
+  parse_year(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str) const
+  {
+    match_results mr;
+    return parse_year(sitr, stream_end, format_str, mr);
+  }
+
+  //! throws bad_year if unable to parse
+  year_type
+  parse_year(std::istreambuf_iterator<charT>& sitr, 
+             std::istreambuf_iterator<charT>& stream_end,
+             string_type format_str,
+             match_results& mr) const
+  {
+    bool use_current_char = false;
+    
+    // skip leading whitespace
+    while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+    charT current_char = *sitr;
+
+    unsigned short year(0);
+    
+    const_itr itr(format_str.begin());
+    while (itr != format_str.end() && (sitr != stream_end)) {
+      if (*itr == '%') {
+        itr++;
+        if (*itr != '%') {
+          //match_results mr;
+          switch(*itr) {
+          case 'Y':
+            {
+              // year from 4 digit string
+              year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 4);
+              break;
+            }
+          case 'y':
+            {
+              // year from 2 digit string (no century)
+              year = fixed_string_to_int<short, charT>(sitr, stream_end, mr, 2);
+              year += 2000; //make 2 digit years in this century
+              break;
+            }
+          default:
+            {} //ignore those we don't understand
+            
+          }//switch
+          
+        }
+        else { // itr == '%', second consecutive
+          sitr++;
+        }
+        
+        itr++; //advance past format specifier
+      }
+      else {  //skip past chars in format and in buffer
+        itr++;
+        if (use_current_char) {
+          use_current_char = false;
+          current_char = *sitr;
+        }
+        else {
+          sitr++;
+        }
+      }
+    }
+    
+    return year_type(year); // throws bad_year exception when values are zero
+  }
+  
+  
+ private:
+  string_type m_format;
+  parse_tree_type m_month_short_names;
+  parse_tree_type m_month_long_names;
+  parse_tree_type m_weekday_short_names;
+  parse_tree_type m_weekday_long_names;
+
+};
+
+} } //namespace
+
+#endif
+
+
+

+ 66 - 0
ext/boost/date_time/gregorian/conversion.hpp

@@ -0,0 +1,66 @@
+#ifndef _GREGORIAN__CONVERSION_HPP___
+#define _GREGORIAN__CONVERSION_HPP___
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-06 07:27:35 -0400 (Sat, 06 Jun 2009) $
+ */
+
+#include <string>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/c_time.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+
+namespace boost {
+
+namespace gregorian {
+
+  //! Converts a date to a tm struct. Throws out_of_range exception if date is a special value
+  inline
+  std::tm to_tm(const date& d)
+  {
+    if (d.is_special())
+    {
+        std::string s = "tm unable to handle ";
+        switch (d.as_special())
+        {
+        case date_time::not_a_date_time:
+            s += "not-a-date-time value"; break;
+        case date_time::neg_infin:
+            s += "-infinity date value"; break;
+        case date_time::pos_infin:
+            s += "+infinity date value"; break;
+        default:
+            s += "a special date value"; break;
+        }
+        boost::throw_exception(std::out_of_range(s));
+    }
+
+    std::tm datetm = {}; // zero initialization is needed for extension members, like tm_zone
+    boost::gregorian::date::ymd_type ymd = d.year_month_day();
+    datetm.tm_year = ymd.year - 1900;
+    datetm.tm_mon = ymd.month - 1;
+    datetm.tm_mday = ymd.day;
+    datetm.tm_wday = d.day_of_week();
+    datetm.tm_yday = d.day_of_year() - 1;
+    datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst
+    return datetm;
+  }
+
+  //! Converts a tm structure into a date dropping the any time values.
+  inline
+  date date_from_tm(const std::tm& datetm)
+  {
+    return date(static_cast<unsigned short>(datetm.tm_year+1900),
+                static_cast<unsigned short>(datetm.tm_mon+1),
+                static_cast<unsigned short>(datetm.tm_mday));
+  }
+
+} } //namespace boost::gregorian
+
+#endif

+ 162 - 0
ext/boost/date_time/gregorian/formatters.hpp

@@ -0,0 +1,162 @@
+#ifndef GREGORIAN_FORMATTERS_HPP___
+#define GREGORIAN_FORMATTERS_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/date_formatting_limited.hpp"
+#else
+#include "boost/date_time/date_formatting.hpp"
+#endif
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+
+/* NOTE: "to_*_string" code for older compilers, ones that define 
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in 
+ * formatters_limited.hpp
+ */
+
+namespace boost {
+namespace gregorian {
+
+  // wrapper function for to_simple_(w)string(date)
+  template<class charT>
+  inline 
+  std::basic_string<charT> to_simple_string_type(const date& d) {
+    return date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d);
+  }
+  //! To YYYY-mmm-DD string where mmm 3 char month name. Example:  2002-Jan-01
+  /*!\ingroup date_format
+   */
+  inline std::string to_simple_string(const date& d) {
+    return to_simple_string_type<char>(d);
+  }
+
+
+  // wrapper function for to_simple_(w)string(date_period)
+  template<class charT>
+  inline std::basic_string<charT> to_simple_string_type(const date_period& d) {
+    typedef std::basic_string<charT> string_type;
+    charT b = '[', m = '/', e=']';
+
+    string_type d1(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.begin()));
+    string_type d2(date_time::date_formatter<date,date_time::simple_format<charT>,charT>::date_to_string(d.last()));
+    return string_type(b + d1 + m + d2 + e);
+  }
+  //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+  /*!\ingroup date_format
+   */
+  inline std::string to_simple_string(const date_period& d) {
+    return to_simple_string_type<char>(d);
+  }
+
+  // wrapper function for to_iso_(w)string(date_period)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_string_type(const date_period& d) {
+    charT sep = '/';
+    std::basic_string<charT> s(date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.begin()));
+    return s + sep + date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d.last());
+  }
+  //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_string(const date_period& d) {
+    return to_iso_string_type<char>(d);
+  }
+
+
+  // wrapper function for to_iso_extended_(w)string(date)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_extended_string_type(const date& d) {
+    return date_time::date_formatter<date,date_time::iso_extended_format<charT>,charT>::date_to_string(d);
+  }
+  //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_extended_string(const date& d) {
+    return to_iso_extended_string_type<char>(d);
+  }
+
+  // wrapper function for to_iso_(w)string(date)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_string_type(const date& d) {
+    return date_time::date_formatter<date,date_time::iso_format<charT>,charT>::date_to_string(d);
+  }
+  //! Convert to iso standard string YYYYMMDD. Example: 20021231
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_string(const date& d) {
+    return to_iso_string_type<char>(d);
+  }
+
+  
+  
+
+  // wrapper function for to_sql_(w)string(date)
+  template<class charT>
+  inline std::basic_string<charT> to_sql_string_type(const date& d) 
+  {
+    date::ymd_type ymd = d.year_month_day();
+    std::basic_ostringstream<charT> ss;
+    ss << ymd.year << "-"
+       << std::setw(2) << std::setfill(ss.widen('0')) 
+       << ymd.month.as_number() //solves problem with gcc 3.1 hanging
+       << "-"
+       << std::setw(2) << std::setfill(ss.widen('0')) 
+       << ymd.day;
+    return ss.str();
+  }
+  inline std::string to_sql_string(const date& d) {
+    return to_sql_string_type<char>(d);
+  }
+
+
+#if !defined(BOOST_NO_STD_WSTRING)
+  //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+  /*!\ingroup date_format
+   */
+  inline std::wstring to_simple_wstring(const date_period& d) {
+    return to_simple_string_type<wchar_t>(d);
+  }
+  //! To YYYY-mmm-DD string where mmm 3 char month name. Example:  2002-Jan-01
+  /*!\ingroup date_format
+   */
+  inline std::wstring to_simple_wstring(const date& d) {
+    return to_simple_string_type<wchar_t>(d);
+  }
+  //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+  /*!\ingroup date_format
+   */
+  inline std::wstring to_iso_wstring(const date_period& d) {
+    return to_iso_string_type<wchar_t>(d);
+  }
+  //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+  /*!\ingroup date_format
+   */
+  inline std::wstring to_iso_extended_wstring(const date& d) {
+    return to_iso_extended_string_type<wchar_t>(d);
+  }
+  //! Convert to iso standard string YYYYMMDD. Example: 20021231
+  /*!\ingroup date_format
+   */
+  inline std::wstring to_iso_wstring(const date& d) {
+    return to_iso_string_type<wchar_t>(d);
+  }
+  inline std::wstring to_sql_wstring(const date& d) {
+    return to_sql_string_type<wchar_t>(d);
+  }
+#endif // BOOST_NO_STD_WSTRING
+
+} } //namespace gregorian
+
+
+#endif
+

+ 81 - 0
ext/boost/date_time/gregorian/formatters_limited.hpp

@@ -0,0 +1,81 @@
+#ifndef GREGORIAN_FORMATTERS_LIMITED_HPP___
+#define GREGORIAN_FORMATTERS_LIMITED_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_formatting_limited.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/compiler_config.hpp"
+
+namespace boost {
+namespace gregorian {
+
+  //! To YYYY-mmm-DD string where mmm 3 char month name. Example:  2002-Jan-01
+  /*!\ingroup date_format
+   */
+  inline std::string to_simple_string(const date& d) {
+    return date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d);
+  }
+
+  //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02]
+  /*!\ingroup date_format
+   */
+  inline std::string to_simple_string(const date_period& d) {
+    std::string s("[");
+    std::string d1(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.begin()));
+    std::string d2(date_time::date_formatter<date,date_time::simple_format<char> >::date_to_string(d.last()));
+    return std::string("[" + d1 + "/" + d2 + "]");
+  }
+
+  //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_string(const date_period& d) {
+    std::string s(date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.begin()));
+    return s + "/" + date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d.last());
+  }
+
+
+  //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_extended_string(const date& d) {
+    return date_time::date_formatter<date,date_time::iso_extended_format<char> >::date_to_string(d);
+  }
+
+  //! Convert to iso standard string YYYYMMDD. Example: 20021231
+  /*!\ingroup date_format
+   */
+  inline std::string to_iso_string(const date& d) {
+    return date_time::date_formatter<date,date_time::iso_format<char> >::date_to_string(d);
+  }
+  
+  
+
+  inline std::string to_sql_string(const date& d) 
+  {
+    date::ymd_type ymd = d.year_month_day();
+    std::ostringstream ss;
+    ss << ymd.year << "-"
+       << std::setw(2) << std::setfill('0') 
+       << ymd.month.as_number() //solves problem with gcc 3.1 hanging
+       << "-"
+       << std::setw(2) << std::setfill('0') 
+       << ymd.day;
+    return ss.str();
+  }
+
+
+} } //namespace gregorian
+
+
+#endif
+

+ 47 - 0
ext/boost/date_time/gregorian/greg_calendar.hpp

@@ -0,0 +1,47 @@
+#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__
+#define GREGORIAN_GREGORIAN_CALENDAR_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/greg_weekday.hpp"
+#include "boost/date_time/gregorian/greg_day_of_year.hpp"
+#include "boost/date_time/gregorian_calendar.hpp"
+#include "boost/date_time/gregorian/greg_ymd.hpp"
+#include "boost/date_time/int_adapter.hpp"
+
+namespace boost {
+namespace gregorian {
+    
+  //!An internal date representation that includes infinities, not a date
+  typedef date_time::int_adapter<unsigned long> fancy_date_rep;
+
+  //! Gregorian calendar for this implementation, hard work in the base
+  class gregorian_calendar : 
+    public date_time::gregorian_calendar_base<greg_year_month_day, fancy_date_rep::int_type> {
+  public:
+    //! Type to hold a weekday (eg: Sunday, Monday,...)
+    typedef greg_weekday         day_of_week_type;
+    //! Counter type from 1 to 366 for gregorian dates.
+    typedef greg_day_of_year_rep day_of_year_type;
+    //! Internal date representation that handles infinity, not a date
+    typedef fancy_date_rep       date_rep_type;
+    //! Date rep implements the traits stuff as well
+    typedef fancy_date_rep       date_traits_type;
+
+    
+  private:
+  };
+
+} } //namespace gregorian
+  
+
+
+
+#endif
+  

+ 136 - 0
ext/boost/date_time/gregorian/greg_date.hpp

@@ -0,0 +1,136 @@
+#ifndef GREG_DATE_HPP___
+#define GREG_DATE_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/date.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/gregorian/greg_calendar.hpp>
+#include <boost/date_time/gregorian/greg_duration.hpp>
+
+namespace boost {
+namespace gregorian {
+
+  //bring special enum values into the namespace
+  using date_time::special_values;
+  using date_time::not_special;
+  using date_time::neg_infin;
+  using date_time::pos_infin;
+  using date_time::not_a_date_time;
+  using date_time::max_date_time;
+  using date_time::min_date_time;
+
+  //! A date type based on gregorian_calendar
+  /*! This class is the primary interface for programming with 
+      greogorian dates.  The is a lightweight type that can be
+      freely passed by value.  All comparison operators are 
+      supported.  
+      \ingroup date_basics
+  */
+  class date : public date_time::date<date, gregorian_calendar, date_duration>
+  {
+   public:
+    typedef gregorian_calendar::year_type year_type;
+    typedef gregorian_calendar::month_type month_type;
+    typedef gregorian_calendar::day_type day_type;
+    typedef gregorian_calendar::day_of_year_type day_of_year_type;
+    typedef gregorian_calendar::ymd_type ymd_type;
+    typedef gregorian_calendar::date_rep_type date_rep_type;
+    typedef gregorian_calendar::date_int_type date_int_type;
+    typedef date_duration  duration_type;
+#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
+    //! Default constructor constructs with not_a_date_time
+    date():
+      date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(not_a_date_time))
+    {}
+#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+    //! Main constructor with year, month, day
+    date(year_type y, month_type m, day_type d) 
+      : date_time::date<date, gregorian_calendar, date_duration>(y, m, d)
+    {
+      if (gregorian_calendar::end_of_month_day(y, m) < d) {
+        boost::throw_exception(bad_day_of_month(std::string("Day of month is not valid for year")));
+      }
+    }
+    //! Constructor from a ymd_type structure
+    explicit date(const ymd_type& ymd) 
+      : date_time::date<date, gregorian_calendar, date_duration>(ymd)
+    {}
+    //! Needed copy constructor
+    explicit date(const date_int_type& rhs):
+      date_time::date<date,gregorian_calendar, date_duration>(rhs)
+    {}
+    //! Needed copy constructor
+    explicit date(date_rep_type rhs):
+      date_time::date<date,gregorian_calendar, date_duration>(rhs)
+    {}
+    //! Constructor for infinities, not a date, max and min date
+    explicit date(special_values sv):
+      date_time::date<date, gregorian_calendar, date_duration>(date_rep_type::from_special(sv))
+    {
+      if (sv == min_date_time)
+      {
+        *this = date(1400, 1, 1);
+      }
+      if (sv == max_date_time)
+      {
+        *this = date(9999, 12, 31);
+      }
+
+    }
+    //!Return the Julian Day number for the date.
+    date_int_type julian_day() const
+    {
+      ymd_type ymd = year_month_day();
+      return gregorian_calendar::julian_day_number(ymd);
+    }
+    //!Return the day of year 1..365 or 1..366 (for leap year)
+    day_of_year_type day_of_year() const
+    {
+      date start_of_year(year(), 1, 1);
+      unsigned short doy = static_cast<unsigned short>((*this-start_of_year).days() + 1);
+      return day_of_year_type(doy);
+    }
+    //!Return the Modified Julian Day number for the date.
+    long modjulian_day() const
+    {
+      ymd_type ymd = year_month_day();
+      return gregorian_calendar::modjulian_day_number(ymd);      
+    }
+    //!Return the iso 8601 week number 1..53
+    int week_number() const
+    {
+      ymd_type ymd = year_month_day();
+      return gregorian_calendar::week_number(ymd);      
+    }
+    //! Return the day number from the calendar
+    date_int_type day_number() const
+    {
+      return days_;
+    }
+    //! Return the last day of the current month
+    date end_of_month() const
+    {
+      ymd_type ymd = year_month_day(); 
+      short eom_day =  gregorian_calendar::end_of_month_day(ymd.year, ymd.month);
+      return date(ymd.year, ymd.month, eom_day);
+    }
+
+   private:
+
+  };
+  
+
+
+} } //namespace gregorian
+
+
+
+#endif

+ 57 - 0
ext/boost/date_time/gregorian/greg_day.hpp

@@ -0,0 +1,57 @@
+#ifndef GREG_DAY_HPP___
+#define GREG_DAY_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+  //! Exception type for gregorian day of month (1..31)
+  struct bad_day_of_month : public std::out_of_range
+  {
+    bad_day_of_month() : 
+      std::out_of_range(std::string("Day of month value is out of range 1..31")) 
+    {}
+    //! Allow other classes to throw with unique string for bad day like Feb 29
+    bad_day_of_month(const std::string& s) : 
+      std::out_of_range(s) 
+    {}
+  };
+  //! Policy class that declares error handling and day of month ranges
+  typedef CV::simple_exception_policy<unsigned short, 1, 31, bad_day_of_month> greg_day_policies;
+
+  //! Generated represetation for gregorian day of month
+  typedef CV::constrained_value<greg_day_policies> greg_day_rep;
+
+  //! Represent a day of the month (range 1 - 31) 
+  /*! This small class allows for simple conversion an integer value into
+      a day of the month for a standard gregorian calendar.  The type 
+      is automatically range checked so values outside of the range 1-31
+      will cause a bad_day_of_month exception
+  */
+  class greg_day : public greg_day_rep {
+  public:
+    greg_day(unsigned short day_of_month) : greg_day_rep(day_of_month) {}
+    unsigned short as_number() const {return value_;}
+    operator unsigned short()  const {return value_;}
+  private:
+    
+  };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif

+ 38 - 0
ext/boost/date_time/gregorian/greg_day_of_year.hpp

@@ -0,0 +1,38 @@
+#ifndef GREG_DAY_OF_YEAR_HPP___
+#define GREG_DAY_OF_YEAR_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+  //! Exception type for day of year (1..366)
+  struct bad_day_of_year : public std::out_of_range
+  {
+    bad_day_of_year() : 
+      std::out_of_range(std::string("Day of year value is out of range 1..366")) 
+    {}
+  };
+
+  //! A day of the year range (1..366)
+  typedef CV::simple_exception_policy<unsigned short,1,366,bad_day_of_year> greg_day_of_year_policies;
+
+  //! Define a range representation type for the day of the year 1..366
+  typedef CV::constrained_value<greg_day_of_year_policies> greg_day_of_year_rep;
+
+
+} } //namespace gregorian
+
+
+
+#endif

+ 134 - 0
ext/boost/date_time/gregorian/greg_duration.hpp

@@ -0,0 +1,134 @@
+#ifndef GREG_DURATION_HPP___
+#define GREG_DURATION_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/date_time/date_duration.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace gregorian {
+
+  //!An internal date representation that includes infinities, not a date
+  typedef boost::date_time::duration_traits_adapted date_duration_rep;
+
+  //! Durations in days for gregorian system
+  /*! \ingroup date_basics
+   */
+  class date_duration :
+    public boost::date_time::date_duration< date_duration_rep >
+  {
+    typedef boost::date_time::date_duration< date_duration_rep > base_type;
+
+  public:
+    typedef base_type::duration_rep duration_rep;
+
+    //! Construct from a day count
+    explicit date_duration(duration_rep day_count = 0) : base_type(day_count) {}
+
+    //! construct from special_values
+    date_duration(date_time::special_values sv) : base_type(sv) {}
+
+    //! Copy constructor
+    date_duration(const date_duration& other) : base_type(static_cast< base_type const& >(other))
+    {}
+
+    //! Construct from another date_duration
+    date_duration(const base_type& other) : base_type(other)
+    {}
+
+    //  Relational operators
+    //  NOTE: Because of date_time::date_duration< T > design choice we don't use Boost.Operators here,
+    //  because we need the class to be a direct base. Either lose EBO, or define operators by hand.
+    //  The latter is more effecient.
+    bool operator== (const date_duration& rhs) const
+    {
+      return base_type::operator== (rhs);
+    }
+    bool operator!= (const date_duration& rhs) const
+    {
+      return !operator== (rhs);
+    }
+    bool operator< (const date_duration& rhs) const
+    {
+      return base_type::operator< (rhs);
+    }
+    bool operator> (const date_duration& rhs) const
+    {
+      return !(base_type::operator< (rhs) || base_type::operator== (rhs));
+    }
+    bool operator<= (const date_duration& rhs) const
+    {
+      return (base_type::operator< (rhs) || base_type::operator== (rhs));
+    }
+    bool operator>= (const date_duration& rhs) const
+    {
+      return !base_type::operator< (rhs);
+    }
+
+    //! Subtract another duration -- result is signed
+    date_duration& operator-= (const date_duration& rhs)
+    {
+      base_type::operator-= (rhs);
+      return *this;
+    }
+    friend date_duration operator- (date_duration rhs, date_duration const& lhs)
+    {
+      rhs -= lhs;
+      return rhs;
+    }
+
+    //! Add a duration -- result is signed
+    date_duration& operator+= (const date_duration& rhs)
+    {
+      base_type::operator+= (rhs);
+      return *this;
+    }
+    friend date_duration operator+ (date_duration rhs, date_duration const& lhs)
+    {
+      rhs += lhs;
+      return rhs;
+    }
+
+    //! unary- Allows for dd = -date_duration(2); -> dd == -2
+    date_duration operator- ()const
+    {
+      return date_duration(get_rep() * (-1));
+    }
+
+    //! Division operations on a duration with an integer.
+    date_duration& operator/= (int divisor)
+    {
+      base_type::operator/= (divisor);
+      return *this;
+    }
+    friend date_duration operator/ (date_duration rhs, int lhs)
+    {
+      rhs /= lhs;
+      return rhs;
+    }
+
+    //! Returns the smallest duration -- used by to calculate 'end'
+    static date_duration unit()
+    {
+      return date_duration(base_type::unit().get_rep());
+    }
+  };      
+
+  //! Shorthand for date_duration
+  typedef date_duration days;
+
+} } //namespace gregorian
+
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include <boost/date_time/date_duration_types.hpp>
+#endif
+
+#endif

+ 43 - 0
ext/boost/date_time/gregorian/greg_duration_types.hpp

@@ -0,0 +1,43 @@
+#ifndef GREG_DURATION_TYPES_HPP___
+#define GREG_DURATION_TYPES_HPP___
+                                                                                
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Subject to Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include <boost/date_time/gregorian/greg_date.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/adjust_functors.hpp>
+#include <boost/date_time/date_duration_types.hpp>
+#include <boost/date_time/gregorian/greg_duration.hpp>
+
+namespace boost {
+namespace gregorian {
+
+  //! config struct for additional duration types (ie months_duration<> & years_duration<>)
+  struct greg_durations_config {
+    typedef date date_type;
+    typedef date_time::int_adapter<int> int_rep;
+    typedef date_time::month_functor<date_type> month_adjustor_type; 
+  };
+
+  typedef date_time::months_duration<greg_durations_config> months;
+  typedef date_time::years_duration<greg_durations_config> years;
+
+  class weeks_duration : public date_duration {
+  public:
+    weeks_duration(duration_rep w) 
+      : date_duration(w * 7) {}
+    weeks_duration(date_time::special_values sv) 
+      : date_duration(sv) {}
+  };
+
+  typedef weeks_duration weeks;
+
+}} // namespace boost::gregorian
+
+#endif // GREG_DURATION_TYPES_HPP___

+ 354 - 0
ext/boost/date_time/gregorian/greg_facet.hpp

@@ -0,0 +1,354 @@
+#ifndef GREGORIAN_FACET_HPP___
+#define GREGORIAN_FACET_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-23 06:13:35 -0500 (Sun, 23 Nov 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_formatting_locales.hpp" // sets BOOST_DATE_TIME_NO_LOCALE
+#include "boost/date_time/gregorian/parsers.hpp"
+
+//This file is basically commented out if locales are not supported
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include <string>
+#include <memory>
+#include <locale>
+#include <iostream>
+#include <exception>
+
+namespace boost {
+namespace gregorian {
+  
+  //! Configuration of the output facet template
+  struct greg_facet_config
+  {
+    typedef boost::gregorian::greg_month month_type;
+    typedef boost::date_time::special_values special_value_enum;
+    typedef boost::gregorian::months_of_year month_enum;
+    typedef boost::date_time::weekdays weekday_enum;
+  };
+
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+  //! Create the base facet type for gregorian::date
+  typedef boost::date_time::date_names_put<greg_facet_config> greg_base_facet;
+
+  //! ostream operator for gregorian::date
+  /*! Uses the date facet to determine various output parameters including:
+   *  - string values for the month (eg: Jan, Feb, Mar) (default: English)
+   *  - string values for special values (eg: not-a-date-time) (default: English)
+   *  - selection of long, short strings, or numerical month representation (default: short string)
+   *  - month day year order (default yyyy-mmm-dd)
+   */
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const date& d)
+  {
+    typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+    typedef boost::date_time::ostream_date_formatter<date, facet_def, charT> greg_ostream_formatter;
+    greg_ostream_formatter::date_put(d, os);
+    return os;
+  }
+
+  //! operator<< for gregorian::greg_month typically streaming: Jan, Feb, Mar...
+  /*! Uses the date facet to determine output string as well as selection of long or short strings.
+   *  Default if no facet is installed is to output a 2 wide numeric value for the month
+   *  eg: 01 == Jan, 02 == Feb, ... 12 == Dec.
+   */
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const greg_month& m)
+  {
+    typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+    typedef boost::date_time::ostream_month_formatter<facet_def, charT> greg_month_formatter;
+    std::locale locale = os.getloc();
+    if (std::has_facet<facet_def>(locale)) {
+      const facet_def& f = std::use_facet<facet_def>(locale);
+      greg_month_formatter::format_month(m, os, f);
+
+    }
+    else { //default to numeric
+      charT fill_char = '0';
+      os  << std::setw(2) << std::setfill(fill_char) << m.as_number();
+    }
+
+    return os;
+  }
+
+  //! operator<< for gregorian::greg_weekday typically streaming: Sun, Mon, Tue, ...
+  /*! Uses the date facet to determine output string as well as selection of long or short string.
+   *  Default if no facet is installed is to output a 3 char english string for the
+   *  day of the week.
+   */
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const greg_weekday& wd)
+  {
+    typedef boost::date_time::date_names_put<greg_facet_config, charT> facet_def;
+    typedef boost::date_time::ostream_weekday_formatter<greg_weekday, facet_def, charT> greg_weekday_formatter;
+    std::locale locale = os.getloc();
+    if (std::has_facet<facet_def>(locale)) {
+      const facet_def& f = std::use_facet<facet_def>(locale);
+      greg_weekday_formatter::format_weekday(wd.as_enum(), os, f, true);
+    }
+    else { //default to short English string eg: Sun, Mon, Tue, Wed...
+      os  << wd.as_short_string();
+    }
+
+    return os;
+  }
+
+  //! operator<< for gregorian::date_period typical output: [2002-Jan-01/2002-Jan-31]
+  /*! Uses the date facet to determine output string as well as selection of long 
+   *  or short string fr dates.
+   *  Default if no facet is installed is to output a 3 char english string for the
+   *  day of the week.
+   */
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const date_period& dp)
+  {
+    os << '['; //TODO: facet or manipulator for periods?
+    os << dp.begin();
+    os << '/'; //TODO: facet or manipulator for periods?
+    os << dp.last();
+    os << ']'; 
+    return os;
+  }
+
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const date_duration& dd)
+  {
+    //os << dd.days();
+    os << dd.get_rep();
+    return os;
+  }
+
+  //! operator<< for gregorian::partial_date. Output: "Jan 1"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const partial_date& pd)
+  {
+    os << std::setw(2) << std::setfill('0') << pd.day() << ' ' 
+       << pd.month().as_short_string() ; 
+    return os;
+  }
+
+  //! operator<< for gregorian::nth_kday_of_month. Output: "first Mon of Jun"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, 
+             const nth_kday_of_month& nkd)
+  {
+    os << nkd.nth_week_as_str() << ' ' 
+       << nkd.day_of_week() << " of "
+       << nkd.month().as_short_string() ; 
+    return os;
+  }
+
+  //! operator<< for gregorian::first_kday_of_month. Output: "first Mon of Jun"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, 
+             const first_kday_of_month& fkd)
+  {
+    os << "first " << fkd.day_of_week() << " of " 
+       << fkd.month().as_short_string() ; 
+    return os;
+  }
+
+  //! operator<< for gregorian::last_kday_of_month. Output: "last Mon of Jun"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, 
+             const last_kday_of_month& lkd)
+  {
+    os << "last " << lkd.day_of_week() << " of " 
+       << lkd.month().as_short_string() ; 
+    return os;
+  }
+
+  //! operator<< for gregorian::first_kday_after. Output: "first Mon after"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, 
+             const first_kday_after& fka)
+  {
+    os << fka.day_of_week() << " after"; 
+    return os;
+  }
+
+  //! operator<< for gregorian::first_kday_before. Output: "first Mon before"
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, 
+             const first_kday_before& fkb)
+  {
+    os << fkb.day_of_week() << " before"; 
+    return os;
+  }
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+  /**************** Input Streaming ******************/
+  
+#if !defined(BOOST_NO_STD_ITERATOR_TRAITS)
+  //! operator>> for gregorian::date
+  template<class charT>
+  inline 
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, date& d)
+  {
+    std::istream_iterator<std::basic_string<charT>, charT> beg(is), eos;
+    
+    typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+    d = from_stream(beg, eos);
+    return is;
+  }
+#endif // BOOST_NO_STD_ITERATOR_TRAITS
+
+  //! operator>> for gregorian::date_duration
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, 
+                                        date_duration& dd)
+  {
+    long v;
+    is >> v;
+    dd = date_duration(v);
+    return is;
+  }
+
+  //! operator>> for gregorian::date_period
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,
+                                        date_period& dp)
+  {
+    std::basic_string<charT> s;
+    is >> s;
+    dp = date_time::from_simple_string_type<date>(s);
+    return is;
+  }
+
+  //! generates a locale with the set of gregorian name-strings of type char*
+  BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, char type);
+
+  //! Returns a pointer to a facet with a default set of names (English)
+  /* Necessary in the event an exception is thrown from op>> for 
+   * weekday or month. See comments in those functions for more info */
+  BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, char>* create_facet_def(char type);
+
+#ifndef BOOST_NO_STD_WSTRING
+  //! generates a locale with the set of gregorian name-strings of type wchar_t*
+  BOOST_DATE_TIME_DECL std::locale generate_locale(std::locale& loc, wchar_t type);
+  //! Returns a pointer to a facet with a default set of names (English)
+  /* Necessary in the event an exception is thrown from op>> for 
+   * weekday or month. See comments in those functions for more info */
+  BOOST_DATE_TIME_DECL boost::date_time::all_date_names_put<greg_facet_config, wchar_t>* create_facet_def(wchar_t type);
+#endif // BOOST_NO_STD_WSTRING
+
+  //! operator>> for gregorian::greg_month - throws exception if invalid month given
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_month& m) 
+  {
+    typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+
+    std::basic_string<charT> s;
+    is >> s;
+    
+    if(!std::has_facet<facet_def>(is.getloc())) {
+      std::locale loc = is.getloc();
+      charT a = '\0';
+      is.imbue(generate_locale(loc, a));
+    }
+
+    short num = 0;
+
+    try{
+      const facet_def& f = std::use_facet<facet_def>(is.getloc());
+      num = date_time::find_match(f.get_short_month_names(), 
+                                  f.get_long_month_names(), 
+                                  (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
+                                                           // which is needed by find_match
+    }
+    /* bad_cast will be thrown if the desired facet is not accessible
+     * so we can generate the facet. This has the drawback of using english
+     * names as a default. */
+    catch(std::bad_cast&){
+      charT a = '\0';
+      std::auto_ptr< const facet_def > f(create_facet_def(a));
+      num = date_time::find_match(f->get_short_month_names(), 
+                                  f->get_long_month_names(), 
+                                  (greg_month::max)(), s); // greg_month spans 1..12, so max returns the array size,
+                                                           // which is needed by find_match
+    }
+    
+    ++num; // months numbered 1-12
+    m = greg_month(num); 
+
+    return is;
+  }
+
+  //! operator>> for gregorian::greg_weekday  - throws exception if invalid weekday given
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is,greg_weekday& wd) 
+  {
+    typedef boost::date_time::all_date_names_put<greg_facet_config, charT> facet_def;
+
+    std::basic_string<charT> s;
+    is >> s;
+
+    if(!std::has_facet<facet_def>(is.getloc())) {
+      std::locale loc = is.getloc();
+      charT a = '\0';
+      is.imbue(generate_locale(loc, a));
+    }
+
+    short num = 0;
+    try{
+      const facet_def& f = std::use_facet<facet_def>(is.getloc());
+      num = date_time::find_match(f.get_short_weekday_names(), 
+                                  f.get_long_weekday_names(), 
+                                  (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
+                                                                 // to form the array size which is needed by find_match
+    }
+    /* bad_cast will be thrown if the desired facet is not accessible
+     * so we can generate the facet. This has the drawback of using english
+     * names as a default. */
+    catch(std::bad_cast&){
+      charT a = '\0';
+      std::auto_ptr< const facet_def > f(create_facet_def(a));
+      num = date_time::find_match(f->get_short_weekday_names(), 
+                                  f->get_long_weekday_names(), 
+                                  (greg_weekday::max)() + 1, s); // greg_weekday spans 0..6, so increment is needed
+                                                                 // to form the array size which is needed by find_match
+    }
+   
+    wd = greg_weekday(num); // weekdays numbered 0-6
+    return is;
+  }
+
+} } //namespace gregorian
+
+#endif  
+    
+    
+#endif
+

+ 105 - 0
ext/boost/date_time/gregorian/greg_month.hpp

@@ -0,0 +1,105 @@
+#ifndef GREG_MONTH_HPP___
+#define GREG_MONTH_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/shared_ptr.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <stdexcept>
+#include <string>
+#include <map>
+#include <algorithm>
+#include <cctype>
+
+namespace boost {
+namespace gregorian {
+
+  typedef date_time::months_of_year months_of_year;
+
+  //bring enum values into the namespace
+  using date_time::Jan;
+  using date_time::Feb;
+  using date_time::Mar;
+  using date_time::Apr;
+  using date_time::May;
+  using date_time::Jun;
+  using date_time::Jul;
+  using date_time::Aug;
+  using date_time::Sep;
+  using date_time::Oct;
+  using date_time::Nov;
+  using date_time::Dec;
+  using date_time::NotAMonth;
+  using date_time::NumMonths;
+  
+  //! Exception thrown if a greg_month is constructed with a value out of range
+  struct bad_month : public std::out_of_range
+  {
+    bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {}
+  };
+  //! Build a policy class for the greg_month_rep
+  typedef CV::simple_exception_policy<unsigned short, 1, 12, bad_month> greg_month_policies;
+  //! A constrained range that implements the gregorian_month rules
+  typedef CV::constrained_value<greg_month_policies> greg_month_rep;
+
+  
+  //! Wrapper class to represent months in gregorian based calendar
+  class BOOST_DATE_TIME_DECL greg_month : public greg_month_rep {
+  public:
+    typedef date_time::months_of_year month_enum;
+    typedef std::map<std::string, unsigned short> month_map_type;
+    typedef boost::shared_ptr<month_map_type> month_map_ptr_type;
+    //! Construct a month from the months_of_year enumeration
+    greg_month(month_enum theMonth) : 
+      greg_month_rep(static_cast<greg_month_rep::value_type>(theMonth)) {}
+    //! Construct from a short value
+    greg_month(unsigned short theMonth) : greg_month_rep(theMonth) {}
+    //! Convert the value back to a short
+    operator unsigned short()  const {return value_;}
+    //! Returns month as number from 1 to 12
+    unsigned short as_number() const {return value_;}
+    month_enum as_enum() const {return static_cast<month_enum>(value_);}
+    const char* as_short_string() const;
+    const char* as_long_string()  const;
+#ifndef BOOST_NO_STD_WSTRING
+    const wchar_t* as_short_wstring() const;
+    const wchar_t* as_long_wstring()  const;
+#endif // BOOST_NO_STD_WSTRING
+    //! Shared pointer to a map of Month strings (Names & Abbrev) & numbers
+    static month_map_ptr_type get_month_map_ptr();
+
+    /* parameterized as_*_string functions are intended to be called
+     * from a template function: "... as_short_string(charT c='\0');" */
+    const char* as_short_string(char) const
+    {
+      return as_short_string();
+    }
+    const char* as_long_string(char) const
+    {
+      return as_long_string();
+    }
+#ifndef BOOST_NO_STD_WSTRING
+    const wchar_t* as_short_string(wchar_t) const
+    {
+      return as_short_wstring();
+    }
+    const wchar_t* as_long_string(wchar_t) const
+    {
+      return as_long_wstring();
+    }
+#endif // BOOST_NO_STD_WSTRING
+  };
+
+} } //namespace gregorian
+
+
+
+#endif

+ 489 - 0
ext/boost/date_time/gregorian/greg_serialize.hpp

@@ -0,0 +1,489 @@
+#ifndef GREGORIAN_SERIALIZE_HPP___
+#define GREGORIAN_SERIALIZE_HPP___
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/gregorian/parsers.hpp"
+#include "boost/serialization/split_free.hpp"
+
+  
+// macros to split serialize functions into save & load functions
+// An expanded version is below for gregorian::date
+// NOTE: these macros define template functions in the boost::serialization namespace.
+// They must be expanded *outside* of any namespace
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_duration::duration_rep)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::date_period)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_day)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::greg_weekday)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::partial_date)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::nth_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::last_kday_of_month)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_before)
+BOOST_SERIALIZATION_SPLIT_FREE(::boost::gregorian::first_kday_after)
+
+namespace boost {
+namespace serialization {
+
+/*! Method that does serialization for gregorian::date -- splits to load/save
+ */
+template<class Archive>                         
+inline void serialize(Archive & ar,                               
+                      ::boost::gregorian::date & d,
+                      const unsigned int file_version)
+{
+  split_free(ar, d, file_version);              
+}                                               
+
+//! Function to save gregorian::date objects using serialization lib
+/*! Dates are serialized into a string for transport and storage. 
+ *  While it would be more efficient to store the internal
+ *  integer used to manipulate the dates, it is an unstable solution.  
+ */
+template<class Archive>
+void save(Archive & ar, 
+          const ::boost::gregorian::date & d, 
+          unsigned int /* version */)
+{
+  std::string ds = to_iso_string(d);
+  ar & make_nvp("date", ds);
+}
+
+//! Function to load gregorian::date objects using serialization lib
+/*! Dates are serialized into a string for transport and storage. 
+ *  While it would be more efficient to store the internal
+ *  integer used to manipulate the dates, it is an unstable solution.  
+ */
+template<class Archive>
+void load(Archive & ar, 
+          ::boost::gregorian::date & d, 
+          unsigned int /*version*/)
+{
+  std::string ds;
+  ar & make_nvp("date", ds);
+  try{
+    d = ::boost::gregorian::from_undelimited_string(ds);
+  }catch(bad_lexical_cast&) {
+    gregorian::special_values sv = gregorian::special_value_from_string(ds);
+    if(sv == gregorian::not_special) {
+      throw; // no match found, rethrow original exception
+    }
+    else {
+      d = gregorian::date(sv);
+    }
+  }
+}
+
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                ::boost::gregorian::date* dp, 
+                                const unsigned int /*file_version*/)
+{
+  // retrieve data from archive required to construct new 
+  // invoke inplace constructor to initialize instance of date
+  ::new(dp) ::boost::gregorian::date(::boost::gregorian::not_a_date_time);
+}
+
+/**** date_duration ****/
+
+//! Function to save gregorian::date_duration objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::date_duration & dd, 
+          unsigned int /*version*/)
+{
+  typename gregorian::date_duration::duration_rep dr = dd.get_rep();
+  ar & make_nvp("date_duration", dr);
+}
+//! Function to load gregorian::date_duration objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::date_duration & dd, unsigned int /*version*/)
+{
+  typename gregorian::date_duration::duration_rep dr(0);
+  ar & make_nvp("date_duration", dr);
+  dd = gregorian::date_duration(dr);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_duration* dd, 
+                                const unsigned int /*file_version*/)
+{
+  ::new(dd) gregorian::date_duration(gregorian::not_a_date_time);
+}
+
+/**** date_duration::duration_rep (most likely int_adapter) ****/
+
+//! helper unction to save date_duration objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::date_duration::duration_rep & dr, 
+          unsigned int /*version*/)
+{
+  typename gregorian::date_duration::duration_rep::int_type it = dr.as_number();
+  ar & make_nvp("date_duration_duration_rep", it);
+}
+//! helper function to load date_duration objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::date_duration::duration_rep & dr, unsigned int /*version*/)
+{
+  typename gregorian::date_duration::duration_rep::int_type it(0);
+  ar & make_nvp("date_duration_duration_rep", it);
+  dr = gregorian::date_duration::duration_rep::int_type(it);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_duration::duration_rep* dr, 
+                                const unsigned int /*file_version*/)
+{
+  ::new(dr) gregorian::date_duration::duration_rep(0);
+}
+
+/**** date_period ****/
+
+//! Function to save gregorian::date_period objects using serialization lib
+/*! date_period objects are broken down into 2 parts for serialization:
+ * the begining date object and the end date object
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::date_period& dp, 
+          unsigned int /*version*/)
+{
+  gregorian::date d1 = dp.begin();
+  gregorian::date d2 = dp.end();
+  ar & make_nvp("date_period_begin_date", d1);
+  ar & make_nvp("date_period_end_date", d2);
+}
+//! Function to load gregorian::date_period objects using serialization lib
+/*! date_period objects are broken down into 2 parts for serialization:
+ * the begining date object and the end date object
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::date_period& dp, unsigned int /*version*/)
+{
+  gregorian::date d1(gregorian::not_a_date_time);
+  gregorian::date d2(gregorian::not_a_date_time);
+  ar & make_nvp("date_period_begin_date", d1);
+  ar & make_nvp("date_period_end_date", d2);
+  dp = gregorian::date_period(d1,d2);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::date_period* dp, 
+                                const unsigned int /*file_version*/)
+{
+  gregorian::date d(gregorian::not_a_date_time);
+  gregorian::date_duration dd(1);
+  ::new(dp) gregorian::date_period(d,dd);
+}
+
+/**** greg_month ****/
+
+//! Function to save gregorian::greg_month objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_month& gm, 
+          unsigned int /*version*/)
+{
+  unsigned short us = gm.as_number();
+  ar & make_nvp("greg_month", us);
+}
+//! Function to load gregorian::greg_month objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_month& gm, unsigned int /*version*/)
+{
+  unsigned short us;
+  ar & make_nvp("greg_month", us);
+  gm = gregorian::greg_month(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_month* gm, 
+                                const unsigned int /*file_version*/)
+{
+  ::new(gm) gregorian::greg_month(1);
+}
+
+/**** greg_day ****/
+
+//! Function to save gregorian::greg_day objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_day& gd, 
+          unsigned int /*version*/)
+{
+  unsigned short us = gd.as_number();
+  ar & make_nvp("greg_day", us);
+}
+//! Function to load gregorian::greg_day objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_day& gd, unsigned int /*version*/)
+{
+  unsigned short us;
+  ar & make_nvp("greg_day", us);
+  gd = gregorian::greg_day(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_day* gd, 
+                                const unsigned int /*file_version*/)
+{
+  ::new(gd) gregorian::greg_day(1);
+}
+
+/**** greg_weekday ****/
+
+//! Function to save gregorian::greg_weekday objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::greg_weekday& gd, 
+          unsigned int /*version*/)
+{
+  unsigned short us = gd.as_number();
+  ar & make_nvp("greg_weekday", us);
+}
+//! Function to load gregorian::greg_weekday objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::greg_weekday& gd, unsigned int /*version*/)
+{
+  unsigned short us;
+  ar & make_nvp("greg_weekday", us);
+  gd = gregorian::greg_weekday(us);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::greg_weekday* gd, 
+                                const unsigned int /*file_version*/)
+{
+  ::new(gd) gregorian::greg_weekday(1);
+}
+
+/**** date_generators ****/
+
+/**** partial_date ****/
+
+//! Function to save gregorian::partial_date objects using serialization lib
+/*! partial_date objects are broken down into 2 parts for serialization:
+ * the day (typically greg_day) and month (typically greg_month) objects
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::partial_date& pd, 
+          unsigned int /*version*/)
+{
+  gregorian::greg_day gd(pd.day());
+  gregorian::greg_month gm(pd.month().as_number());
+  ar & make_nvp("partial_date_day", gd);
+  ar & make_nvp("partial_date_month", gm);
+}
+//! Function to load gregorian::partial_date objects using serialization lib
+/*! partial_date objects are broken down into 2 parts for serialization:
+ * the day (greg_day) and month (greg_month) objects
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::partial_date& pd, unsigned int /*version*/)
+{
+  gregorian::greg_day gd(1);
+  gregorian::greg_month gm(1);
+  ar & make_nvp("partial_date_day", gd);
+  ar & make_nvp("partial_date_month", gm);
+  pd = gregorian::partial_date(gd,gm);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, gregorian::partial_date* pd, 
+                                const unsigned int /*file_version*/)
+{
+  gregorian::greg_month gm(1);
+  gregorian::greg_day gd(1);
+  ::new(pd) gregorian::partial_date(gd,gm);
+}
+
+/**** nth_kday_of_month ****/
+
+//! Function to save nth_day_of_the_week_in_month objects using serialization lib
+/*! nth_day_of_the_week_in_month  objects are broken down into 3 parts for 
+ * serialization: the week number, the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::nth_kday_of_month& nkd, 
+          unsigned int /*version*/)
+{
+  typename gregorian::nth_kday_of_month::week_num wn(nkd.nth_week());
+  typename gregorian::nth_kday_of_month::day_of_week_type d(nkd.day_of_week().as_number());
+  typename gregorian::nth_kday_of_month::month_type m(nkd.month().as_number());
+  ar & make_nvp("nth_kday_of_month_week_num", wn);
+  ar & make_nvp("nth_kday_of_month_day_of_week", d);
+  ar & make_nvp("nth_kday_of_month_month", m);
+}
+//! Function to load nth_day_of_the_week_in_month objects using serialization lib
+/*! nth_day_of_the_week_in_month  objects are broken down into 3 parts for 
+ * serialization: the week number, the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::nth_kday_of_month& nkd, unsigned int /*version*/)
+{
+  typename gregorian::nth_kday_of_month::week_num wn(gregorian::nth_kday_of_month::first);
+  typename gregorian::nth_kday_of_month::day_of_week_type d(gregorian::Monday);
+  typename gregorian::nth_kday_of_month::month_type m(gregorian::Jan);
+  ar & make_nvp("nth_kday_of_month_week_num", wn);
+  ar & make_nvp("nth_kday_of_month_day_of_week", d);
+  ar & make_nvp("nth_kday_of_month_month", m);
+  
+  nkd = gregorian::nth_kday_of_month(wn,d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                gregorian::nth_kday_of_month* nkd, 
+                                const unsigned int /*file_version*/)
+{
+  // values used are not significant
+  ::new(nkd) gregorian::nth_kday_of_month(gregorian::nth_kday_of_month::first,
+                                         gregorian::Monday,gregorian::Jan);
+}
+
+/**** first_kday_of_month ****/
+
+//! Function to save first_day_of_the_week_in_month objects using serialization lib
+/*! first_day_of_the_week_in_month objects are broken down into 2 parts for 
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_of_month& fkd, 
+          unsigned int /*version*/)
+{
+  typename gregorian::first_kday_of_month::day_of_week_type d(fkd.day_of_week().as_number());
+  typename gregorian::first_kday_of_month::month_type m(fkd.month().as_number());
+  ar & make_nvp("first_kday_of_month_day_of_week", d);
+  ar & make_nvp("first_kday_of_month_month", m);
+}
+//! Function to load first_day_of_the_week_in_month objects using serialization lib
+/*! first_day_of_the_week_in_month objects are broken down into 2 parts for 
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_of_month& fkd, unsigned int /*version*/)
+{
+  typename gregorian::first_kday_of_month::day_of_week_type d(gregorian::Monday);
+  typename gregorian::first_kday_of_month::month_type m(gregorian::Jan);
+  ar & make_nvp("first_kday_of_month_day_of_week", d);
+  ar & make_nvp("first_kday_of_month_month", m);
+  
+  fkd = gregorian::first_kday_of_month(d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                gregorian::first_kday_of_month* fkd, 
+                                const unsigned int /*file_version*/)
+{
+  // values used are not significant
+  ::new(fkd) gregorian::first_kday_of_month(gregorian::Monday,gregorian::Jan);
+}
+
+/**** last_kday_of_month ****/
+
+//! Function to save last_day_of_the_week_in_month objects using serialization lib
+/*! last_day_of_the_week_in_month objects are broken down into 2 parts for 
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void save(Archive & ar, const gregorian::last_kday_of_month& lkd, 
+          unsigned int /*version*/)
+{
+  typename gregorian::last_kday_of_month::day_of_week_type d(lkd.day_of_week().as_number());
+  typename gregorian::last_kday_of_month::month_type m(lkd.month().as_number());
+  ar & make_nvp("last_kday_of_month_day_of_week", d);
+  ar & make_nvp("last_kday_of_month_month", m);
+}
+//! Function to load last_day_of_the_week_in_month objects using serialization lib
+/*! last_day_of_the_week_in_month objects are broken down into 2 parts for 
+ * serialization: the day of the week, and the month
+ */
+template<class Archive>
+void load(Archive & ar, gregorian::last_kday_of_month& lkd, unsigned int /*version*/)
+{
+  typename gregorian::last_kday_of_month::day_of_week_type d(gregorian::Monday);
+  typename gregorian::last_kday_of_month::month_type m(gregorian::Jan);
+  ar & make_nvp("last_kday_of_month_day_of_week", d);
+  ar & make_nvp("last_kday_of_month_month", m);
+  
+  lkd = gregorian::last_kday_of_month(d,m);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                gregorian::last_kday_of_month* lkd, 
+                                const unsigned int /*file_version*/)
+{
+  // values used are not significant
+  ::new(lkd) gregorian::last_kday_of_month(gregorian::Monday,gregorian::Jan);
+}
+
+/**** first_kday_before ****/
+
+//! Function to save first_day_of_the_week_before objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_before& fkdb, 
+          unsigned int /*version*/)
+{
+  typename gregorian::first_kday_before::day_of_week_type d(fkdb.day_of_week().as_number());
+  ar & make_nvp("first_kday_before_day_of_week", d);
+}
+//! Function to load first_day_of_the_week_before objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_before& fkdb, unsigned int /*version*/)
+{
+  typename gregorian::first_kday_before::day_of_week_type d(gregorian::Monday);
+  ar & make_nvp("first_kday_before_day_of_week", d);
+  
+  fkdb = gregorian::first_kday_before(d);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                gregorian::first_kday_before* fkdb, 
+                                const unsigned int /*file_version*/)
+{
+  // values used are not significant
+  ::new(fkdb) gregorian::first_kday_before(gregorian::Monday);
+}
+
+/**** first_kday_after ****/
+
+//! Function to save first_day_of_the_week_after objects using serialization lib
+template<class Archive>
+void save(Archive & ar, const gregorian::first_kday_after& fkda, 
+          unsigned int /*version*/)
+{
+  typename gregorian::first_kday_after::day_of_week_type d(fkda.day_of_week().as_number());
+  ar & make_nvp("first_kday_after_day_of_week", d);
+}
+//! Function to load first_day_of_the_week_after objects using serialization lib
+template<class Archive>
+void load(Archive & ar, gregorian::first_kday_after& fkda, unsigned int /*version*/)
+{
+  typename gregorian::first_kday_after::day_of_week_type d(gregorian::Monday);
+  ar & make_nvp("first_kday_after_day_of_week", d);
+  
+  fkda = gregorian::first_kday_after(d);
+}
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                gregorian::first_kday_after* fkda, 
+                                const unsigned int /*file_version*/)
+{
+  // values used are not significant
+  ::new(fkda) gregorian::first_kday_after(gregorian::Monday);
+}
+
+} // namespace serialization
+} // namespace boost
+
+#endif

+ 66 - 0
ext/boost/date_time/gregorian/greg_weekday.hpp

@@ -0,0 +1,66 @@
+#ifndef GREG_WEEKDAY_HPP___
+#define GREG_WEEKDAY_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include "boost/date_time/date_defs.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+  //bring enum values into the namespace
+  using date_time::Sunday;
+  using date_time::Monday;
+  using date_time::Tuesday;
+  using date_time::Wednesday;
+  using date_time::Thursday;
+  using date_time::Friday;
+  using date_time::Saturday;
+
+
+  //! Exception that flags that a weekday number is incorrect
+  struct bad_weekday : public std::out_of_range
+  {
+    bad_weekday() : std::out_of_range(std::string("Weekday is out of range 0..6")) {}
+  };
+  typedef CV::simple_exception_policy<unsigned short, 0, 6, bad_weekday> greg_weekday_policies;
+  typedef CV::constrained_value<greg_weekday_policies> greg_weekday_rep;
+
+
+  //! Represent a day within a week (range 0==Sun to 6==Sat)
+  class BOOST_DATE_TIME_DECL greg_weekday : public greg_weekday_rep {
+  public:
+    typedef boost::date_time::weekdays weekday_enum;
+    greg_weekday(unsigned short day_of_week_num) :
+      greg_weekday_rep(day_of_week_num)
+    {}
+
+    unsigned short as_number() const {return value_;}
+    const char* as_short_string() const;
+    const char* as_long_string()  const;
+#ifndef BOOST_NO_STD_WSTRING
+    const wchar_t* as_short_wstring() const;
+    const wchar_t* as_long_wstring()  const;
+#endif // BOOST_NO_STD_WSTRING
+    weekday_enum as_enum() const {return static_cast<weekday_enum>(value_);}
+
+
+  };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif

+ 53 - 0
ext/boost/date_time/gregorian/greg_year.hpp

@@ -0,0 +1,53 @@
+#ifndef GREG_YEAR_HPP___
+#define GREG_YEAR_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/constrained_value.hpp"
+#include <stdexcept>
+#include <string>
+
+namespace boost {
+namespace gregorian {
+
+  //! Exception type for gregorian year
+  struct bad_year : public std::out_of_range
+  {
+    bad_year() : 
+      std::out_of_range(std::string("Year is out of valid range: 1400..10000")) 
+    {}
+  };
+  //! Policy class that declares error handling gregorian year type
+  typedef CV::simple_exception_policy<unsigned short, 1400, 10000, bad_year> greg_year_policies;
+
+  //! Generated representation for gregorian year
+  typedef CV::constrained_value<greg_year_policies> greg_year_rep;
+
+  //! Represent a day of the month (range 1900 - 10000) 
+  /*! This small class allows for simple conversion an integer value into
+      a year for the gregorian calendar.  This currently only allows a
+      range of 1900 to 10000.  Both ends of the range are a bit arbitrary
+      at the moment, but they are the limits of current testing of the 
+      library.  As such they may be increased in the future.
+  */
+  class greg_year : public greg_year_rep {
+  public:
+    greg_year(unsigned short year) : greg_year_rep(year) {}
+    operator unsigned short()  const {return value_;}
+  private:
+    
+  };
+
+
+
+} } //namespace gregorian
+
+
+
+#endif

+ 33 - 0
ext/boost/date_time/gregorian/greg_ymd.hpp

@@ -0,0 +1,33 @@
+#ifndef DATE_TIME_GREG_YMD_HPP__
+#define DATE_TIME_GREG_YMD_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/year_month_day.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/gregorian/greg_day.hpp"
+#include "boost/date_time/gregorian/greg_year.hpp"
+#include "boost/date_time/gregorian/greg_month.hpp"
+
+namespace boost {
+namespace gregorian {
+  
+  typedef date_time::year_month_day_base<greg_year, 
+                                         greg_month, 
+                                         greg_day> greg_year_month_day;
+  
+  
+  
+} } //namespace gregorian
+
+
+
+
+#endif
+  

+ 38 - 0
ext/boost/date_time/gregorian/gregorian.hpp

@@ -0,0 +1,38 @@
+#ifndef GREGORIAN_HPP__
+#define GREGORIAN_HPP__
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file gregorian.hpp
+  Single file header that provides overall include for all elements of 
+  the gregorian date-time system.  This includes the various types 
+  defined, but also other functions for formatting and parsing.
+*/
+
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/gregorian/conversion.hpp"
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/gregorian/formatters_limited.hpp"
+#else
+#include "boost/date_time/gregorian/formatters.hpp"
+#endif
+
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/gregorian/greg_facet.hpp"
+#else
+#include "boost/date_time/gregorian/gregorian_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+
+#include "boost/date_time/gregorian/parsers.hpp"
+
+
+
+#endif

+ 784 - 0
ext/boost/date_time/gregorian/gregorian_io.hpp

@@ -0,0 +1,784 @@
+#ifndef DATE_TIME_GREGORIAN_IO_HPP__
+#define DATE_TIME_GREGORIAN_IO_HPP__
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/date_facet.hpp>
+#include <boost/date_time/period_parser.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/special_values_parser.hpp>
+#include <boost/date_time/special_values_formatter.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/gregorian/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace gregorian {
+
+
+  typedef boost::date_time::period_formatter<wchar_t> wperiod_formatter;
+  typedef boost::date_time::period_formatter<char>    period_formatter;
+  
+  typedef boost::date_time::date_facet<date,wchar_t> wdate_facet;
+  typedef boost::date_time::date_facet<date,char>    date_facet;
+
+  typedef boost::date_time::period_parser<date,char>       period_parser;
+  typedef boost::date_time::period_parser<date,wchar_t>    wperiod_parser;
+    
+  typedef boost::date_time::special_values_formatter<char> special_values_formatter; 
+  typedef boost::date_time::special_values_formatter<wchar_t> wspecial_values_formatter; 
+  
+  typedef boost::date_time::special_values_parser<date,char> special_values_parser; 
+  typedef boost::date_time::special_values_parser<date,wchar_t> wspecial_values_parser; 
+  
+  typedef boost::date_time::date_input_facet<date,char>    date_input_facet;
+  typedef boost::date_time::date_input_facet<date,wchar_t> wdate_input_facet;
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date& d) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), d);
+    else {
+      //instantiate a custom facet for dealing with dates since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every date
+      //if the locale did not already exist.  Of course this will be overridden
+      //if the user imbues at some later point.  With the default settings
+      //for the facet the resulting format will be the same as the
+      //std::time_facet settings.
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), d);
+    }
+    return os;
+  }
+
+  //! input operator for date
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, date& d)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+        
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, d);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, d);
+        }
+      }
+      catch(...) { 
+        // mask tells us what exceptions are turned on
+        std::ios_base::iostate exception_mask = is.exceptions();
+        // if the user wants exceptions on failbit, we'll rethrow our 
+        // date_time exception & set the failbit
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {} // ignore this one
+          throw; // rethrow original exception
+        }
+        else {
+          // if the user want's to fail quietly, we simply set the failbit
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }    
+    return is;
+  }
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_duration& dd) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dd);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), dd);
+
+    }
+    return os;
+  }
+
+  //! input operator for date_duration
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, date_duration& dd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+        
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, dd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::date_period& dp) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), dp);
+    else {
+      //instantiate a custom facet for dealing with date periods since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every time period
+      //if the local did not already exist.  Of course this will be overridden
+      //if the user imbues at some later point.  With the default settings
+      //for the facet the resulting format will be the same as the
+      //std::time_facet settings.
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), dp);
+
+    }
+    return os;
+  }
+
+  //! input operator for date_period 
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, date_period& dp)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, dp);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, dp);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  /********** small gregorian types **********/
+  
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_month& gm) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gm);
+    else {
+      custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...)
+      //custom_date_facet* f = new custom_date_facet("%B");
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), gm);
+    }
+    return os;
+  }
+
+  //! input operator for greg_month
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, greg_month& m)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, m);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, m);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::greg_weekday& gw) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), gw);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), gw);
+    }
+    return os;
+  }
+ 
+  //! input operator for greg_weekday
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, greg_weekday& wd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, wd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, wd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  //NOTE: output operator for greg_day was not necessary
+
+  //! input operator for greg_day
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, greg_day& gd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, gd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  //NOTE: output operator for greg_year was not necessary
+
+  //! input operator for greg_year
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, greg_year& gy)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, gy);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, gy);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  /********** date generator types **********/
+  
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::partial_date& pd) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), pd);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), pd);
+    }
+    return os;
+  }
+
+  //! input operator for partial_date
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, partial_date& pd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, pd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, pd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), nkd);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), nkd);
+    }
+    return os;
+  }
+
+  //! input operator for nth_day_of_the_week_in_month
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, 
+             nth_day_of_the_week_in_month& nday)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, nday);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, nday);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fkd);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), fkd);
+    }
+    return os;
+  }
+
+  //! input operator for first_day_of_the_week_in_month
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, 
+             first_day_of_the_week_in_month& fkd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, fkd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc()))
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), lkd);
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), lkd);
+    }
+    return os;
+  }
+
+  //! input operator for last_day_of_the_week_in_month
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, 
+             last_day_of_the_week_in_month& lkd)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, lkd);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, lkd);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_after& fda) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc())) {
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fda);
+    } 
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), fda);
+    }
+    return os;
+  }
+
+  //! input operator for first_day_of_the_week_after
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, 
+             first_day_of_the_week_after& fka)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fka);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, fka);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const boost::gregorian::first_day_of_the_week_before& fdb) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::date_facet<date, CharT> custom_date_facet;
+    std::ostreambuf_iterator<CharT> output_itr(os);
+    if (std::has_facet<custom_date_facet>(os.getloc())) {
+      std::use_facet<custom_date_facet>(os.getloc()).put(output_itr, os, os.fill(), fdb);
+    }
+    else {
+      custom_date_facet* f = new custom_date_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(output_itr, os, os.fill(), fdb);
+    }
+    return os;
+  }
+
+  //! input operator for first_day_of_the_week_before
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, 
+             first_day_of_the_week_before& fkb)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false); 
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::date_input_facet<date, CharT> date_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<date_input_facet>(is.getloc())) {
+          std::use_facet<date_input_facet>(is.getloc()).get(sit, str_end, is, fkb);
+        }
+        else {
+          date_input_facet* f = new date_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, fkb);
+        }
+      }
+      catch(...) { 
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); } 
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit); 
+        } 
+            
+      }
+    }
+    return is;
+  }
+
+  
+} } // namespaces
+
+#endif // DATE_TIME_GREGORIAN_IO_HPP__

+ 109 - 0
ext/boost/date_time/gregorian/gregorian_types.hpp

@@ -0,0 +1,109 @@
+#ifndef _GREGORIAN_TYPES_HPP__
+#define _GREGORIAN_TYPES_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file gregorian_types.hpp
+  Single file header that defines most of the types for the gregorian 
+  date-time system.
+*/
+
+#include "boost/date_time/date.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/gregorian/greg_calendar.hpp"
+#include "boost/date_time/gregorian/greg_duration.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#endif
+#include "boost/date_time/gregorian/greg_date.hpp"
+#include "boost/date_time/date_generators.hpp"
+#include "boost/date_time/date_clock_device.hpp"
+#include "boost/date_time/date_iterator.hpp"
+#include "boost/date_time/adjust_functors.hpp"
+
+namespace boost {
+
+//! Gregorian date system based on date_time components
+/*! This date system defines a full complement of types including
+ *  a date, date_duration, date_period, day_clock, and a
+ *  day_iterator.
+ */
+namespace gregorian {
+  //! Date periods for the gregorian system
+  /*!\ingroup date_basics
+   */
+  typedef date_time::period<date, date_duration> date_period;  
+
+  //! A unifying date_generator base type
+  /*! A unifying date_generator base type for: 
+   * partial_date, nth_day_of_the_week_in_month,
+   * first_day_of_the_week_in_month, and last_day_of_the_week_in_month
+   */
+  typedef date_time::year_based_generator<date> year_based_generator;
+
+  //! A date generation object type
+  typedef date_time::partial_date<date> partial_date;
+
+  typedef date_time::nth_kday_of_month<date> nth_kday_of_month;
+  typedef nth_kday_of_month nth_day_of_the_week_in_month;
+
+  typedef date_time::first_kday_of_month<date> first_kday_of_month;
+  typedef first_kday_of_month first_day_of_the_week_in_month;
+
+  typedef date_time::last_kday_of_month<date> last_kday_of_month;
+  typedef last_kday_of_month last_day_of_the_week_in_month;
+
+  typedef date_time::first_kday_after<date> first_kday_after;
+  typedef first_kday_after first_day_of_the_week_after;
+
+  typedef date_time::first_kday_before<date> first_kday_before;
+  typedef first_kday_before first_day_of_the_week_before;
+
+  //! A clock to get the current day from the local computer
+  /*!\ingroup date_basics
+   */
+  typedef date_time::day_clock<date> day_clock;
+
+  //! Base date_iterator type for gregorian types.
+  /*!\ingroup date_basics
+   */
+  typedef date_time::date_itr_base<date> date_iterator;
+
+  //! A day level iterator
+  /*!\ingroup date_basics
+   */
+  typedef date_time::date_itr<date_time::day_functor<date>,
+                              date> day_iterator;
+  //! A week level iterator
+  /*!\ingroup date_basics
+   */
+  typedef date_time::date_itr<date_time::week_functor<date>,
+                              date> week_iterator;
+  //! A month level iterator
+  /*!\ingroup date_basics
+   */
+  typedef date_time::date_itr<date_time::month_functor<date>,
+                              date> month_iterator;
+  //! A year level iterator
+  /*!\ingroup date_basics
+   */
+  typedef date_time::date_itr<date_time::year_functor<date>,
+                              date> year_iterator;
+
+  // bring in these date_generator functions from date_time namespace
+  using date_time::days_until_weekday;
+  using date_time::days_before_weekday;
+  using date_time::next_weekday;
+  using date_time::previous_weekday;
+
+} } //namespace gregorian
+
+
+
+#endif

+ 91 - 0
ext/boost/date_time/gregorian/parsers.hpp

@@ -0,0 +1,91 @@
+#ifndef GREGORIAN_PARSERS_HPP___
+#define GREGORIAN_PARSERS_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/date_parsing.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/parse_format_base.hpp"
+#include <string>
+#include <sstream>
+
+namespace boost {
+namespace gregorian {
+
+  //! Return special_value from string argument
+  /*! Return special_value from string argument. If argument is 
+   * not one of the special value names (defined in src/gregorian/names.hpp), 
+   * return 'not_special' */
+  BOOST_DATE_TIME_DECL special_values special_value_from_string(const std::string& s);
+
+  //! Deprecated: Use from_simple_string
+  inline date from_string(std::string s) {
+    return date_time::parse_date<date>(s);
+  }
+
+  //! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted)
+  inline date from_simple_string(std::string s) {
+    return date_time::parse_date<date>(s, date_time::ymd_order_iso);
+  }
+  
+  //! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted)
+  inline date from_us_string(std::string s) {
+    return date_time::parse_date<date>(s, date_time::ymd_order_us);
+  }
+  
+  //! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted)
+  inline date from_uk_string(std::string s) {
+    return date_time::parse_date<date>(s, date_time::ymd_order_dmy);
+  }
+  
+  //! From iso type date string where with order year-month-day eg: 20020125
+  inline date from_undelimited_string(std::string s) {
+    return date_time::parse_undelimited_date<date>(s);
+  }
+
+  //! From iso type date string where with order year-month-day eg: 20020125
+  inline date date_from_iso_string(const std::string& s) {
+    return date_time::parse_undelimited_date<date>(s);
+  }
+
+#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS))
+  //! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted
+  /* Arguments passed in by-value for convertability of char[] 
+   * to iterator_type. Calls to from_stream_type are by-reference 
+   * since conversion is already done */
+  template<class iterator_type>
+  inline date from_stream(iterator_type beg, iterator_type end) {
+    if(beg == end)
+    {
+      return date(not_a_date_time);
+    }
+    typedef typename std::iterator_traits<iterator_type>::value_type value_type;
+    return  date_time::from_stream_type<date>(beg, end, value_type());
+  }
+#endif //BOOST_NO_STD_ITERATOR_TRAITS
+  
+#if (defined(_MSC_VER) && (_MSC_VER < 1300))
+    // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings
+#else
+  //! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25])
+  inline date_period date_period_from_string(const std::string& s){
+    return date_time::from_simple_string_type<date,char>(s);
+  }
+#  if !defined(BOOST_NO_STD_WSTRING)
+  //! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25])
+  inline date_period date_period_from_wstring(const std::wstring& s){
+    return date_time::from_simple_string_type<date,wchar_t>(s);
+  }
+#  endif // BOOST_NO_STD_WSTRING
+#endif
+
+} } //namespace gregorian
+
+#endif

+ 70 - 0
ext/boost/date_time/gregorian_calendar.hpp

@@ -0,0 +1,70 @@
+#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__
+#define DATE_TIME_GREGORIAN_CALENDAR_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+namespace boost {
+namespace date_time {
+
+
+  //! An implementation of the Gregorian calendar
+  /*! This is a parameterized implementation of a proleptic Gregorian Calendar that
+      can be used in the creation of date systems or just to perform calculations.
+      All the methods of this class are static functions, so the intent is to
+      never create instances of this class.
+    @param ymd_type_ Struct type representing the year, month, day.  The ymd_type must
+           define a of types for the year, month, and day.  These types need to be
+           arithmetic types.
+    @param date_int_type_ Underlying type for the date count.  Must be an arithmetic type.
+  */
+  template<typename ymd_type_, typename date_int_type_>
+  class gregorian_calendar_base {
+  public:
+    //! define a type a date split into components 
+    typedef ymd_type_  ymd_type;
+    //! define a type for representing months
+    typedef typename ymd_type::month_type  month_type;
+    //! define a type for representing days
+    typedef typename ymd_type::day_type  day_type;
+    //! Type to hold a stand alone year value (eg: 2002)
+    typedef typename ymd_type::year_type  year_type;
+    //! Define the integer type to use for internal calculations
+    typedef date_int_type_ date_int_type;
+
+
+    static unsigned short day_of_week(const ymd_type& ymd);
+    static int week_number(const ymd_type&ymd);
+    //static unsigned short day_of_year(date_int_type);
+    static date_int_type day_number(const ymd_type& ymd);
+    static date_int_type julian_day_number(const ymd_type& ymd);
+    static long modjulian_day_number(const ymd_type& ymd);
+    static ymd_type from_day_number(date_int_type);
+    static ymd_type from_julian_day_number(date_int_type);
+    static ymd_type from_modjulian_day_number(long);
+    static bool is_leap_year(year_type);
+    static unsigned short end_of_month_day(year_type y, month_type m);
+    static ymd_type epoch();
+    static unsigned short days_in_week();
+
+  };
+
+
+
+} } //namespace
+  
+#ifndef NO_BOOST_DATE_TIME_INLINE
+#include "boost/date_time/gregorian_calendar.ipp"
+#endif
+
+
+
+#endif
+  
+

+ 219 - 0
ext/boost/date_time/gregorian_calendar.ipp

@@ -0,0 +1,219 @@
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#ifndef NO_BOOST_DATE_TIME_INLINE
+  #undef BOOST_DATE_TIME_INLINE
+  #define BOOST_DATE_TIME_INLINE inline
+#endif
+
+namespace boost {
+namespace date_time {
+  //! Return the day of the week (0==Sunday, 1==Monday, etc)
+  /*! Converts a year-month-day into a day of the week number
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  unsigned short
+  gregorian_calendar_base<ymd_type_,date_int_type_>::day_of_week(const ymd_type& ymd) {
+    unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
+    unsigned short y = static_cast<unsigned short>(ymd.year - a);
+    unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 2);
+    unsigned short d = static_cast<unsigned short>((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7);
+    //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n";
+    return d;
+  }
+  
+  //!Return the iso week number for the date
+  /*!Implements the rules associated with the iso 8601 week number.
+    Basically the rule is that Week 1 of the year is the week that contains 
+    January 4th or the week that contains the first Thursday in January.
+    Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000.
+  */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  int
+  gregorian_calendar_base<ymd_type_,date_int_type_>::week_number(const ymd_type& ymd) {
+    unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1));
+    unsigned long juliantoday = julian_day_number(ymd);
+    unsigned long day = (julianbegin + 3) % 7;
+    unsigned long week = (juliantoday + day - julianbegin + 4)/7;
+    
+    if ((week >= 1) && (week <= 52)) {
+      return week;
+    }
+    
+    if ((week == 53)) {
+      if((day==6) ||(day == 5 && is_leap_year(ymd.year))) {
+        return week; //under these circumstances week == 53.
+      } else {
+        return 1; //monday - wednesday is in week 1 of next year
+      }
+    }
+    //if the week is not in current year recalculate using the previous year as the beginning year
+    else if (week == 0) {
+      julianbegin = julian_day_number(ymd_type(static_cast<unsigned short>(ymd.year-1),1,1));
+      juliantoday = julian_day_number(ymd);
+      day = (julianbegin + 3) % 7;
+      week = (juliantoday + day - julianbegin + 4)/7;
+      return week;
+    }
+    
+    return week;  //not reachable -- well except if day == 5 and is_leap_year != true
+    
+  }
+  
+  //! Convert a ymd_type into a day number
+  /*! The day number is an absolute number of days since the start of count
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  date_int_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::day_number(const ymd_type& ymd) 
+  {
+    unsigned short a = static_cast<unsigned short>((14-ymd.month)/12);
+    unsigned short y = static_cast<unsigned short>(ymd.year + 4800 - a);
+    unsigned short m = static_cast<unsigned short>(ymd.month + 12*a - 3);
+    unsigned long  d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045;
+    return d;
+  }
+  
+  //! Convert a year-month-day into the julian day number
+  /*! Since this implementation uses julian day internally, this is the same as the day_number.
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  date_int_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::julian_day_number(const ymd_type& ymd) 
+  {
+    return day_number(ymd);
+  }
+
+  //! Convert year-month-day into a modified julian day number
+  /*! The day number is an absolute number of days.
+   *  MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  long
+  gregorian_calendar_base<ymd_type_,date_int_type_>::modjulian_day_number(const ymd_type& ymd) 
+  {
+    return julian_day_number(ymd)-2400001; //prerounded
+  }
+  
+  //! Change a day number into a year-month-day
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  ymd_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::from_day_number(date_int_type dayNumber) 
+  {
+    date_int_type a = dayNumber + 32044;
+    date_int_type b = (4*a + 3)/146097;
+    date_int_type c = a-((146097*b)/4);
+    date_int_type d = (4*c + 3)/1461;
+    date_int_type e = c - (1461*d)/4;
+    date_int_type m = (5*e + 2)/153;
+    unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
+    unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
+    year_type year = static_cast<unsigned short>(100*b + d - 4800 + (m/10));
+    //std::cout << year << "-" << month << "-" << day << "\n";
+    
+    return ymd_type(static_cast<unsigned short>(year),month,day);
+  }
+  
+  //! Change a day number into a year-month-day
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  ymd_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::from_julian_day_number(date_int_type dayNumber) 
+  {
+    date_int_type a = dayNumber + 32044;
+    date_int_type b = (4*a+3)/146097;
+    date_int_type c = a - ((146097*b)/4);
+    date_int_type d = (4*c + 3)/1461;
+    date_int_type e = c - ((1461*d)/4);
+    date_int_type m = (5*e + 2)/153;
+    unsigned short day = static_cast<unsigned short>(e - ((153*m + 2)/5) + 1);
+    unsigned short month = static_cast<unsigned short>(m + 3 - 12 * (m/10));
+    year_type year = static_cast<year_type>(100*b + d - 4800 + (m/10));
+    //std::cout << year << "-" << month << "-" << day << "\n";
+    
+    return ymd_type(year,month,day);
+  }
+  
+  //! Change a modified julian day number into a year-month-day
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  ymd_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::from_modjulian_day_number(long dayNumber) {
+    date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded
+    return from_julian_day_number(jd);
+  }
+  
+  //! Determine if the provided year is a leap year
+  /*!
+   *@return true if year is a leap year, false otherwise
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  bool
+  gregorian_calendar_base<ymd_type_,date_int_type_>::is_leap_year(year_type year) 
+  {
+    //divisible by 4, not if divisible by 100, but true if divisible by 400
+    return (!(year % 4))  && ((year % 100) || (!(year % 400)));
+  }
+  
+  //! Calculate the last day of the month
+  /*! Find the day which is the end of the month given year and month
+   *  No error checking is performed.
+   */
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  unsigned short
+  gregorian_calendar_base<ymd_type_,date_int_type_>::end_of_month_day(year_type year,
+                                                                      month_type month) 
+  {
+    switch (month) {
+    case 2:
+      if (is_leap_year(year)) {
+        return 29;
+      } else {
+        return 28;
+      };
+    case 4:
+    case 6:
+    case 9:
+    case 11:
+      return 30;
+    default:
+      return 31;
+    };
+
+  }
+  
+  //! Provide the ymd_type specification for the calandar start
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  ymd_type_
+  gregorian_calendar_base<ymd_type_,date_int_type_>::epoch() 
+  {
+    return ymd_type(1400,1,1);
+  }
+
+  //! Defines length of a week for week calculations
+  template<typename ymd_type_, typename date_int_type_>
+  BOOST_DATE_TIME_INLINE
+  unsigned short
+  gregorian_calendar_base<ymd_type_,date_int_type_>::days_in_week() 
+  {
+    return 7;
+  }
+
+
+} } //namespace gregorian
+
+

+ 509 - 0
ext/boost/date_time/int_adapter.hpp

@@ -0,0 +1,509 @@
+#ifndef _DATE_TIME_INT_ADAPTER_HPP__
+#define _DATE_TIME_INT_ADAPTER_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include "boost/config.hpp"
+#include "boost/limits.hpp" //work around compilers without limits
+#include "boost/date_time/special_defs.hpp"
+#include "boost/date_time/locale_config.hpp"
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+#  include <ostream>
+#endif
+
+namespace boost {
+namespace date_time {
+
+
+//! Adapter to create integer types with +-infinity, and not a value
+/*! This class is used internally in counted date/time representations.
+ *  It adds the floating point like features of infinities and
+ *  not a number. It also provides mathmatical operations with
+ *  consideration to special values following these rules:
+ *@code
+ *  +infinity  -  infinity  == Not A Number (NAN)
+ *   infinity  *  non-zero  == infinity
+ *   infinity  *  zero      == NAN
+ *  +infinity  * -integer   == -infinity
+ *   infinity  /  infinity  == NAN
+ *   infinity  *  infinity  == infinity 
+ *@endcode 
+ */
+template<typename int_type_>
+class int_adapter {
+public:
+  typedef int_type_ int_type;
+  int_adapter(int_type v) :
+    value_(v)
+  {}
+  static bool has_infinity()
+  {
+    return  true;
+  }
+  static const int_adapter  pos_infinity()
+  {
+    return (::std::numeric_limits<int_type>::max)();
+  }
+  static const int_adapter  neg_infinity()
+  {
+    return (::std::numeric_limits<int_type>::min)();
+  }
+  static const int_adapter  not_a_number()
+  {
+    return (::std::numeric_limits<int_type>::max)()-1;
+  }
+  static  int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION ()
+  {
+    return (::std::numeric_limits<int_type>::max)()-2;
+  }
+  static  int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION ()
+  {
+    return (::std::numeric_limits<int_type>::min)()+1;
+  }
+  static int_adapter from_special(special_values sv)
+  {
+    switch (sv) {
+    case not_a_date_time: return not_a_number();
+    case neg_infin:       return neg_infinity();
+    case pos_infin:       return pos_infinity();
+    case max_date_time:   return (max)();
+    case min_date_time:   return (min)();
+    default:              return not_a_number();
+    }
+  }
+  static bool is_inf(int_type v)
+  {
+    return (v == neg_infinity().as_number() ||
+            v == pos_infinity().as_number());
+  }
+  static bool is_neg_inf(int_type v)
+  {
+    return (v == neg_infinity().as_number());
+  }
+  static bool is_pos_inf(int_type v)
+  {
+    return (v == pos_infinity().as_number());
+  }
+  static bool is_not_a_number(int_type v)
+  {
+    return (v == not_a_number().as_number());
+  }
+  //! Returns either special value type or is_not_special
+  static special_values to_special(int_type v)
+  {
+    if (is_not_a_number(v)) return not_a_date_time;
+    if (is_neg_inf(v)) return neg_infin;
+    if (is_pos_inf(v)) return pos_infin;
+    return not_special;
+  }
+
+  //-3 leaves room for representations of infinity and not a date
+  static  int_type maxcount()
+  {
+    return (::std::numeric_limits<int_type>::max)()-3;
+  }
+  bool is_infinity() const
+  {
+    return (value_ == neg_infinity().as_number() ||
+            value_ == pos_infinity().as_number());
+  }
+  bool is_pos_infinity()const
+  {
+    return(value_ == pos_infinity().as_number());
+  }
+  bool is_neg_infinity()const
+  {
+    return(value_ == neg_infinity().as_number());
+  }
+  bool is_nan() const
+  {
+    return (value_ == not_a_number().as_number());
+  }
+  bool is_special() const
+  {
+    return(is_infinity() || is_nan()); 
+  }
+  bool operator==(const int_adapter& rhs) const
+  {
+    return (compare(rhs) == 0);
+  }
+  bool operator==(const int& rhs) const
+  {
+    // quiets compiler warnings
+    bool is_signed = std::numeric_limits<int_type>::is_signed;
+    if(!is_signed)
+    {
+      if(is_neg_inf(value_) && rhs == 0)
+      {
+        return false;
+      }
+    }
+    return (compare(rhs) == 0);
+  }
+  bool operator!=(const int_adapter& rhs) const
+  {
+    return (compare(rhs) != 0);
+  }
+  bool operator!=(const int& rhs) const
+  {
+    // quiets compiler warnings
+    bool is_signed = std::numeric_limits<int_type>::is_signed;
+    if(!is_signed)
+    {
+      if(is_neg_inf(value_) && rhs == 0)
+      {
+        return true;
+      }
+    }
+    return (compare(rhs) != 0);
+  }
+  bool operator<(const int_adapter& rhs) const
+  {
+    return (compare(rhs) == -1);
+  }
+  bool operator<(const int& rhs) const
+  {
+    // quiets compiler warnings
+    bool is_signed = std::numeric_limits<int_type>::is_signed;
+    if(!is_signed)
+    {
+      if(is_neg_inf(value_) && rhs == 0)
+      {
+        return true;
+      }
+    }
+    return (compare(rhs) == -1);
+  }
+  bool operator>(const int_adapter& rhs) const
+  {
+    return (compare(rhs) == 1);
+  }
+  int_type as_number() const
+  {
+    return value_;
+  }
+  //! Returns either special value type or is_not_special
+  special_values as_special() const
+  {
+    return int_adapter::to_special(value_);
+  }
+  //creates nasty ambiguities
+//   operator int_type() const
+//   {
+//     return value_;
+//   }
+
+  /*! Operator allows for adding dissimilar int_adapter types.
+   * The return type will match that of the the calling object's type */
+  template<class rhs_type>
+  inline
+  int_adapter operator+(const int_adapter<rhs_type>& rhs) const
+  {
+    if(is_special() || rhs.is_special())
+    {
+      if (is_nan() || rhs.is_nan()) 
+      {
+        return int_adapter::not_a_number();
+      }
+      if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ||
+      (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) )
+      {
+        return int_adapter::not_a_number();
+      }
+      if (is_infinity()) 
+      {
+        return *this;
+      }
+      if (rhs.is_pos_inf(rhs.as_number())) 
+      {
+        return int_adapter::pos_infinity();
+      }
+      if (rhs.is_neg_inf(rhs.as_number())) 
+      {
+        return int_adapter::neg_infinity();
+      }
+    }
+    return int_adapter<int_type>(value_ + rhs.as_number());
+  }
+
+  int_adapter operator+(const int_type rhs) const
+  {
+    if(is_special())
+    {
+      if (is_nan()) 
+      {
+        return int_adapter<int_type>(not_a_number());
+      }
+      if (is_infinity()) 
+      {
+        return *this;
+      }
+    }
+    return int_adapter<int_type>(value_ + rhs);
+  }
+  
+  /*! Operator allows for subtracting dissimilar int_adapter types.
+   * The return type will match that of the the calling object's type */
+  template<class rhs_type>
+  inline
+  int_adapter operator-(const int_adapter<rhs_type>& rhs)const
+  {
+    if(is_special() || rhs.is_special())
+    {
+      if (is_nan() || rhs.is_nan()) 
+      {
+        return int_adapter::not_a_number();
+      }
+      if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ||
+         (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) )
+      {
+        return int_adapter::not_a_number();
+      }
+      if (is_infinity()) 
+      {
+        return *this;
+      }
+      if (rhs.is_pos_inf(rhs.as_number())) 
+      {
+        return int_adapter::neg_infinity();
+      }
+      if (rhs.is_neg_inf(rhs.as_number())) 
+      {
+        return int_adapter::pos_infinity();
+      }
+    }
+    return int_adapter<int_type>(value_ - rhs.as_number());
+  }
+  int_adapter operator-(const int_type rhs) const
+  {
+    if(is_special())
+    {
+      if (is_nan()) 
+      {
+        return int_adapter<int_type>(not_a_number());
+      }
+      if (is_infinity()) 
+      {
+        return *this;
+      }
+    }
+    return int_adapter<int_type>(value_ - rhs);
+  }
+
+  // should templatize this to be consistant with op +-
+  int_adapter operator*(const int_adapter& rhs)const
+  {
+    if(this->is_special() || rhs.is_special())
+    {
+      return mult_div_specials(rhs);
+    }
+    return int_adapter<int_type>(value_ * rhs.value_);
+  }
+  /*! Provided for cases when automatic conversion from 
+   * 'int' to 'int_adapter' causes incorrect results. */
+  int_adapter operator*(const int rhs) const
+  {
+    if(is_special())
+    {
+      return mult_div_specials(rhs);
+    }
+    return int_adapter<int_type>(value_ * rhs);
+  }
+
+  // should templatize this to be consistant with op +-
+  int_adapter operator/(const int_adapter& rhs)const
+  {
+    if(this->is_special() || rhs.is_special())
+    {
+      if(is_infinity() && rhs.is_infinity())
+      {
+        return int_adapter<int_type>(not_a_number());
+      }
+      if(rhs != 0)
+      {
+        return mult_div_specials(rhs);
+      }
+      else { // let divide by zero blow itself up
+        return int_adapter<int_type>(value_ / rhs.value_);
+      }
+    }
+    return int_adapter<int_type>(value_ / rhs.value_);
+  }
+  /*! Provided for cases when automatic conversion from 
+   * 'int' to 'int_adapter' causes incorrect results. */
+  int_adapter operator/(const int rhs) const
+  {
+    if(is_special() && rhs != 0)
+    {
+      return mult_div_specials(rhs);
+    }
+    return int_adapter<int_type>(value_ / rhs);
+  }
+
+  // should templatize this to be consistant with op +-
+  int_adapter operator%(const int_adapter& rhs)const
+  {
+    if(this->is_special() || rhs.is_special())
+    {
+      if(is_infinity() && rhs.is_infinity())
+      {
+        return int_adapter<int_type>(not_a_number());
+      }
+      if(rhs != 0)
+      {
+        return mult_div_specials(rhs);
+      }
+      else { // let divide by zero blow itself up
+        return int_adapter<int_type>(value_ % rhs.value_);
+      }
+    }
+    return int_adapter<int_type>(value_ % rhs.value_);
+  }
+  /*! Provided for cases when automatic conversion from 
+   * 'int' to 'int_adapter' causes incorrect results. */
+  int_adapter operator%(const int rhs) const
+  {
+    if(is_special() && rhs != 0)
+    {
+      return mult_div_specials(rhs);
+    }
+    return int_adapter<int_type>(value_ % rhs);
+  }
+private:
+  int_type value_;
+  
+  //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs
+  int compare(const int_adapter& rhs)const
+  {
+    if(this->is_special() || rhs.is_special())
+    {
+      if(this->is_nan() || rhs.is_nan()) {
+        if(this->is_nan() && rhs.is_nan()) {
+          return 0; // equal
+        }
+        else {
+          return 2; // nan
+        }
+      }
+      if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) ||
+         (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) )
+        {
+          return -1; // less than
+        }
+      if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) ||
+         (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) {
+        return 1; // greater than
+      }
+    }
+    if(value_ < rhs.value_) return -1;
+    if(value_ > rhs.value_) return 1;
+    // implied-> if(value_ == rhs.value_) 
+    return 0;
+  }
+  /* When multiplying and dividing with at least 1 special value
+   * very simmilar rules apply. In those cases where the rules
+   * are different, they are handled in the respective operator 
+   * function. */
+  //! Assumes at least 'this' or 'rhs' is a special value
+  int_adapter mult_div_specials(const int_adapter& rhs)const
+  {
+    int min_value; 
+    // quiets compiler warnings
+    bool is_signed = std::numeric_limits<int_type>::is_signed;
+    if(is_signed) {
+      min_value = 0;
+    }
+    else {
+      min_value = 1;// there is no zero with unsigned
+    }
+    if(this->is_nan() || rhs.is_nan()) {
+      return int_adapter<int_type>(not_a_number());
+    }
+    if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) {
+        return int_adapter<int_type>(pos_infinity());
+    }
+    if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) {
+        return int_adapter<int_type>(neg_infinity());
+    }
+    //implied -> if(this->value_ == 0 || rhs.value_ == 0)
+    return int_adapter<int_type>(not_a_number());
+  }
+  /* Overloaded function necessary because of special
+   * situation where int_adapter is instantiated with 
+   * 'unsigned' and func is called with negative int.
+   * It would produce incorrect results since 'unsigned'
+   * wraps around when initialized with a negative value */
+  //! Assumes 'this' is a special value
+  int_adapter mult_div_specials(const int& rhs) const
+  {
+    int min_value; 
+    // quiets compiler warnings
+    bool is_signed = std::numeric_limits<int_type>::is_signed;
+    if(is_signed) {
+      min_value = 0;
+    }
+    else {
+      min_value = 1;// there is no zero with unsigned
+    }
+    if(this->is_nan()) {
+      return int_adapter<int_type>(not_a_number());
+    }
+    if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) {
+        return int_adapter<int_type>(pos_infinity());
+    }
+    if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) {
+        return int_adapter<int_type>(neg_infinity());
+    }
+    //implied -> if(this->value_ == 0 || rhs.value_ == 0)
+    return int_adapter<int_type>(not_a_number());
+  }
+  
+};
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+  /*! Expected output is either a numeric representation 
+   * or a special values representation.<BR> 
+   * Ex. "12", "+infinity", "not-a-number", etc. */
+  //template<class charT = char, class traits = std::traits<charT>, typename int_type>
+  template<class charT, class traits, typename int_type>
+  inline
+  std::basic_ostream<charT, traits>& 
+  operator<<(std::basic_ostream<charT, traits>& os, const int_adapter<int_type>& ia)
+  {
+    if(ia.is_special()) {
+      // switch copied from date_names_put.hpp
+      switch(ia.as_special())
+        {
+      case not_a_date_time:
+        os << "not-a-number";
+        break;
+      case pos_infin:
+        os << "+infinity";
+        break;
+      case neg_infin:
+        os << "-infinity";
+        break;
+      default:
+        os << "";
+      }
+    }
+    else {
+      os << ia.as_number(); 
+    }
+    return os;
+  }
+#endif
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 303 - 0
ext/boost/date_time/iso_format.hpp

@@ -0,0 +1,303 @@
+#ifndef ISO_FORMAT_HPP___
+#define ISO_FORMAT_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/parse_format_base.hpp"
+
+namespace boost {
+namespace date_time {
+
+//! Class to provide common iso formatting spec
+template<class charT>
+class iso_format_base {
+public:
+  //! Describe month format -- its an integer in iso format
+  static month_format_spec month_format()
+  {
+    return month_as_integer;
+  }
+
+  //! String used printed is date is invalid
+  static const charT* not_a_date()
+  {     
+    return "not-a-date-time";
+  }
+  //! String used to for positive infinity value
+  static const charT* pos_infinity()
+  {
+    return "+infinity";
+  }
+  //! String used to for positive infinity value
+  static const charT* neg_infinity()
+  {
+    return "-infinity";
+  }
+
+  //! ISO char for a year -- used in durations
+  static charT year_sep_char()
+  {
+    return 'Y';
+  }
+  //! ISO char for a month
+  static charT month_sep_char()
+  {
+    return '-';
+  }
+  //! ISO char for a day
+  static charT day_sep_char()
+  {
+    return '-';
+  }
+  //! char for minute
+  static charT hour_sep_char()
+  {
+    return ':';
+  }
+  //! char for minute
+  static charT minute_sep_char()
+  {
+    return ':';
+  }
+  //! char for second
+  static charT second_sep_char()
+  {
+    return ':';
+  }
+  //! ISO char for a period
+  static charT period_start_char()
+  {
+    return 'P';
+  }
+  //! Used in time in mixed strings to set start of time
+  static charT time_start_char()
+  {
+    return 'T';
+  }
+
+  //! Used in mixed strings to identify start of a week number
+  static charT week_start_char()
+  {
+    return 'W';
+  }
+
+  //! Separators for periods
+  static charT period_sep_char()
+  {
+    return '/';
+  }
+  //! Separator for hh:mm:ss
+  static charT time_sep_char()
+  {
+    return ':';
+  }
+  //! Preferred Separator for hh:mm:ss,decimal_fraction
+  static charT fractional_time_sep_char()
+  {
+    return ',';
+  }
+
+  static bool is_component_sep(charT sep)
+  {
+    switch(sep) {
+    case 'H':
+    case 'M':
+    case 'S':
+    case 'W':
+    case 'T':
+    case 'Y':
+    case 'D':return true;
+    default:
+      return false;
+    }
+  }
+
+  static bool is_fractional_time_sep(charT sep)
+  {
+    switch(sep) {
+    case ',':
+    case '.': return true;
+    default: return false;
+    }
+  }
+  static bool is_timezone_sep(charT sep)
+  {
+    switch(sep) {
+    case '+':
+    case '-': return true;
+    default: return false;
+    }
+  }
+  static charT element_sep_char()
+  {
+    return '-';
+  }
+
+};
+
+#ifndef BOOST_NO_STD_WSTRING
+
+//! Class to provide common iso formatting spec
+template<>
+class iso_format_base<wchar_t> {
+public:
+  //! Describe month format -- its an integer in iso format
+  static month_format_spec month_format()
+  {
+    return month_as_integer;
+  }
+
+  //! String used printed is date is invalid
+  static const wchar_t* not_a_date()
+  {      
+    return L"not-a-date-time";
+  }
+  //! String used to for positive infinity value
+  static const wchar_t* pos_infinity()
+  {
+    return L"+infinity";
+  }
+  //! String used to for positive infinity value
+  static const wchar_t* neg_infinity()
+  {
+    return L"-infinity";
+  }
+
+  //! ISO char for a year -- used in durations
+  static wchar_t year_sep_char()
+  {
+    return 'Y';
+  }
+  //! ISO char for a month
+  static wchar_t month_sep_char()
+  {
+    return '-';
+  }
+  //! ISO char for a day
+  static wchar_t day_sep_char()
+  {
+    return '-';
+  }
+  //! char for minute
+  static wchar_t hour_sep_char()
+  {
+    return ':';
+  }
+  //! char for minute
+  static wchar_t minute_sep_char()
+  {
+    return ':';
+  }
+  //! char for second
+  static wchar_t second_sep_char()
+  {
+    return ':';
+  }
+  //! ISO char for a period
+  static wchar_t period_start_char()
+  {
+    return 'P';
+  }
+  //! Used in time in mixed strings to set start of time
+  static wchar_t time_start_char()
+  {
+    return 'T';
+  }
+
+  //! Used in mixed strings to identify start of a week number
+  static wchar_t week_start_char()
+  {
+    return 'W';
+  }
+
+  //! Separators for periods
+  static wchar_t period_sep_char()
+  {
+    return '/';
+  }
+  //! Separator for hh:mm:ss
+  static wchar_t time_sep_char()
+  {
+    return ':';
+  }
+  //! Preferred Separator for hh:mm:ss,decimal_fraction
+  static wchar_t fractional_time_sep_char()
+  {
+    return ',';
+  }
+
+  static bool is_component_sep(wchar_t sep)
+  {
+    switch(sep) {
+    case 'H':
+    case 'M':
+    case 'S':
+    case 'W':
+    case 'T':
+    case 'Y':
+    case 'D':return true;
+    default:
+      return false;
+    }
+  }
+
+  static bool is_fractional_time_sep(wchar_t sep)
+  {
+    switch(sep) {
+    case ',':
+    case '.': return true;
+    default: return false;
+    }
+  }
+  static bool is_timezone_sep(wchar_t sep)
+  {
+    switch(sep) {
+    case '+':
+    case '-': return true;
+    default: return false;
+    }
+  }
+  static wchar_t element_sep_char()
+  {
+    return '-';
+  }
+
+};
+
+#endif // BOOST_NO_STD_WSTRING
+
+//! Format description for iso normal YYYYMMDD
+template<class charT>
+class iso_format : public iso_format_base<charT> {
+public:
+  //! The ios standard format doesn't use char separators
+  static bool has_date_sep_chars()
+  {
+    return false;
+  }
+};
+
+//! Extended format uses seperators YYYY-MM-DD
+template<class charT>
+class iso_extended_format : public iso_format_base<charT> {
+public:
+  //! Extended format needs char separators
+  static bool has_date_sep_chars()
+  {
+    return true;
+  }
+
+};
+
+} } //namespace date_time
+
+
+
+
+#endif

+ 34 - 0
ext/boost/date_time/local_time/conversion.hpp

@@ -0,0 +1,34 @@
+#ifndef DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
+#define DATE_TIME_LOCAL_TIME_CONVERSION_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+#include "boost/date_time/posix_time/conversion.hpp"
+#include "boost/date_time/c_time.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+
+namespace boost {
+namespace local_time {
+
+//! Function that creates a tm struct from a local_date_time
+inline
+std::tm to_tm(const local_date_time& lt) {
+  std::tm lt_tm = posix_time::to_tm(lt.local_time());
+  if(lt.is_dst()){
+    lt_tm.tm_isdst = 1;
+  }
+  else{
+    lt_tm.tm_isdst = 0;
+  }
+  return lt_tm;
+}
+
+
+}} // namespaces
+#endif // DATE_TIME_LOCAL_TIME_CONVERSION_HPP__

+ 169 - 0
ext/boost/date_time/local_time/custom_time_zone.hpp

@@ -0,0 +1,169 @@
+#ifndef LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
+#define LOCAL_TIME_CUSTOM_TIME_ZONE_HPP__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/time_zone_base.hpp"
+#include "boost/date_time/time_zone_names.hpp"
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
+#include "boost/date_time/string_convert.hpp"
+//#include "boost/date_time/special_defs.hpp"
+#include "boost/shared_ptr.hpp"
+
+namespace boost {
+namespace local_time {
+
+  //typedef boost::date_time::time_zone_names time_zone_names;
+  typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
+  //typedef boost::date_time::time_zone_base<boost::posix_time::ptime> time_zone;
+  typedef boost::shared_ptr<dst_calc_rule> dst_calc_rule_ptr;
+
+  //! A real time zone
+  template<class CharT>
+  class custom_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
+  public:
+    typedef boost::posix_time::time_duration time_duration_type;
+    typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
+    typedef typename base_type::string_type string_type;
+    typedef typename base_type::stringstream_type stringstream_type;
+    typedef date_time::time_zone_names_base<CharT> time_zone_names;
+    typedef CharT char_type;
+    
+    custom_time_zone_base(const time_zone_names& zone_names,   
+                     const time_duration_type& utc_offset,
+                     const dst_adjustment_offsets& dst_shift,
+                     boost::shared_ptr<dst_calc_rule> calc_rule) :
+      zone_names_(zone_names),
+      base_utc_offset_(utc_offset),
+      dst_offsets_(dst_shift),
+      dst_calc_rules_(calc_rule)
+    {};
+    virtual ~custom_time_zone_base() {};
+    virtual string_type dst_zone_abbrev() const
+    {
+      return zone_names_.dst_zone_abbrev();
+    }
+    virtual string_type std_zone_abbrev() const
+    {
+      return zone_names_.std_zone_abbrev();
+    }
+    virtual string_type dst_zone_name() const
+    {
+      return zone_names_.dst_zone_name();
+    }
+    virtual string_type std_zone_name() const
+    {
+      return zone_names_.std_zone_name();
+    }
+    //! True if zone uses daylight savings adjustments
+    virtual bool has_dst() const
+    {
+      return (dst_calc_rules_); //if calc_rule is set the tz has dst
+    }
+    //! Local time that DST starts -- NADT if has_dst is false
+    virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y) const
+    {
+      gregorian::date d(gregorian::not_a_date_time);
+      if (dst_calc_rules_) {
+        d = dst_calc_rules_->start_day(y);
+      }
+      return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
+    }
+    //! Local time that DST ends -- NADT if has_dst is false
+    virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y) const
+    {
+      gregorian::date d(gregorian::not_a_date_time);
+      if (dst_calc_rules_) {
+        d = dst_calc_rules_->end_day(y);
+      }
+      return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
+    }
+    //! Base offset from UTC for zone (eg: -07:30:00)
+    virtual time_duration_type base_utc_offset() const
+    {
+      return base_utc_offset_;
+    }
+    //! Adjustment forward or back made while DST is in effect
+    virtual time_duration_type dst_offset() const
+    {
+      return dst_offsets_.dst_adjust_;
+    }
+    //! Returns a POSIX time_zone string for this object
+    virtual string_type to_posix_string() const
+    {
+      // std offset dst [offset],start[/time],end[/time] - w/o spaces
+      stringstream_type ss;
+      ss.fill('0');
+      boost::shared_ptr<dst_calc_rule> no_rules;
+      // std
+      ss << std_zone_abbrev();
+      // offset
+      if(base_utc_offset().is_negative()) {
+        // inverting the sign guarantees we get two digits
+        ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
+      }
+      else {
+        ss << '+' << std::setw(2) << base_utc_offset().hours();
+      }
+      if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
+        ss << ':' << std::setw(2) << base_utc_offset().minutes();
+        if(base_utc_offset().seconds() != 0) {
+          ss << ':' << std::setw(2) << base_utc_offset().seconds();
+        }
+      }
+      if(dst_calc_rules_ != no_rules) {
+        // dst
+        ss << dst_zone_abbrev();
+        // dst offset
+        if(dst_offset().is_negative()) {
+          // inverting the sign guarantees we get two digits
+          ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
+        }
+        else {
+          ss << '+' << std::setw(2) << dst_offset().hours();
+        }
+        if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offset().minutes();
+          if(dst_offset().seconds() != 0) {
+            ss << ':' << std::setw(2) << dst_offset().seconds();
+          }
+        }
+        // start/time
+        ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
+           << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
+           << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
+        if(dst_offsets_.dst_start_offset_.seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
+        }
+        // end/time
+        ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
+           << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
+           << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
+        if(dst_offsets_.dst_end_offset_.seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
+        }
+      }
+
+      return ss.str();
+    }
+  private:
+    time_zone_names zone_names_;
+    bool has_dst_;
+    time_duration_type base_utc_offset_;
+    dst_adjustment_offsets dst_offsets_;
+    boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
+  };
+
+  typedef custom_time_zone_base<char> custom_time_zone;
+
+} }//namespace
+
+
+
+#endif

+ 115 - 0
ext/boost/date_time/local_time/date_duration_operators.hpp

@@ -0,0 +1,115 @@
+#ifndef LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
+#define LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___
+                                                                                
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or 
+ * http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+
+namespace boost {
+namespace local_time {
+  
+  /*!@file date_duration_operators.hpp Operators for local_date_time and 
+   * optional gregorian types. Operators use snap-to-end-of-month behavior. 
+   * Further details on this behavior can be found in reference for 
+   * date_time/date_duration_types.hpp and documentation for 
+   * month and year iterators.
+   */
+ 
+
+  /*! Adds a months object and a local_date_time. Result will be same 
+   * day-of-month as local_date_time unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  local_date_time 
+  operator+(const local_date_time& t, const boost::gregorian::months& m)
+  {
+    return t + m.get_offset(t.utc_time().date());
+  }
+  
+  /*! Adds a months object to a local_date_time. Result will be same 
+   * day-of-month as local_date_time unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  local_date_time 
+  operator+=(local_date_time& t, const boost::gregorian::months& m)
+  {
+    return t += m.get_offset(t.utc_time().date());
+  }
+
+  /*! Subtracts a months object and a local_date_time. Result will be same 
+   * day-of-month as local_date_time unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  local_date_time 
+  operator-(const local_date_time& t, const boost::gregorian::months& m)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t + m.get_neg_offset(t.utc_time().date());
+  }
+  
+  /*! Subtracts a months object from a local_date_time. Result will be same 
+   * day-of-month as local_date_time unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  local_date_time 
+  operator-=(local_date_time& t, const boost::gregorian::months& m)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t += m.get_neg_offset(t.utc_time().date());
+  }
+
+  // local_date_time & years
+  
+  /*! Adds a years object and a local_date_time. Result will be same 
+   * month and day-of-month as local_date_time unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  local_date_time 
+  operator+(const local_date_time& t, const boost::gregorian::years& y)
+  {
+    return t + y.get_offset(t.utc_time().date());
+  }
+
+  /*! Adds a years object to a local_date_time. Result will be same 
+   * month and day-of-month as local_date_time unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  local_date_time 
+  operator+=(local_date_time& t, const boost::gregorian::years& y)
+  {
+    return t += y.get_offset(t.utc_time().date());
+  }
+
+  /*! Subtracts a years object and a local_date_time. Result will be same 
+   * month and day-of-month as local_date_time unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  local_date_time 
+  operator-(const local_date_time& t, const boost::gregorian::years& y)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t + y.get_neg_offset(t.utc_time().date());
+  }
+
+  /*! Subtracts a years object from a local_date_time. Result will be same 
+   * month and day-of-month as local_date_time unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  local_date_time 
+  operator-=(local_date_time& t, const boost::gregorian::years& y)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t += y.get_neg_offset(t.utc_time().date());
+  }
+
+
+}} // namespaces
+
+#endif // LOCAL_TIME_DATE_DURATION_OPERATORS_HPP___

+ 77 - 0
ext/boost/date_time/local_time/dst_transition_day_rules.hpp

@@ -0,0 +1,77 @@
+#ifndef LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
+#define LOCAL_TIME_DST_TRANSITION_DAY_RULES_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include "boost/date_time/gregorian/gregorian_types.hpp"
+#include "boost/date_time/dst_transition_generators.hpp"
+
+namespace boost {
+namespace local_time {
+   
+    //! Provides rule of the form starting Apr 30 ending Oct 21
+    typedef date_time::dst_day_calc_rule<gregorian::date> dst_calc_rule;
+
+    struct partial_date_rule_spec 
+    {
+      typedef gregorian::date date_type;
+      typedef gregorian::partial_date start_rule;
+      typedef gregorian::partial_date end_rule;
+    };
+    
+    //! Provides rule of the form first Sunday in April, last Saturday in Oct
+    typedef date_time::day_calc_dst_rule<partial_date_rule_spec> partial_date_dst_rule;
+
+    struct first_last_rule_spec 
+    {
+      typedef gregorian::date date_type;
+      typedef gregorian::first_kday_of_month start_rule;
+      typedef gregorian::last_kday_of_month end_rule;
+    };
+
+    //! Provides rule of the form first Sunday in April, last Saturday in Oct
+    typedef date_time::day_calc_dst_rule<first_last_rule_spec> first_last_dst_rule;
+
+    struct last_last_rule_spec 
+    {
+      typedef gregorian::date date_type;
+      typedef gregorian::last_kday_of_month start_rule;
+      typedef gregorian::last_kday_of_month end_rule;
+    };
+
+    //! Provides rule of the form last Sunday in April, last Saturday in Oct
+    typedef date_time::day_calc_dst_rule<last_last_rule_spec> last_last_dst_rule;
+
+    struct nth_last_rule_spec
+    {
+      typedef gregorian::date date_type;
+      typedef gregorian::nth_kday_of_month start_rule;
+      typedef gregorian::last_kday_of_month end_rule;
+    };
+
+    //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April, last Sunday in Oct
+    typedef date_time::day_calc_dst_rule<nth_last_rule_spec> nth_last_dst_rule;
+    
+    struct nth_kday_rule_spec
+    {
+      typedef gregorian::date date_type;
+      typedef gregorian::nth_kday_of_month start_rule;
+      typedef gregorian::nth_kday_of_month end_rule;
+    };
+
+    //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
+    typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_kday_dst_rule;
+    //! Provides rule in form of [1st|2nd|3rd|4th] Sunday in April/October
+    typedef date_time::day_calc_dst_rule<nth_kday_rule_spec> nth_day_of_the_week_in_month_dst_rule;
+
+
+} }//namespace
+
+
+#endif

+ 527 - 0
ext/boost/date_time/local_time/local_date_time.hpp

@@ -0,0 +1,527 @@
+#ifndef LOCAL_TIME_LOCAL_DATE_TIME_HPP__
+#define LOCAL_TIME_LOCAL_DATE_TIME_HPP__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <string>
+#include <iomanip>
+#include <sstream>
+#include <stdexcept>
+#include <boost/shared_ptr.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/time.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp> //todo remove?
+#include <boost/date_time/dst_rules.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace local_time {
+
+  //! simple exception for reporting when STD or DST cannot be determined
+  struct ambiguous_result : public std::logic_error
+  {
+    ambiguous_result (std::string const& msg = std::string()) :
+      std::logic_error(std::string("Daylight Savings Results are ambiguous: " + msg)) {}
+  };
+  //! simple exception for when time label given cannot exist
+  struct time_label_invalid : public std::logic_error
+  {
+    time_label_invalid (std::string const& msg = std::string()) :
+      std::logic_error(std::string("Time label given is invalid: " + msg)) {}
+  };
+  struct dst_not_valid: public std::logic_error
+  {
+    dst_not_valid(std::string const& msg = std::string()) :
+      std::logic_error(std::string("is_dst flag does not match resulting dst for time label given: " + msg)) {}
+  };
+
+  //TODO: I think these should be in local_date_time_base and not 
+  // necessarily brought into the namespace
+  using date_time::time_is_dst_result;
+  using date_time::is_in_dst;
+  using date_time::is_not_in_dst;
+  using date_time::ambiguous;
+  using date_time::invalid_time_label;
+
+  //! Representation of "wall-clock" time in a particular time zone
+  /*! Representation of "wall-clock" time in a particular time zone
+   * Local_date_time_base holds a time value (date and time offset from 00:00) 
+   * along with a time zone. The time value is stored as UTC and conversions 
+   * to wall clock time are made as needed. This approach allows for 
+   * operations between wall-clock times in different time zones, and 
+   * daylight savings time considerations, to be made. Time zones are 
+   * required to be in the form of a boost::shared_ptr<time_zone_base>.
+   */
+  template<class utc_time_=posix_time::ptime, 
+           class tz_type=date_time::time_zone_base<utc_time_,char> >
+  class local_date_time_base :  public date_time::base_time<utc_time_, 
+                                                            boost::posix_time::posix_time_system> { 
+  public:
+    typedef utc_time_ utc_time_type;
+    typedef typename utc_time_type::time_duration_type time_duration_type;
+    typedef typename utc_time_type::date_type date_type;
+    typedef typename date_type::duration_type date_duration_type;
+    typedef typename utc_time_type::time_system_type time_system_type;
+    /*! This constructor interprets the passed time as a UTC time.
+     *  So, for example, if the passed timezone is UTC-5 then the
+     *  time will be adjusted back 5 hours.  The time zone allows for 
+     *  automatic calculation of whether the particular time is adjusted for
+     *  daylight savings, etc.
+     *  If the time zone shared pointer is null then time stays unadjusted.
+     *@param t A UTC time
+     *@param tz Timezone for to adjust the UTC time to.
+     */
+    local_date_time_base(utc_time_type t, 
+                         boost::shared_ptr<tz_type> tz) : 
+      date_time::base_time<utc_time_type, time_system_type>(t),
+      zone_(tz)
+    {
+      // param was already utc so nothing more to do
+    } 
+
+    /*! This constructs a local time -- the passed time information 
+     * understood to be in the passed tz. The DST flag must be passed 
+     * to indicate whether the time is in daylight savings or not.  
+     *  @throws -- time_label_invalid if the time passed does not exist in 
+     *             the given locale. The non-existent case occurs typically 
+     *             during the shift-back from daylight savings time.  When 
+     *             the clock is shifted forward a range of times 
+     *             (2 am to 3 am in the US) is skipped and hence is invalid.
+     *  @throws -- dst_not_valid if the DST flag is passed for a period 
+     *             where DST is not active.
+     */
+    local_date_time_base(date_type d, 
+                         time_duration_type td,
+                         boost::shared_ptr<tz_type> tz, 
+                         bool dst_flag) : //necessary for constr_adj()
+      date_time::base_time<utc_time_type,time_system_type>(construction_adjustment(utc_time_type(d, td), tz, dst_flag)),
+      zone_(tz)
+    {
+      if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()){
+        
+        // d & td are already local so we use them
+        time_is_dst_result result = check_dst(d, td, tz);
+        bool in_dst = (result == is_in_dst); // less processing than is_dst()
+
+        // ambig occurs at end, invalid at start
+        if(result == invalid_time_label){
+          // Ex: 2:15am local on trans-in day in nyc, dst_flag irrelevant
+          std::ostringstream ss;
+          ss << "time given: " << d << ' ' << td;
+          boost::throw_exception(time_label_invalid(ss.str()));
+        }
+        else if(result != ambiguous && in_dst != dst_flag){
+          // is dst_flag accurate?
+          // Ex: false flag in NYC in June
+          std::ostringstream ss;
+          ss.setf(std::ios_base::boolalpha);
+          ss << "flag given: dst=" << dst_flag << ", dst calculated: dst=" << in_dst;
+          boost::throw_exception(dst_not_valid(ss.str()));
+        }
+        
+        // everything checks out and conversion to utc already done
+      }
+    } 
+    
+    //TODO maybe not the right set...Ignore the last 2 for now...
+    enum DST_CALC_OPTIONS { EXCEPTION_ON_ERROR, NOT_DATE_TIME_ON_ERROR }; 
+                            //ASSUME_DST_ON_ERROR, ASSUME_NOT_DST_ON_ERROR };
+
+    /*! This constructs a local time -- the passed time information 
+     * understood to be in the passed tz.  The DST flag is calculated 
+     * according to the specified rule. 
+     */
+    local_date_time_base(date_type d, 
+                         time_duration_type td,
+                         boost::shared_ptr<tz_type> tz, 
+                         DST_CALC_OPTIONS calc_option) : 
+      // dummy value - time_ is set in constructor code
+      date_time::base_time<utc_time_type,time_system_type>(utc_time_type(d,td)),
+      zone_(tz)
+    {
+      time_is_dst_result result = check_dst(d, td, tz);
+      if(result == ambiguous) {
+        if(calc_option == EXCEPTION_ON_ERROR){
+          std::ostringstream ss;
+          ss << "time given: " << d << ' ' << td;
+          boost::throw_exception(ambiguous_result(ss.str()));
+        }
+        else{ // NADT on error
+          this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
+        }
+      }
+      else if(result == invalid_time_label){
+        if(calc_option == EXCEPTION_ON_ERROR){
+          std::ostringstream ss;
+          ss << "time given: " << d << ' ' << td;
+          boost::throw_exception(time_label_invalid(ss.str()));
+        }
+        else{ // NADT on error
+          this->time_ = posix_time::posix_time_system::get_time_rep(date_type(date_time::not_a_date_time), time_duration_type(date_time::not_a_date_time));
+        }
+      }
+      else if(result == is_in_dst){
+        utc_time_type t = 
+          construction_adjustment(utc_time_type(d, td), tz, true);
+        this->time_ = posix_time::posix_time_system::get_time_rep(t.date(), 
+                                                            t.time_of_day());
+      }
+      else{
+        utc_time_type t = 
+          construction_adjustment(utc_time_type(d, td), tz, false);
+        this->time_ = posix_time::posix_time_system::get_time_rep(t.date(), 
+                                                            t.time_of_day());
+      }
+    }
+
+
+    //! Determines if given time label is in daylight savings for given zone
+    /*! Determines if given time label is in daylight savings for given zone. 
+     * Takes a date and time_duration representing a local time, along 
+     * with time zone, and returns a time_is_dst_result object as result.
+     */
+    static time_is_dst_result check_dst(date_type d, 
+                                        time_duration_type td,
+                                        boost::shared_ptr<tz_type> tz) 
+    {
+      if(tz != boost::shared_ptr<tz_type>() && tz->has_dst()) {
+        typedef typename date_time::dst_calculator<date_type, time_duration_type> dst_calculator;
+        return dst_calculator::local_is_dst(
+            d, td, 
+            tz->dst_local_start_time(d.year()).date(), 
+            tz->dst_local_start_time(d.year()).time_of_day(), 
+            tz->dst_local_end_time(d.year()).date(), 
+            tz->dst_local_end_time(d.year()).time_of_day(),
+            tz->dst_offset()
+        );
+      }
+      else{
+        return is_not_in_dst;
+      }
+    }
+
+    //! Simple destructor, releases time zone if last referrer
+    ~local_date_time_base() {};
+
+    //! Copy constructor
+    local_date_time_base(const local_date_time_base& rhs) : 
+      date_time::base_time<utc_time_type, time_system_type>(rhs),
+      zone_(rhs.zone_)
+    {}
+
+    //! Special values constructor
+    explicit local_date_time_base(const boost::date_time::special_values sv,
+                                  boost::shared_ptr<tz_type> tz = boost::shared_ptr<tz_type>()) :
+      date_time::base_time<utc_time_type, time_system_type>(utc_time_type(sv)),
+      zone_(tz)
+    {}
+
+    //! returns time zone associated with calling instance
+    boost::shared_ptr<tz_type> zone() const 
+    {
+      return zone_;
+    }
+    //! returns false is time_zone is NULL and if time value is a special_value
+    bool is_dst() const
+    {
+      if(zone_ != boost::shared_ptr<tz_type>() && zone_->has_dst() && !this->is_special()) {
+        // check_dst takes a local time, *this is utc
+        utc_time_type lt(this->time_);
+        lt += zone_->base_utc_offset();
+        // dst_offset only needs to be considered with ambiguous time labels
+        // make that adjustment there
+
+        switch(check_dst(lt.date(), lt.time_of_day(), zone_)){
+          case is_not_in_dst:
+            return false;
+          case is_in_dst:
+            return true;
+          case ambiguous: 
+            if(lt + zone_->dst_offset() < zone_->dst_local_end_time(lt.date().year())) {
+              return true;
+            }
+            break;
+          case invalid_time_label: 
+            if(lt >= zone_->dst_local_start_time(lt.date().year())) {
+              return true;
+            }
+            break;
+        }
+      }
+      return false;
+    }
+    //! Returns object's time value as a utc representation
+    utc_time_type utc_time() const 
+    {
+      return utc_time_type(this->time_);
+    }
+    //! Returns object's time value as a local representation
+    utc_time_type local_time() const 
+    {
+      if(zone_ != boost::shared_ptr<tz_type>()){
+        utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
+        if (is_dst()) {
+          lt += zone_->dst_offset();
+        }
+        return lt;
+      }
+      return utc_time_type(this->time_);
+    }
+    //! Returns string in the form "2003-Aug-20 05:00:00 EDT"
+    /*! Returns string in the form "2003-Aug-20 05:00:00 EDT". If
+     * time_zone is NULL the time zone abbreviation will be "UTC". The time 
+     * zone abbrev will not be included if calling object is a special_value*/
+    std::string to_string() const
+    {
+      //TODO is this a temporary function ???
+      std::ostringstream ss;
+      if(this->is_special()){
+        ss << utc_time();
+        return ss.str();
+      }
+      if(zone_ == boost::shared_ptr<tz_type>()) {
+        ss << utc_time() << " UTC";
+        return ss.str();
+      }
+      bool is_dst_ = is_dst();
+      utc_time_type lt = this->utc_time() + zone_->base_utc_offset();
+      if (is_dst_) {
+        lt += zone_->dst_offset();
+      }
+      ss << local_time() << " ";
+      if (is_dst()) {
+        ss << zone_->dst_zone_abbrev();
+      }
+      else {
+        ss << zone_->std_zone_abbrev();
+      }
+      return ss.str();
+    }
+    /*! returns a local_date_time_base in the given time zone with the 
+     * optional time_duration added. */
+    local_date_time_base local_time_in(boost::shared_ptr<tz_type> new_tz, 
+                                       time_duration_type td=time_duration_type(0,0,0)) const 
+    {
+      return local_date_time_base(utc_time_type(this->time_) + td, new_tz);
+    }
+    
+    //! Returns name of associated time zone or "Coordinated Universal Time".
+    /*! Optional bool parameter will return time zone as an offset 
+     * (ie "+07:00" extended iso format). Empty string is returned for 
+     * classes that do not use a time_zone */
+    std::string zone_name(bool as_offset=false) const
+    {
+      if(zone_ == boost::shared_ptr<tz_type>()) {
+        if(as_offset) {
+          return std::string("Z");
+        }
+        else {
+          return std::string("Coordinated Universal Time");
+        }
+      }
+      if (is_dst()) {
+        if(as_offset) {
+          time_duration_type td = zone_->base_utc_offset();
+          td += zone_->dst_offset();
+          return zone_as_offset(td, ":");
+        }
+        else {
+          return zone_->dst_zone_name();
+        }
+      }
+      else {
+        if(as_offset) {
+          time_duration_type td = zone_->base_utc_offset();
+          return zone_as_offset(td, ":");
+        }
+        else {
+          return zone_->std_zone_name();
+        }
+      }
+    }
+    //! Returns abbreviation of associated time zone or "UTC".
+    /*! Optional bool parameter will return time zone as an offset 
+     * (ie "+0700" iso format). Empty string is returned for classes 
+     * that do not use a time_zone */
+    std::string zone_abbrev(bool as_offset=false) const
+    {
+      if(zone_ == boost::shared_ptr<tz_type>()) {
+        if(as_offset) {
+          return std::string("Z");
+        }
+        else {
+          return std::string("UTC");
+        }
+      }
+      if (is_dst()) {
+        if(as_offset) {
+          time_duration_type td = zone_->base_utc_offset();
+          td += zone_->dst_offset();
+          return zone_as_offset(td, "");
+        }
+        else {
+          return zone_->dst_zone_abbrev();
+        }
+      }
+      else {
+        if(as_offset) {
+          time_duration_type td = zone_->base_utc_offset();
+          return zone_as_offset(td, "");
+        }
+        else {
+          return zone_->std_zone_abbrev();
+        }
+      }
+    }
+
+    //! returns a posix_time_zone string for the associated time_zone. If no time_zone, "UTC+00" is returned.
+    std::string zone_as_posix_string() const
+    {
+      if(zone_ == shared_ptr<tz_type>()) {
+        return std::string("UTC+00");
+      }
+      return zone_->to_posix_string();
+    }
+      
+    //! Equality comparison operator
+    /*bool operator==(const date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>& rhs) const
+    { // fails due to rhs.time_ being protected
+      return date_time::base_time<boost::posix_time::ptime,boost::posix_time::posix_time_system>::operator==(rhs);
+      //return this->time_ == rhs.time_;
+    }*/
+    //! Equality comparison operator
+    bool operator==(const local_date_time_base& rhs) const
+    {
+      return time_system_type::is_equal(this->time_, rhs.time_);
+    }
+    //! Non-Equality comparison operator
+    bool operator!=(const local_date_time_base& rhs) const
+    {
+      return !(*this == rhs);
+    }
+    //! Less than comparison operator
+    bool operator<(const local_date_time_base& rhs) const
+    {
+      return time_system_type::is_less(this->time_, rhs.time_);
+    }
+    //! Less than or equal to comparison operator
+    bool operator<=(const local_date_time_base& rhs) const
+    {
+      return (*this < rhs || *this == rhs);
+    }
+    //! Greater than comparison operator
+    bool operator>(const local_date_time_base& rhs) const
+    {
+      return !(*this <= rhs);
+    }
+    //! Greater than or equal to comparison operator
+    bool operator>=(const local_date_time_base& rhs) const
+    {
+      return (*this > rhs || *this == rhs);
+    }
+
+    //! Local_date_time + date_duration 
+    local_date_time_base operator+(const date_duration_type& dd) const
+    {
+      return local_date_time_base(time_system_type::add_days(this->time_,dd), zone_);
+    }
+    //! Local_date_time += date_duration 
+    local_date_time_base operator+=(const date_duration_type& dd)
+    {
+      this->time_ = time_system_type::add_days(this->time_,dd);
+      return *this;
+    }
+    //! Local_date_time - date_duration 
+    local_date_time_base operator-(const date_duration_type& dd) const
+    {
+      return local_date_time_base(time_system_type::subtract_days(this->time_,dd), zone_);
+    }
+    //! Local_date_time -= date_duration 
+    local_date_time_base operator-=(const date_duration_type& dd)
+    {
+      this->time_ = time_system_type::subtract_days(this->time_,dd);
+      return *this;
+    }
+    //! Local_date_time + time_duration 
+    local_date_time_base operator+(const time_duration_type& td) const
+    {
+      return local_date_time_base(time_system_type::add_time_duration(this->time_,td), zone_);
+    }
+    //! Local_date_time += time_duration 
+    local_date_time_base operator+=(const time_duration_type& td) 
+    {
+      this->time_ = time_system_type::add_time_duration(this->time_,td);
+      return *this;
+    }
+    //! Local_date_time - time_duration 
+    local_date_time_base operator-(const time_duration_type& td) const
+    {
+      return local_date_time_base(time_system_type::subtract_time_duration(this->time_,td), zone_);
+    }
+    //! Local_date_time -= time_duration 
+    local_date_time_base operator-=(const time_duration_type& td)
+    {
+      this->time_ = time_system_type::subtract_time_duration(this->time_,td);
+      return *this;
+    }
+    //! local_date_time -= local_date_time --> time_duration_type
+    time_duration_type operator-(const local_date_time_base& rhs) const
+    {
+      return utc_time_type(this->time_) - utc_time_type(rhs.time_);
+    }
+  private:
+    boost::shared_ptr<tz_type> zone_;
+    //bool is_dst_;
+
+    /*! Adjust the passed in time to UTC?
+     */
+    utc_time_type construction_adjustment(utc_time_type t, 
+                                          boost::shared_ptr<tz_type> z,
+                                          bool dst_flag)
+    {
+      if(z != boost::shared_ptr<tz_type>()) {
+        if(dst_flag && z->has_dst()) {
+          t -= z->dst_offset();
+        } // else no adjust
+        t -= z->base_utc_offset();
+      }
+      return t;
+    }
+
+    /*! Simple formatting code -- todo remove this?
+     */
+    std::string zone_as_offset(const time_duration_type& td, 
+                               const std::string& separator) const
+    {
+      std::ostringstream ss;
+      if(td.is_negative()) {
+        // a negative duration is represented as "-[h]h:mm"
+        // we require two digits for the hour. A positive duration 
+        // with the %H flag will always give two digits
+        ss << "-";
+      }
+      else {
+        ss << "+";
+      }
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.hours()) 
+          << separator
+          << std::setw(2) << std::setfill('0')
+          << date_time::absolute_value(td.minutes());
+      return ss.str();
+    }
+  };
+
+  //!Use the default parameters to define local_date_time
+  typedef local_date_time_base<> local_date_time;
+
+} }
+
+
+#endif

+ 24 - 0
ext/boost/date_time/local_time/local_time.hpp

@@ -0,0 +1,24 @@
+#ifndef LOCAL_TIME_LOCAL_TIME_HPP__
+#define LOCAL_TIME_LOCAL_TIME_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/local_time/local_date_time.hpp"
+#include "boost/date_time/local_time/local_time_types.hpp"
+#if !defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/local_time/local_time_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+#include "boost/date_time/local_time/posix_time_zone.hpp"
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+#include "boost/date_time/local_time/tz_database.hpp"
+#include "boost/date_time/local_time/conversion.hpp"
+#include "boost/date_time/time_zone_base.hpp"
+
+
+#endif

+ 186 - 0
ext/boost/date_time/local_time/local_time_io.hpp

@@ -0,0 +1,186 @@
+#ifndef BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
+#define BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/time_facet.hpp>
+#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/local_time/local_date_time.hpp>
+#include <boost/date_time/local_time/posix_time_zone.hpp>
+#include <boost/date_time/local_time/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace local_time {
+
+  typedef boost::date_time::time_facet<local_date_time, wchar_t> wlocal_time_facet;
+  typedef boost::date_time::time_facet<local_date_time, char>     local_time_facet;
+
+  typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,wchar_t> wlocal_time_input_facet;
+  typedef boost::date_time::time_input_facet<local_date_time::utc_time_type,char>     local_time_input_facet;
+
+  //! operator<< for local_date_time - see local_time docs for formatting details
+  template<class CharT, class TraitsT>
+  inline
+  std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os, const local_date_time& ldt)
+  {
+    boost::io::ios_flags_saver iflags(os);
+    typedef local_date_time time_type;//::utc_time_type typename 
+    typedef date_time::time_facet<time_type, CharT> custom_time_facet;
+    typedef std::time_put<CharT> std_time_facet;
+    std::ostreambuf_iterator<CharT> oitr(os);
+
+    if(std::has_facet<custom_time_facet>(os.getloc())) {
+      std::use_facet<custom_time_facet>(os.getloc()).put(oitr, 
+                                                         os, 
+                                                         os.fill(), 
+                                                         ldt);
+    }
+    else {
+      custom_time_facet* f = new custom_time_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(oitr, os, os.fill(), ldt);
+    }
+
+    return os;
+  }
+
+
+  //! input operator for local_date_time
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, local_date_time& ldt)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+    if (strm_sentry) {
+      try {
+        typedef typename local_date_time::utc_time_type utc_time_type;
+        typedef typename date_time::time_input_facet<utc_time_type, CharT> time_input_facet;
+
+        // intermediate objects
+        std::basic_string<CharT> tz_str;
+        utc_time_type pt(not_a_date_time); 
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<time_input_facet>(is.getloc())) {
+          std::use_facet<time_input_facet>(is.getloc()).get_local_time(sit, str_end, is, pt, tz_str);
+        }
+        else {
+          time_input_facet* f = new time_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get_local_time(sit, str_end, is, pt, tz_str);
+        }
+        if(tz_str.empty()) {
+          time_zone_ptr null_ptr;
+          // a null time_zone_ptr creates a local_date_time that is UTC
+          ldt = local_date_time(pt, null_ptr);
+        }
+        else {
+          time_zone_ptr tz_ptr(new posix_time_zone(date_time::convert_string_type<CharT,char>(tz_str)));
+          // the "date & time" constructor expects the time label to *not* be utc.
+          // a posix_tz_string also expects the time label to *not* be utc.
+          ldt = local_date_time(pt.date(), pt.time_of_day(), tz_ptr, local_date_time::EXCEPTION_ON_ERROR);
+        }
+      }
+      catch(...) {
+        // mask tells us what exceptions are turned on
+        std::ios_base::iostate exception_mask = is.exceptions();
+        // if the user wants exceptions on failbit, we'll rethrow our 
+        // date_time exception & set the failbit
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); }
+          catch(std::ios_base::failure&) {} // ignore this one
+          throw; // rethrow original exception
+        }
+        else {
+          // if the user want's to fail quietly, we simply set the failbit
+          is.setstate(std::ios_base::failbit);
+        }
+
+      }
+    }
+    return is;
+  }
+
+  //! output operator for local_time_period
+  template <class CharT, class TraitsT>
+  inline
+  std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os,
+             const boost::local_time::local_time_period& p) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::time_facet<local_date_time, CharT> custom_facet;
+    typedef std::time_put<CharT> std_time_facet;
+    std::ostreambuf_iterator<CharT> oitr(os);
+    if (std::has_facet<custom_facet>(os.getloc())) {
+      std::use_facet<custom_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+    }
+    else {
+      //instantiate a custom facet for dealing with periods since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every time period
+      //if the local did not already exist.  Of course this will be overridden
+      //if the user imbues as some later point.
+      custom_facet* f = new custom_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(oitr, os, os.fill(), p);
+    }
+    return os;
+  }
+
+  //! input operator for local_time_period
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, boost::local_time::local_time_period& tp)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::time_input_facet<local_date_time, CharT> time_input_facet;
+
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<time_input_facet>(is.getloc())) {
+          std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
+        }
+        else {
+          time_input_facet* f = new time_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, tp);
+        }
+      }
+      catch(...) {
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); }
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit);
+        }
+
+      }
+    }
+    return is;
+  }
+
+} } // namespaces
+
+#endif // BOOST_DATE_TIME_LOCAL_TIME_IO_HPP__

+ 52 - 0
ext/boost/date_time/local_time/local_time_types.hpp

@@ -0,0 +1,52 @@
+#ifndef LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
+#define LOCAL_TIME_LOCAL_TIME_TYPES_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/local_time/local_date_time.hpp"
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/time_iterator.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/local_time/date_duration_operators.hpp"
+#endif //BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+
+namespace boost {
+namespace local_time {
+
+  typedef boost::date_time::period<local_date_time, 
+                                   boost::posix_time::time_duration> local_time_period;
+
+  typedef date_time::time_itr<local_date_time> local_time_iterator;
+
+  typedef date_time::second_clock<local_date_time> local_sec_clock; 
+  typedef date_time::microsec_clock<local_date_time> local_microsec_clock;
+  
+  typedef date_time::time_zone_base<posix_time::ptime, char> time_zone;
+  typedef date_time::time_zone_base<posix_time::ptime, wchar_t> wtime_zone;
+
+  //! Shared Pointer for custom_time_zone and posix_time_zone objects
+  typedef boost::shared_ptr<time_zone> time_zone_ptr;
+  typedef boost::shared_ptr<wtime_zone> wtime_zone_ptr;
+ 
+  typedef date_time::time_zone_names_base<char> time_zone_names;
+  typedef date_time::time_zone_names_base<wchar_t> wtime_zone_names;
+
+  //bring special enum values into the namespace
+  using date_time::special_values;
+  using date_time::not_special;
+  using date_time::neg_infin;
+  using date_time::pos_infin;
+  using date_time::not_a_date_time;
+  using date_time::max_date_time;
+  using date_time::min_date_time;
+
+}} // namespaces
+
+#endif // LOCAL_TIME_LOCAL_TIME_TYPES_HPP__

+ 464 - 0
ext/boost/date_time/local_time/posix_time_zone.hpp

@@ -0,0 +1,464 @@
+#ifndef _DATE_TIME_POSIX_TIME_ZONE__
+#define _DATE_TIME_POSIX_TIME_ZONE__ 
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-26 10:39:19 -0500 (Wed, 26 Nov 2008) $
+ */
+
+#include <string>
+#include <sstream>
+#include <stdexcept>
+#include <boost/tokenizer.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <boost/date_time/time_zone_names.hpp>
+#include <boost/date_time/time_zone_base.hpp>
+#include <boost/date_time/local_time/dst_transition_day_rules.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/string_convert.hpp>
+#include <boost/date_time/time_parsing.hpp>
+
+namespace boost{
+namespace local_time{
+
+  //! simple exception for UTC and Daylight savings start/end offsets
+  struct bad_offset : public std::out_of_range
+  {
+    bad_offset(std::string const& msg = std::string()) :
+      std::out_of_range(std::string("Offset out of range: " + msg)) {}
+  };
+  //! simple exception for UTC daylight savings adjustment
+  struct bad_adjustment : public std::out_of_range
+  {
+    bad_adjustment(std::string const& msg = std::string()) :
+      std::out_of_range(std::string("Adjustment out of range: " + msg)) {}
+  };
+  
+  typedef boost::date_time::dst_adjustment_offsets<boost::posix_time::time_duration> dst_adjustment_offsets;
+
+  //! A time zone class constructed from a POSIX time zone string
+  /*! A POSIX time zone string takes the form of:<br>
+   * "std offset dst [offset],start[/time],end[/time]" (w/no spaces)
+   * 'std' specifies the abbrev of the time zone.<br> 
+   * 'offset' is the offset from UTC.<br>
+   * 'dst' specifies the abbrev of the time zone during daylight savings time.<br>
+   * The second offset is how many hours changed during DST. Default=1<br>
+   * 'start' and'end' are the dates when DST goes into (and out of) effect.<br>
+   * 'offset' takes the form of: [+|-]hh[:mm[:ss]] {h=0-23, m/s=0-59}<br>
+   * 'time' and 'offset' take the same form. Time defaults=02:00:00<br>
+   * 'start' and 'end' can be one of three forms:<br>
+   * Mm.w.d {month=1-12, week=1-5 (5 is always last), day=0-6}<br>
+   * Jn {n=1-365 Feb29 is never counted}<br>
+   * n  {n=0-365 Feb29 is counted in leap years}<br>
+   * Example "PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"
+   * <br>
+   * Exceptions will be thrown under these conditions:<br>
+   * An invalid date spec (see date class)<br>
+   * A boost::local_time::bad_offset exception will be thrown for:<br>
+   * A DST start or end offset that is negative or more than 24 hours<br>
+   * A UTC zone that is greater than +12 or less than -12 hours<br>
+   * A boost::local_time::bad_adjustment exception will be thrown for:<br>
+   * A DST adjustment that is 24 hours or more (positive or negative)<br>
+   */
+  template<class CharT>
+  class posix_time_zone_base : public date_time::time_zone_base<posix_time::ptime,CharT> {
+  public:
+    typedef boost::posix_time::time_duration time_duration_type;
+    typedef date_time::time_zone_names_base<CharT> time_zone_names;
+    typedef date_time::time_zone_base<posix_time::ptime,CharT> base_type;
+    typedef typename base_type::string_type string_type;
+    typedef CharT char_type;
+    typedef typename base_type::stringstream_type stringstream_type;
+    typedef boost::char_separator<char_type, std::char_traits<char_type> > char_separator_type;
+    typedef boost::tokenizer<char_separator_type,
+                             typename string_type::const_iterator,
+                             string_type> tokenizer_type;
+    typedef typename boost::tokenizer<char_separator_type,
+                             typename string_type::const_iterator,
+                             string_type>::iterator tokenizer_iterator_type;
+
+    //! Construct from a POSIX time zone string
+    posix_time_zone_base(const string_type& s) : 
+      //zone_names_("std_name","std_abbrev","no-dst","no-dst"),
+      zone_names_(),
+      has_dst_(false), 
+      base_utc_offset_(posix_time::hours(0)),
+      dst_offsets_(posix_time::hours(0),posix_time::hours(0),posix_time::hours(0)),
+      dst_calc_rules_()
+    {
+#ifdef __HP_aCC
+      // Work around bug in aC++ compiler: see QXCR1000880488 in the
+      // HP bug tracking system
+      const char_type sep_chars[2] = {',',0};
+#else
+      const char_type sep_chars[2] = {','};
+#endif
+      char_separator_type sep(sep_chars);
+      tokenizer_type tokens(s, sep);
+      tokenizer_iterator_type it = tokens.begin();
+      calc_zone(*it++);
+      if(has_dst_){
+        string_type tmp_str = *it++;
+        calc_rules(tmp_str, *it);
+      }
+    } 
+    virtual ~posix_time_zone_base() {};
+    //!String for the zone when not in daylight savings (eg: EST)
+    virtual string_type std_zone_abbrev()const
+    {
+      return zone_names_.std_zone_abbrev();
+    }
+    //!String for the timezone when in daylight savings (eg: EDT)
+    /*! For those time zones that have no DST, an empty string is used */
+    virtual string_type dst_zone_abbrev() const
+    {
+      return zone_names_.dst_zone_abbrev();
+    }
+    //!String for the zone when not in daylight savings (eg: Eastern Standard Time)
+    /*! The full STD name is not extracted from the posix time zone string. 
+     * Therefore, the STD abbreviation is used in it's place */
+    virtual string_type std_zone_name()const
+    {
+      return zone_names_.std_zone_name();
+    }
+    //!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
+    /*! The full DST name is not extracted from the posix time zone string. 
+     * Therefore, the STD abbreviation is used in it's place. For time zones 
+     * that have no DST, an empty string is used */
+    virtual string_type dst_zone_name()const
+    {
+      return zone_names_.dst_zone_name();
+    }
+    //! True if zone uses daylight savings adjustments otherwise false
+    virtual bool has_dst()const
+    {
+      return has_dst_;
+    }
+    //! Local time that DST starts -- NADT if has_dst is false
+    virtual posix_time::ptime dst_local_start_time(gregorian::greg_year y)const
+    {
+      gregorian::date d(gregorian::not_a_date_time);
+      if(has_dst_)
+      {
+        d = dst_calc_rules_->start_day(y);
+      }
+      return posix_time::ptime(d, dst_offsets_.dst_start_offset_);
+    }
+    //! Local time that DST ends -- NADT if has_dst is false
+    virtual posix_time::ptime dst_local_end_time(gregorian::greg_year y)const
+    {
+      gregorian::date d(gregorian::not_a_date_time);
+      if(has_dst_)
+      {
+        d = dst_calc_rules_->end_day(y);
+      }
+      return posix_time::ptime(d, dst_offsets_.dst_end_offset_);
+    }
+    //! Base offset from UTC for zone (eg: -07:30:00)
+    virtual time_duration_type base_utc_offset()const
+    {
+      return base_utc_offset_;
+    }
+    //! Adjustment forward or back made while DST is in effect
+    virtual time_duration_type dst_offset()const
+    {
+      return dst_offsets_.dst_adjust_;
+    }
+
+    //! Returns a POSIX time_zone string for this object
+    virtual string_type to_posix_string() const
+    {
+      // std offset dst [offset],start[/time],end[/time] - w/o spaces
+      stringstream_type ss;
+      ss.fill('0');
+      boost::shared_ptr<dst_calc_rule> no_rules;
+      // std
+      ss << std_zone_abbrev();
+      // offset
+      if(base_utc_offset().is_negative()) {
+        // inverting the sign guarantees we get two digits
+        ss << '-' << std::setw(2) << base_utc_offset().invert_sign().hours();
+      }
+      else {
+        ss << '+' << std::setw(2) << base_utc_offset().hours();
+      }
+      if(base_utc_offset().minutes() != 0 || base_utc_offset().seconds() != 0) {
+        ss << ':' << std::setw(2) << base_utc_offset().minutes();
+        if(base_utc_offset().seconds() != 0) {
+          ss << ':' << std::setw(2) << base_utc_offset().seconds();
+        }
+      }
+      if(dst_calc_rules_ != no_rules) {
+        // dst
+        ss << dst_zone_abbrev();
+        // dst offset
+        if(dst_offset().is_negative()) {
+        // inverting the sign guarantees we get two digits
+          ss << '-' << std::setw(2) << dst_offset().invert_sign().hours();
+        }
+        else {
+          ss << '+' << std::setw(2) << dst_offset().hours();
+        }
+        if(dst_offset().minutes() != 0 || dst_offset().seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offset().minutes();
+          if(dst_offset().seconds() != 0) {
+            ss << ':' << std::setw(2) << dst_offset().seconds();
+          }
+        }
+        // start/time
+        ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->start_rule_as_string()) << '/'
+           << std::setw(2) << dst_offsets_.dst_start_offset_.hours() << ':'
+           << std::setw(2) << dst_offsets_.dst_start_offset_.minutes();
+        if(dst_offsets_.dst_start_offset_.seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offsets_.dst_start_offset_.seconds();
+        }
+        // end/time
+        ss << ',' << date_time::convert_string_type<char, char_type>(dst_calc_rules_->end_rule_as_string()) << '/'
+           << std::setw(2) << dst_offsets_.dst_end_offset_.hours() << ':'
+           << std::setw(2) << dst_offsets_.dst_end_offset_.minutes();
+        if(dst_offsets_.dst_end_offset_.seconds() != 0) {
+          ss << ':' << std::setw(2) << dst_offsets_.dst_end_offset_.seconds();
+        }
+      }
+
+      return ss.str();
+    }
+  private:
+    time_zone_names zone_names_;
+    bool has_dst_;
+    time_duration_type base_utc_offset_;
+    dst_adjustment_offsets dst_offsets_;
+    boost::shared_ptr<dst_calc_rule> dst_calc_rules_;
+
+    /*! Extract time zone abbreviations for STD & DST as well
+     * as the offsets for the time shift that occurs and how
+     * much of a shift. At this time full time zone names are
+     * NOT extracted so the abbreviations are used in their place */
+    void calc_zone(const string_type& obj){
+      const char_type empty_string[2] = {'\0'};
+      stringstream_type ss(empty_string);
+      typename string_type::const_pointer sit = obj.c_str(), obj_end = sit + obj.size();
+      string_type l_std_zone_abbrev, l_dst_zone_abbrev;
+
+      // get 'std' name/abbrev
+      while(std::isalpha(*sit)){
+        ss << *sit++;
+      }
+      l_std_zone_abbrev = ss.str(); 
+      ss.str(empty_string);
+
+      // get UTC offset
+      if(sit != obj_end){
+        // get duration
+        while(sit != obj_end && !std::isalpha(*sit)){
+          ss << *sit++;
+        }
+        base_utc_offset_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str()); 
+        ss.str(empty_string);
+
+        // base offset must be within range of -12 hours to +12 hours
+        if(base_utc_offset_ < time_duration_type(-12,0,0) ||
+          base_utc_offset_ > time_duration_type(12,0,0))
+        {
+          boost::throw_exception(bad_offset(posix_time::to_simple_string(base_utc_offset_)));
+        }
+      }
+
+      // get DST data if given
+      if(sit != obj_end){
+        has_dst_ = true;
+    
+        // get 'dst' name/abbrev
+        while(sit != obj_end && std::isalpha(*sit)){
+          ss << *sit++;
+        }
+        l_dst_zone_abbrev = ss.str(); 
+        ss.str(empty_string);
+
+        // get DST offset if given
+        if(sit != obj_end){
+          // get duration
+          while(sit != obj_end && !std::isalpha(*sit)){
+            ss << *sit++;
+          }
+          dst_offsets_.dst_adjust_ = date_time::str_from_delimited_time_duration<time_duration_type,char_type>(ss.str());  
+          ss.str(empty_string);
+        }
+        else{ // default DST offset
+          dst_offsets_.dst_adjust_ = posix_time::hours(1);
+        }
+
+        // adjustment must be within +|- 1 day
+        if(dst_offsets_.dst_adjust_ <= time_duration_type(-24,0,0) ||
+            dst_offsets_.dst_adjust_ >= time_duration_type(24,0,0))
+        {
+          boost::throw_exception(bad_adjustment(posix_time::to_simple_string(dst_offsets_.dst_adjust_)));
+        }
+      }
+      // full names not extracted so abbrevs used in their place
+      zone_names_ = time_zone_names(l_std_zone_abbrev, l_std_zone_abbrev, l_dst_zone_abbrev, l_dst_zone_abbrev);
+    }
+
+    void calc_rules(const string_type& start, const string_type& end){
+#ifdef __HP_aCC
+      // Work around bug in aC++ compiler: see QXCR1000880488 in the
+      // HP bug tracking system
+      const char_type sep_chars[2] = {'/',0};
+#else
+      const char_type sep_chars[2] = {'/'};
+#endif
+      char_separator_type sep(sep_chars);
+      tokenizer_type st_tok(start, sep);
+      tokenizer_type et_tok(end, sep);
+      tokenizer_iterator_type sit = st_tok.begin();
+      tokenizer_iterator_type eit = et_tok.begin();
+
+      // generate date spec
+      char_type x = string_type(*sit).at(0);
+      if(x == 'M'){
+        M_func(*sit, *eit);
+      }
+      else if(x == 'J'){
+        julian_no_leap(*sit, *eit);
+      }
+      else{
+        julian_day(*sit, *eit);
+      }
+
+      ++sit;
+      ++eit;
+      // generate durations
+      // starting offset
+      if(sit != st_tok.end()){
+        dst_offsets_.dst_start_offset_ =  date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*sit);
+      }
+      else{
+        // default
+        dst_offsets_.dst_start_offset_ = posix_time::hours(2);
+      }
+      // start/end offsets must fall on given date
+      if(dst_offsets_.dst_start_offset_ < time_duration_type(0,0,0) ||
+          dst_offsets_.dst_start_offset_ >= time_duration_type(24,0,0))
+      {
+        boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_start_offset_)));
+      }
+
+      // ending offset
+      if(eit != et_tok.end()){
+        dst_offsets_.dst_end_offset_ =  date_time::str_from_delimited_time_duration<time_duration_type,char_type>(*eit);
+      }
+      else{
+        // default
+        dst_offsets_.dst_end_offset_ = posix_time::hours(2);
+      }
+      // start/end offsets must fall on given date
+      if(dst_offsets_.dst_end_offset_ < time_duration_type(0,0,0) ||
+        dst_offsets_.dst_end_offset_ >= time_duration_type(24,0,0))
+      {
+        boost::throw_exception(bad_offset(posix_time::to_simple_string(dst_offsets_.dst_end_offset_)));
+      }
+    }
+
+    /* Parses out a start/end date spec from a posix time zone string.
+     * Date specs come in three possible formats, this function handles
+     * the 'M' spec. Ex "M2.2.4" => 2nd month, 2nd week, 4th day .
+     */
+    void M_func(const string_type& s, const string_type& e){
+      typedef gregorian::nth_kday_of_month nkday;
+      unsigned short sm=0,sw=0,sd=0,em=0,ew=0,ed=0; // start/end month,week,day
+#ifdef __HP_aCC
+      // Work around bug in aC++ compiler: see QXCR1000880488 in the
+      // HP bug tracking system
+      const char_type sep_chars[3] = {'M','.',0};
+#else
+      const char_type sep_chars[3] = {'M','.'};
+#endif
+      char_separator_type sep(sep_chars);
+      tokenizer_type stok(s, sep), etok(e, sep);
+      
+      tokenizer_iterator_type it = stok.begin();
+      sm = lexical_cast<unsigned short>(*it++);
+      sw = lexical_cast<unsigned short>(*it++);
+      sd = lexical_cast<unsigned short>(*it);
+     
+      it = etok.begin();
+      em = lexical_cast<unsigned short>(*it++);
+      ew = lexical_cast<unsigned short>(*it++);
+      ed = lexical_cast<unsigned short>(*it);
+
+      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+        new nth_kday_dst_rule(
+          nth_last_dst_rule::start_rule(
+            static_cast<nkday::week_num>(sw),sd,sm), 
+          nth_last_dst_rule::start_rule(
+            static_cast<nkday::week_num>(ew),ed,em) 
+          )
+      );
+    }
+    
+    //! Julian day. Feb29 is never counted, even in leap years
+    // expects range of 1-365
+    void julian_no_leap(const string_type& s, const string_type& e){
+      typedef gregorian::gregorian_calendar calendar;
+      const unsigned short year = 2001; // Non-leap year
+      unsigned short sm=1;
+      int sd=0;
+      sd = lexical_cast<int>(s.substr(1)); // skip 'J'
+      while(sd >= calendar::end_of_month_day(year,sm)){
+        sd -= calendar::end_of_month_day(year,sm++);
+      }
+      unsigned short em=1;
+      int ed=0;
+      ed = lexical_cast<int>(e.substr(1)); // skip 'J'
+      while(ed > calendar::end_of_month_day(year,em)){
+        ed -= calendar::end_of_month_day(year,em++);
+      }
+
+      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+        new partial_date_dst_rule(
+          partial_date_dst_rule::start_rule(
+            sd, static_cast<date_time::months_of_year>(sm)), 
+          partial_date_dst_rule::end_rule(
+            ed, static_cast<date_time::months_of_year>(em)) 
+          )
+      );
+    }
+
+    //! Julian day. Feb29 is always counted, but exception thrown in non-leap years
+    // expects range of 0-365
+    void julian_day(const string_type& s, const string_type& e){
+      int sd=0, ed=0;
+      sd = lexical_cast<int>(s);
+      ed = lexical_cast<int>(e);
+      dst_calc_rules_ = shared_ptr<dst_calc_rule>(
+        new partial_date_dst_rule(
+          partial_date_dst_rule::start_rule(++sd),// args are 0-365
+          partial_date_dst_rule::end_rule(++ed) // pd expects 1-366
+          )
+      );
+    }
+
+    //! helper function used when throwing exceptions
+    static std::string td_as_string(const time_duration_type& td)
+    {
+      std::string s;
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+      s = posix_time::to_simple_string(td);
+#else
+      std::stringstream ss;
+      ss << td;
+      s = ss.str();
+#endif
+      return s;
+    }
+  };
+
+  typedef posix_time_zone_base<char> posix_time_zone;
+  
+} } // namespace boost::local_time
+
+
+#endif // _DATE_TIME_POSIX_TIME_ZONE__ 

+ 32 - 0
ext/boost/date_time/local_time/tz_database.hpp

@@ -0,0 +1,32 @@
+#ifndef BOOST_DATE_TIME_TZ_DATABASE_HPP__
+#define BOOST_DATE_TIME_TZ_DATABASE_HPP__
+
+/* Copyright (c) 2003-2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include <string>
+#include "boost/date_time/local_time/custom_time_zone.hpp"
+#include "boost/date_time/local_time/dst_transition_day_rules.hpp"
+#include "boost/date_time/tz_db_base.hpp"
+
+
+namespace boost {
+namespace local_time {
+
+  using date_time::data_not_accessible; 
+  using date_time::bad_field_count; 
+
+  //! Object populated with boost::shared_ptr<time_zone_base> objects
+  /*! Object populated with boost::shared_ptr<time_zone_base> objects
+   * Database is populated from specs stored in external csv file. See
+   * date_time::tz_db_base for greater detail */
+  typedef date_time::tz_db_base<custom_time_zone, nth_kday_dst_rule> tz_database;
+
+}} // namespace
+
+#endif // BOOST_DATE_TIME_TZ_DATABASE_HPP__
+

+ 218 - 0
ext/boost/date_time/local_time_adjustor.hpp

@@ -0,0 +1,218 @@
+#ifndef DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
+#define DATE_TIME_LOCAL_TIME_ADJUSTOR_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+/*! @file local_time_adjustor.hpp
+  Time adjustment calculations for local times
+*/
+
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/date_generators.hpp>
+#include <boost/date_time/dst_rules.hpp>
+#include <boost/date_time/time_defs.hpp> // boost::date_time::dst_flags
+#include <boost/date_time/special_defs.hpp> // not_a_date_time
+
+namespace boost {
+  namespace date_time {
+
+
+    //! Provides a base offset adjustment from utc
+    template<class time_duration_type, 
+             short hours, unsigned short minutes = 0>
+    class utc_adjustment 
+    {
+    public:
+      static time_duration_type local_to_utc_base_offset()
+      {
+        time_duration_type td(hours,minutes,0);
+        return td.invert_sign();
+      }
+      static time_duration_type utc_to_local_base_offset()
+      {
+        return time_duration_type(hours,minutes,0);
+      }
+    };
+
+
+
+    //! Allow sliding utc adjustment with fixed dst rules
+    template<class time_type, class dst_rules>
+    class dynamic_local_time_adjustor : public dst_rules
+    {
+    public:
+      typedef typename time_type::time_duration_type time_duration_type;
+      typedef typename time_type::date_type date_type;
+
+      dynamic_local_time_adjustor(time_duration_type utc_offset) :
+        utc_offset_(utc_offset)
+      {}
+      
+      //! Presumes local time
+      time_duration_type utc_offset(bool is_dst) 
+      { 
+        if (is_dst) {
+          return utc_offset_ + this->dst_offset();
+        }
+        else {
+          return utc_offset_;
+        }
+
+      }
+    private:
+      time_duration_type utc_offset_;
+
+    };
+
+
+
+    //! Embed the rules for local time adjustments at compile time
+    template<class time_type, class dst_rules, class utc_offset_rules>
+    class static_local_time_adjustor: public dst_rules, public utc_offset_rules
+    {
+    public:
+      typedef typename time_type::time_duration_type time_duration_type;
+      typedef typename time_type::date_type date_type;
+
+      //! Calculates the offset from a utc time to local based on dst and utc offset
+      /*! @param t UTC time to calculate offset to local time
+       *  This adjustment depends on the following observations about the
+       *  workings of the DST boundary offset.  Since UTC time labels are
+       *  monotonically increasing we can determine if a given local time
+       *  is in DST or not and therefore adjust the offset appropriately.
+       * 
+       *  The logic is as follows.  Starting with UTC time use the offset to
+       *  create a label for an non-dst adjusted local time.  Then call
+       *  dst_rules::local_is_dst with the non adjust local time.  The
+       *  results of this function will either unabiguously decide that
+       *  the initial local time is in dst or return an illegal or
+       *  ambiguous result.  An illegal result only occurs at the end
+       *  of dst (where labels are skipped) and indicates that dst has
+       *  ended.  An ambiguous result means that we need to recheck by
+       *  making a dst adjustment and then rechecking.  If the dst offset
+       *  is added to the utc time and the recheck proves non-ambiguous
+       *  then we are past the boundary.  If it is still ambiguous then
+       *  we are ahead of the boundary and dst is still in effect.
+       *
+       *  TODO -- check if all dst offsets are positive.  If not then
+       *  the algorithm needs to check for this and reverse the 
+       *  illegal/ambiguous logic.
+       */
+      static time_duration_type utc_to_local_offset(const time_type& t)
+      {
+        //get initial local time guess by applying utc offset
+        time_type initial = t + utc_offset_rules::utc_to_local_base_offset();
+        time_is_dst_result dst_flag = 
+          dst_rules::local_is_dst(initial.date(), initial.time_of_day());
+        switch(dst_flag) {
+        case is_in_dst:        return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+        case is_not_in_dst:    return utc_offset_rules::utc_to_local_base_offset();
+        case invalid_time_label:return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+        case ambiguous: {
+          time_type retry = initial + dst_rules::dst_offset();
+          dst_flag = dst_rules::local_is_dst(retry.date(), retry.time_of_day());
+          //if still ambibuous then the utc time still translates to a dst time
+          if (dst_flag == ambiguous) {
+            return utc_offset_rules::utc_to_local_base_offset() + dst_rules::dst_offset();
+          }
+          // we are past the dst boundary
+          else {
+            return utc_offset_rules::utc_to_local_base_offset();
+          }
+        }
+        }//case
+        //TODO  better exception type
+        boost::throw_exception(std::out_of_range("Unreachable case"));
+        BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
+      }
+
+      //! Get the offset to UTC given a local time
+      static time_duration_type local_to_utc_offset(const time_type& t, 
+                                                    date_time::dst_flags dst=date_time::calculate) 
+      {
+        switch (dst) {
+        case is_dst:
+          return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
+        case not_dst:
+          return utc_offset_rules::local_to_utc_base_offset();
+        case calculate:
+          time_is_dst_result res = 
+            dst_rules::local_is_dst(t.date(), t.time_of_day());
+          switch(res) {
+          case is_in_dst:      return utc_offset_rules::local_to_utc_base_offset() - dst_rules::dst_offset();
+          case is_not_in_dst:      return utc_offset_rules::local_to_utc_base_offset();
+          case ambiguous:          return utc_offset_rules::local_to_utc_base_offset();
+          case invalid_time_label: break;
+          }
+        }
+        boost::throw_exception(std::out_of_range("Time label invalid"));
+        BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return time_duration_type(not_a_date_time)); // should never reach
+      }
+
+
+    private:
+
+    };
+
+    void dummy_to_prevent_msvc6_ice(); //why ask why?
+
+    //! Template that simplifies the creation of local time calculator 
+    /*! Use this template to create the timezone to utc convertors as required.
+     * 
+     *  This class will also work for other regions that don't use dst and
+     *  have a utc offset which is an integral number of hours.
+     *
+     *  <b>Template Parameters</b>
+     *  -time_type  -- Time class to use
+     *  -utc_offset -- Number hours local time is adjust from utc
+     *  -use_dst -- true (default) if region uses dst, false otherwise
+     *  For example:
+     *  @code
+     *  //eastern timezone is utc-5
+     typedef date_time::local_adjustor<ptime, -5, us_dst> us_eastern;
+     typedef date_time::local_adjustor<ptime, -6, us_dst> us_central;
+     typedef date_time::local_adjustor<ptime, -7, us_dst> us_mountain;
+     typedef date_time::local_adjustor<ptime, -8, us_dst> us_pacific;
+     typedef date_time::local_adjustor<ptime, -7, no_dst> us_arizona;
+     @endcode
+      
+    */
+    template<class time_type, short utc_offset, class dst_rule>
+    class local_adjustor
+    {
+    public:
+      typedef typename time_type::time_duration_type time_duration_type;
+      typedef typename time_type::date_type date_type;
+      typedef static_local_time_adjustor<time_type, 
+                                         dst_rule,
+                                         utc_adjustment<time_duration_type, 
+                                                        utc_offset> > dst_adjustor;
+      //! Convert a utc time to local time
+      static time_type utc_to_local(const time_type& t)
+      {
+        time_duration_type td = dst_adjustor::utc_to_local_offset(t);
+        return t + td;
+      }
+      //! Convert a local time to utc
+      static time_type local_to_utc(const time_type& t, 
+                                    date_time::dst_flags dst=date_time::calculate)
+      {
+        time_duration_type td = dst_adjustor::local_to_utc_offset(t, dst);
+        return t + td;
+      }
+    };
+
+
+  } } //namespace date_time
+
+
+
+#endif

+ 193 - 0
ext/boost/date_time/local_timezone_defs.hpp

@@ -0,0 +1,193 @@
+#ifndef DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
+#define DATE_TIME_LOCAL_TIMEZONE_DEFS_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-11-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include "boost/date_time/dst_rules.hpp"
+
+namespace boost {
+  namespace date_time {
+
+    // Configurations for common dst rules cases:
+    // See http://www.wharton.co.uk/Support/sup_dst.htm for more
+    // information on how various locales use dst rules
+
+    //! Specification for daylight savings start rules in US
+    /*! This class is used to configure dst_calc_engine template typically
+        as follows:
+        @code
+          using namespace boost::gregorian;
+          using namespace boost::posix_time;
+          typedef us_dst_trait<date> us_dst_traits;
+          typedef boost::date_time::dst_calc_engine<date, time_duration, 
+                                                    us_dst_traits>  
+                                                    us_dst_calc;
+          //calculate the 2002 transition day of USA April 7 2002
+          date dst_start = us_dst_calc::local_dst_start_day(2002); 
+
+          //calculate the 2002 transition day of USA Oct 27 2002
+          date dst_end = us_dst_calc::local_dst_end_day(2002); 
+                                                    
+          //check if a local time is in dst or not -- posible answers
+          //are yes, no, invalid time label, ambiguous
+          ptime t(...some time...);  
+          if (us_dst::local_is_dst(t.date(), t.time_of_day()) 
+              == boost::date_time::is_not_in_dst) 
+          {
+
+          }
+
+        @endcode
+        This generates a type suitable for the calculation of dst 
+        transitions for the United States.  Of course other templates
+        can be used for other locales.
+
+    */
+
+     template<class date_type>
+     struct us_dst_trait
+     {
+       typedef typename date_type::day_of_week_type day_of_week_type;
+       typedef typename date_type::month_type month_type;
+       typedef typename date_type::year_type year_type;
+       typedef date_time::nth_kday_of_month<date_type> start_rule_functor;
+       typedef date_time::first_kday_of_month<date_type> end_rule_functor;
+       typedef date_time::first_kday_of_month<date_type> start_rule_functor_pre2007;
+       typedef date_time::last_kday_of_month<date_type> end_rule_functor_pre2007;
+       static day_of_week_type start_day(year_type) {return Sunday;}
+       static month_type start_month(year_type y) 
+       {
+         if (y < 2007) return Apr;
+         return Mar;
+       }
+       static day_of_week_type end_day(year_type) {return Sunday;}
+       static month_type end_month(year_type y) 
+       {
+         if (y < 2007) return Oct;
+         return Nov;
+       }
+       static date_type local_dst_start_day(year_type year)
+       {
+         if (year < 2007) {
+           start_rule_functor_pre2007 start1(start_day(year), 
+                                             start_month(year));
+           return start1.get_date(year);
+         }
+         start_rule_functor start(start_rule_functor::second,
+                                  start_day(year), 
+                                  start_month(year));
+         return start.get_date(year);
+          
+       }
+       static date_type local_dst_end_day(year_type year)
+       {
+         if (year < 2007) {
+           end_rule_functor_pre2007 end_rule(end_day(year), 
+                                             end_month(year));
+           return end_rule.get_date(year);
+         }
+         end_rule_functor end(end_day(year), 
+                              end_month(year));
+         return end.get_date(year);      
+       }
+       static int dst_start_offset_minutes() { return 120;}
+       static int dst_end_offset_minutes() { return 120; }
+       static int dst_shift_length_minutes() { return 60; }
+     };
+
+    //!Rules for daylight savings start in the EU (Last Sun in Mar)
+    /*!These amount to the following:
+      - Start of dst day is last Sunday in March
+      - End day of dst is last Sunday in Oct
+      - Going forward switch time is 2:00 am (offset 120 minutes)
+      - Going back switch time is 3:00 am (off set 180 minutes)
+      - Shift duration is one hour (60 minutes)
+    */
+    template<class date_type>
+    struct eu_dst_trait
+    {
+      typedef typename date_type::day_of_week_type day_of_week_type;
+      typedef typename date_type::month_type month_type;
+      typedef typename date_type::year_type year_type;
+      typedef date_time::last_kday_of_month<date_type> start_rule_functor;
+      typedef date_time::last_kday_of_month<date_type> end_rule_functor;
+      static day_of_week_type start_day(year_type) {return Sunday;}
+      static month_type start_month(year_type) {return Mar;}
+      static day_of_week_type end_day(year_type) {return Sunday;}
+      static month_type end_month(year_type) {return Oct;}
+      static int dst_start_offset_minutes() { return 120;}
+      static int dst_end_offset_minutes() { return 180; }
+      static int dst_shift_length_minutes() { return 60; }
+      static date_type local_dst_start_day(year_type year)
+      {
+        start_rule_functor start(start_day(year), 
+                                 start_month(year));
+        return start.get_date(year);      
+      }
+      static date_type local_dst_end_day(year_type year)
+      {
+        end_rule_functor end(end_day(year), 
+                             end_month(year));
+        return end.get_date(year);      
+      }
+    };
+
+    //! Alternative dst traits for some parts of the United Kingdom
+    /* Several places in the UK use EU start and end rules for the 
+       day, but different local conversion times (eg: forward change at 1:00 
+       am local and  backward change at 2:00 am dst instead of 2:00am 
+       forward and 3:00am back for the EU).
+    */
+    template<class date_type>
+    struct uk_dst_trait : public eu_dst_trait<date_type>
+    {
+      static int dst_start_offset_minutes() { return 60;}
+      static int dst_end_offset_minutes() { return 120; }
+      static int dst_shift_length_minutes() { return 60; }
+    };
+
+    //Rules for Adelaide Australia
+    template<class date_type>
+    struct acst_dst_trait
+    {
+      typedef typename date_type::day_of_week_type day_of_week_type;
+      typedef typename date_type::month_type month_type;
+      typedef typename date_type::year_type year_type;
+      typedef date_time::last_kday_of_month<date_type> start_rule_functor;
+      typedef date_time::last_kday_of_month<date_type> end_rule_functor;
+      static day_of_week_type start_day(year_type) {return Sunday;}
+      static month_type start_month(year_type) {return Oct;}
+      static day_of_week_type end_day(year_type) {return Sunday;}
+      static month_type end_month(year_type) {return Mar;}
+      static int dst_start_offset_minutes() { return 120;}
+      static int dst_end_offset_minutes() { return 180; }
+      static int dst_shift_length_minutes() { return 60; }
+      static date_type local_dst_start_day(year_type year)
+      {
+        start_rule_functor start(start_day(year), 
+                                 start_month(year));
+        return start.get_date(year);      
+      }
+      static date_type local_dst_end_day(year_type year)
+      {
+        end_rule_functor end(end_day(year), 
+                             end_month(year));
+        return end.get_date(year);      
+      }
+    };
+    
+    
+
+
+
+
+} } //namespace boost::date_time
+
+
+#endif

+ 31 - 0
ext/boost/date_time/locale_config.hpp

@@ -0,0 +1,31 @@
+#ifndef DATE_TIME_LOCALE_CONFIG_HPP___
+#define DATE_TIME_LOCALE_CONFIG_HPP___
+
+/* Copyright (c) 2002-2006 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+// This file configures whether the library will support locales and hence
+// iostream based i/o.  Even if a compiler has some support for locales,
+// any failure to be compatible gets the compiler on the exclusion list.
+//
+// At the moment this is defined for MSVC 6 and any compiler that
+// defines BOOST_NO_STD_LOCALE (gcc 2.95.x)
+
+#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE
+#include "boost/detail/workaround.hpp"
+
+//This file basically becomes a noop if locales are not properly supported
+#if (defined(BOOST_NO_STD_LOCALE)  \
+ || (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \
+ || (BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x581 )) ) )
+#define BOOST_DATE_TIME_NO_LOCALE
+#endif
+
+
+#endif
+

+ 127 - 0
ext/boost/date_time/microsec_time_clock.hpp

@@ -0,0 +1,127 @@
+#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
+#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 07:36:43 -0400 (Thu, 04 Jun 2009) $
+ */
+
+
+/*! @file microsec_time_clock.hpp
+  This file contains a high resolution time clock implementation.
+*/
+
+#include <boost/cstdint.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/date_time/compiler_config.hpp>
+#include <boost/date_time/c_time.hpp>
+#include <boost/date_time/time_clock.hpp>
+#include <boost/date_time/filetime_functions.hpp>
+
+#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+
+namespace boost {
+namespace date_time {
+
+  //! A clock providing microsecond level resolution
+  /*! A high precision clock that measures the local time
+   *  at a resolution up to microseconds and adjusts to the
+   *  resolution of the time system.  For example, for the
+   *  a library configuration with nano second resolution,
+   *  the last 3 places of the fractional seconds will always
+   *  be 000 since there are 1000 nano-seconds in a micro second.
+   */
+  template<class time_type>
+  class microsec_clock
+  {
+  private:
+    //! Type for the function used to convert time_t to tm
+    typedef std::tm* (*time_converter)(const std::time_t*, std::tm*);
+
+  public:
+    typedef typename time_type::date_type date_type;
+    typedef typename time_type::time_duration_type time_duration_type;
+    typedef typename time_duration_type::rep_type resolution_traits_type;
+
+    //! return a local time object for the given zone, based on computer clock
+    //JKG -- looks like we could rewrite this against universal_time
+    template<class time_zone_type>
+    static time_type local_time(shared_ptr<time_zone_type> tz_ptr)
+    {
+      typedef typename time_type::utc_time_type utc_time_type;
+      typedef second_clock<utc_time_type> second_clock;
+      // we'll need to know the utc_offset this machine has
+      // in order to get a utc_time_type set to utc
+      utc_time_type utc_time = second_clock::universal_time();
+      time_duration_type utc_offset = second_clock::local_time() - utc_time;
+      // use micro clock to get a local time with sub seconds
+      // and adjust it to get a true utc time reading with sub seconds
+      utc_time = microsec_clock<utc_time_type>::local_time() - utc_offset;
+      return time_type(utc_time, tz_ptr);
+    }
+
+    //! Returns the local time based on computer clock settings
+    static time_type local_time()
+    {
+      return create_time(&c_time::localtime);
+    }
+
+    //! Returns the UTC time based on computer settings
+    static time_type universal_time()
+    {
+      return create_time(&c_time::gmtime);
+    }
+
+  private:
+    static time_type create_time(time_converter converter)
+    {
+#ifdef BOOST_HAS_GETTIMEOFDAY
+      timeval tv;
+      gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux.
+      std::time_t t = tv.tv_sec;
+      boost::uint32_t sub_sec = tv.tv_usec;
+#elif defined(BOOST_HAS_FTIME)
+      winapi::file_time ft;
+      winapi::get_system_time_as_file_time(ft);
+      uint64_t micros = winapi::file_time_to_microseconds(ft); // it will not wrap, since ft is the current time
+                                                               // and cannot be before 1970-Jan-01
+      std::time_t t = static_cast<std::time_t>(micros / 1000000UL); // seconds since epoch
+      // microseconds -- static casts supress warnings
+      boost::uint32_t sub_sec = static_cast<boost::uint32_t>(micros % 1000000UL);
+#else
+#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected.
+#endif
+
+      std::tm curr;
+      std::tm* curr_ptr = converter(&t, &curr);
+      date_type d(curr_ptr->tm_year + 1900,
+                  curr_ptr->tm_mon + 1,
+                  curr_ptr->tm_mday);
+
+      //The following line will adjust the fractional second tick in terms
+      //of the current time system.  For example, if the time system
+      //doesn't support fractional seconds then res_adjust returns 0
+      //and all the fractional seconds return 0.
+      int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000);
+
+      time_duration_type td(curr_ptr->tm_hour,
+                            curr_ptr->tm_min,
+                            curr_ptr->tm_sec,
+                            sub_sec * adjust);
+
+      return time_type(d,td);
+    }
+  };
+
+
+} } //namespace date_time
+
+#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+
+
+#endif
+

+ 29 - 0
ext/boost/date_time/parse_format_base.hpp

@@ -0,0 +1,29 @@
+#ifndef DATE_TIME_PARSE_FORMAT_BASE__
+#define DATE_TIME_PARSE_FORMAT_BASE__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+namespace boost {
+namespace date_time {
+
+  //! Enum for distinguishing parsing and formatting options
+  enum month_format_spec {month_as_integer, month_as_short_string, 
+                          month_as_long_string};
+
+  //! Enum for distinguishing the order of Month, Day, & Year.
+  /*! Enum for distinguishing the order in which Month, Day, & Year
+   * will appear in a date string */
+  enum ymd_order_spec {ymd_order_iso,  //order is year-month-day
+                       ymd_order_dmy,  //day-month-year
+                       ymd_order_us};  //order is month-day-year
+
+
+} }//namespace date_time
+
+#endif

+ 377 - 0
ext/boost/date_time/period.hpp

@@ -0,0 +1,377 @@
+#ifndef DATE_TIME_PERIOD_HPP___
+#define DATE_TIME_PERIOD_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! \file period.hpp
+  This file contain the implementation of the period abstraction. This is
+  basically the same idea as a range.  Although this class is intended for
+  use in the time library, it is pretty close to general enough for other
+  numeric uses.
+
+*/
+
+#include "boost/operators.hpp"
+
+
+namespace boost {
+namespace date_time {
+  //!Provides generalized period type useful in date-time systems
+  /*!This template uses a class to represent a time point within the period
+    and another class to represent a duration.  As a result, this class is
+    not appropriate for use when the number and duration representation 
+    are the same (eg: in the regular number domain).
+    
+    A period can be specified by providing either the begining point and 
+    a duration or the begining point and the end point( end is NOT part 
+    of the period but 1 unit past it. A period will be "invalid" if either
+    end_point <= begin_point or the given duration is <= 0. Any valid period 
+    will return false for is_null().
+    
+    Zero length periods are also considered invalid. Zero length periods are
+    periods where the begining and end points are the same, or, the given 
+    duration is zero. For a zero length period, the last point will be one 
+    unit less than the begining point.
+
+    In the case that the begin and last are the same, the period has a 
+    length of one unit.
+    
+    The best way to handle periods is usually to provide a begining point and
+    a duration.  So, day1 + 7 days is a week period which includes all of the
+    first day and 6 more days (eg: Sun to Sat).
+
+   */
+  template<class point_rep, class duration_rep>
+  class period : private
+      boost::less_than_comparable<period<point_rep, duration_rep> 
+    , boost::equality_comparable< period<point_rep, duration_rep> 
+    > >
+  {
+  public:
+    typedef point_rep point_type;
+    typedef duration_rep duration_type;
+
+    period(point_rep first_point, point_rep end_point);
+    period(point_rep first_point, duration_rep len);
+    point_rep begin() const;
+    point_rep end() const;
+    point_rep last() const;
+    duration_rep length() const;
+    bool is_null() const;
+    bool operator==(const period& rhs) const;
+    bool operator<(const period& rhs) const;
+    void shift(const duration_rep& d);
+    void expand(const duration_rep& d);
+    bool contains(const point_rep& point) const;
+    bool contains(const period& other) const;
+    bool intersects(const period& other) const;
+    bool is_adjacent(const period& other) const;
+    bool is_before(const point_rep& point) const;
+    bool is_after(const point_rep& point) const;
+    period intersection(const period& other) const;
+    period merge(const period& other) const;
+    period span(const period& other) const;
+  private:
+    point_rep begin_;
+    point_rep last_;
+  };
+
+  //! create a period from begin to last eg: [begin,end)
+  /*! If end <= begin then the period will be invalid
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  period<point_rep,duration_rep>::period(point_rep first_point, 
+                                         point_rep end_point) : 
+    begin_(first_point), 
+    last_(end_point - duration_rep::unit())
+  {}
+
+  //! create a period as [begin, begin+len)
+  /*! If len is <= 0 then the period will be invalid
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  period<point_rep,duration_rep>::period(point_rep first_point, duration_rep len) :
+    begin_(first_point), 
+    last_(first_point + len-duration_rep::unit())
+  { }
+
+
+  //! Return the first element in the period
+  template<class point_rep, class duration_rep>
+  inline
+  point_rep period<point_rep,duration_rep>::begin() const 
+  {
+    return begin_;
+  }
+
+  //! Return one past the last element 
+  template<class point_rep, class duration_rep>
+  inline
+  point_rep period<point_rep,duration_rep>::end() const 
+  {
+    return last_ + duration_rep::unit();
+  }
+
+  //! Return the last item in the period
+  template<class point_rep, class duration_rep>
+  inline
+  point_rep period<point_rep,duration_rep>::last() const 
+  {
+    return last_;
+  }
+
+  //! True if period is ill formed (length is zero or less)
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::is_null() const 
+  {
+    return end() <= begin_;
+  }
+
+  //! Return the length of the period
+  template<class point_rep, class duration_rep>
+  inline
+  duration_rep period<point_rep,duration_rep>::length() const
+  {
+    if(last_ < begin_){ // invalid period
+      return last_+duration_rep::unit() - begin_;
+    }
+    else{
+      return end() - begin_; // normal case
+    }
+  }
+
+  //! Equality operator
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::operator==(const period& rhs) const 
+  {
+    return  ((begin_ == rhs.begin_) && 
+             (last_ == rhs.last_));
+  }
+
+  //! Strict as defined by rhs.last <= lhs.last
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::operator<(const period& rhs) const 
+  {
+    return (last_ < rhs.begin_);
+  } 
+
+
+  //! Shift the start and end by the specified amount
+  template<class point_rep, class duration_rep>
+  inline
+  void period<point_rep,duration_rep>::shift(const duration_rep& d)
+  {
+    begin_ = begin_ + d;
+    last_  = last_  + d;
+  }
+
+  /** Expands the size of the period by the duration on both ends.
+   *
+   *So before expand 
+   *@code
+   *
+   *         [-------]
+   * ^   ^   ^   ^   ^   ^  ^
+   * 1   2   3   4   5   6  7
+   * 
+   *@endcode
+   * After expand(2)
+   *@code
+   *
+   * [----------------------]
+   * ^   ^   ^   ^   ^   ^  ^
+   * 1   2   3   4   5   6  7
+   * 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  void period<point_rep,duration_rep>::expand(const duration_rep& d)
+  {
+    begin_ = begin_ - d;
+    last_  = last_  + d;
+  }
+
+  //! True if the point is inside the period, zero length periods contain no points
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::contains(const point_rep& point) const 
+  {
+    return ((point >= begin_) &&
+            (point <= last_));
+  }
+
+
+  //! True if this period fully contains (or equals) the other period
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::contains(const period<point_rep,duration_rep>& other) const
+  {
+    return ((begin_ <= other.begin_) && (last_ >= other.last_));
+  }
+
+
+  //! True if periods are next to each other without a gap.
+  /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent
+   * with either of p1 or p2.
+   *@code
+   *   [-p1-)
+   *        [-p2-)
+   *          [-p3-) 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  bool 
+  period<point_rep,duration_rep>::is_adjacent(const period<point_rep,duration_rep>& other) const 
+  {
+    return (other.begin() == end() ||
+            begin_ == other.end());
+  }
+
+
+  //! True if all of the period is prior or t < start
+  /* In the example below only point 1 would evaluate to true.
+   *@code
+   *     [---------])
+   * ^   ^    ^     ^   ^
+   * 1   2    3     4   5
+   * 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  bool 
+  period<point_rep,duration_rep>::is_after(const point_rep& t) const 
+  { 
+    if (is_null()) 
+    {
+      return false; //null period isn't after
+    }
+    
+    return t < begin_;
+  }
+
+  //! True if all of the period is prior to the passed point or end <= t
+  /* In the example below points 4 and 5 return true.
+   *@code
+   *     [---------])
+   * ^   ^    ^     ^   ^
+   * 1   2    3     4   5
+   * 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  bool 
+  period<point_rep,duration_rep>::is_before(const point_rep& t) const 
+  { 
+    if (is_null()) 
+    {
+      return false;  //null period isn't before anything
+    }
+    
+    return last_ < t;
+  }
+
+
+  //! True if the periods overlap in any way
+  /* In the example below p1 intersects with p2, p4, and p6.
+   *@code
+   *       [---p1---)
+   *             [---p2---)
+   *                [---p3---) 
+   *  [---p4---) 
+   * [-p5-) 
+   *         [-p6-) 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  bool period<point_rep,duration_rep>::intersects(const period<point_rep,duration_rep>& other) const 
+  { 
+    return ( contains(other.begin_) ||
+             other.contains(begin_) ||
+             ((other.begin_ < begin_) && (other.last_ >= begin_)));
+  }
+
+  //! Returns the period of intersection or invalid range no intersection
+  template<class point_rep, class duration_rep>
+  inline
+  period<point_rep,duration_rep>
+  period<point_rep,duration_rep>::intersection(const period<point_rep,duration_rep>& other) const 
+  {
+    if (begin_ > other.begin_) {
+      if (last_ <= other.last_) { //case2
+        return *this;  
+      }
+      //case 1
+      return period<point_rep,duration_rep>(begin_, other.end());
+    }
+    else {
+      if (last_ <= other.last_) { //case3
+        return period<point_rep,duration_rep>(other.begin_, this->end());
+      }
+      //case4
+      return other;
+    }
+    //unreachable
+  }
+
+  //! Returns the union of intersecting periods -- or null period
+  /*! 
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  period<point_rep,duration_rep>
+  period<point_rep,duration_rep>::merge(const period<point_rep,duration_rep>& other) const 
+  {
+    if (this->intersects(other)) {      
+      if (begin_ < other.begin_) {
+        return period<point_rep,duration_rep>(begin_, last_ > other.last_ ? this->end() : other.end());
+      }
+      
+      return period<point_rep,duration_rep>(other.begin_, last_ > other.last_ ? this->end() : other.end());
+      
+    }
+    return period<point_rep,duration_rep>(begin_,begin_); // no intersect return null
+  }
+
+  //! Combine two periods with earliest start and latest end.
+  /*! Combines two periods and any gap between them such that 
+   *  start = min(p1.start, p2.start)
+   *  end   = max(p1.end  , p2.end)
+   *@code
+   *        [---p1---)
+   *                       [---p2---)
+   * result:
+   *        [-----------p3----------) 
+   *@endcode
+   */
+  template<class point_rep, class duration_rep>
+  inline
+  period<point_rep,duration_rep>
+  period<point_rep,duration_rep>::span(const period<point_rep,duration_rep>& other) const 
+  {
+    point_rep start((begin_ < other.begin_) ? begin() : other.begin());
+    point_rep newend((last_  < other.last_)  ? other.end() : this->end());
+    return period<point_rep,duration_rep>(start, newend);
+  }
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 196 - 0
ext/boost/date_time/period_formatter.hpp

@@ -0,0 +1,196 @@
+
+#ifndef DATETIME_PERIOD_FORMATTER_HPP___
+#define DATETIME_PERIOD_FORMATTER_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+
+namespace boost { namespace date_time {
+
+
+  //! Not a facet, but a class used to specify and control period formats
+  /*! Provides settings for the following:
+   *   - period_separator -- default '/'
+   *   - period_open_start_delimeter -- default '['
+   *   - period_open_range_end_delimeter -- default ')' 
+   *   - period_closed_range_end_delimeter -- default ']' 
+   *   - display_as_open_range, display_as_closed_range -- default closed_range
+   *
+   *  Thus the default formatting for a period is as follows:
+   *@code
+   *  [period.start()/period.last()]
+   *@endcode 
+   *  So for a typical date_period this would be
+   *@code
+   *  [2004-Jan-04/2004-Feb-01]
+   *@endcode
+   * where the date formatting is controlled by the date facet
+   */
+  template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+  class period_formatter { 
+  public:
+    typedef std::basic_string<CharT> string_type;
+    typedef CharT                    char_type;
+    typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
+    typedef std::vector<std::basic_string<CharT> > collection_type;
+    
+    static const char_type default_period_separator[2];
+    static const char_type default_period_start_delimeter[2];
+    static const char_type default_period_open_range_end_delimeter[2];
+    static const char_type default_period_closed_range_end_delimeter[2];
+
+    enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE };
+
+    //! Constructor that sets up period formatter options -- default should suffice most cases.
+    period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE, 
+                     const char_type* const period_separator = default_period_separator, 
+                     const char_type* const period_start_delimeter = default_period_start_delimeter,
+                     const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
+                     const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) :
+      m_range_option(range_option_in),
+      m_period_separator(period_separator),
+      m_period_start_delimeter(period_start_delimeter),
+      m_open_range_end_delimeter(period_open_range_end_delimeter),
+      m_closed_range_end_delimeter(period_closed_range_end_delimeter)
+    {}
+
+    //! Puts the characters between period elements into stream -- default is /
+    OutItrT put_period_separator(OutItrT& oitr) const 
+    {
+      const_itr_type ci = m_period_separator.begin();
+      while (ci != m_period_separator.end()) {
+        *oitr = *ci;
+        ci++;
+      }
+      return oitr;
+    }
+
+    //! Puts the period start characters into stream -- default is [
+    OutItrT put_period_start_delimeter(OutItrT& oitr) const 
+    {
+      const_itr_type ci = m_period_start_delimeter.begin();
+      while (ci != m_period_start_delimeter.end()) {
+        *oitr = *ci;
+        ci++;
+      }
+      return oitr;
+    }
+
+    //! Puts the period end characters into stream as controled by open/closed range setting.
+    OutItrT put_period_end_delimeter(OutItrT& oitr) const 
+    {
+      
+      const_itr_type ci, end;
+      if (m_range_option == AS_OPEN_RANGE) {
+        ci = m_open_range_end_delimeter.begin();
+        end = m_open_range_end_delimeter.end();
+      }
+      else {
+        ci = m_closed_range_end_delimeter.begin();
+        end = m_closed_range_end_delimeter.end();
+      }
+      while (ci != end) {
+        *oitr = *ci;
+        ci++;
+      }
+      return oitr;
+    }
+   
+    range_display_options range_option() const
+    {
+      return m_range_option;
+    }
+
+    //! Reset the range_option control
+    void 
+    range_option(range_display_options option) const
+    {
+      m_range_option = option;
+    }
+    void delimiter_strings(const string_type& separator,
+                           const string_type& start_delim,
+                           const string_type& open_end_delim,
+                           const string_type& closed_end_delim)
+    {
+      m_period_separator;
+      m_period_start_delimeter;
+      m_open_range_end_delimeter;
+      m_closed_range_end_delimeter;
+    }
+
+
+    //! Generic code to output a period -- no matter the period type.
+    /*! This generic code will output any period using a facet to
+     *  to output the 'elements'.  For example, in the case of a date_period
+     *  the elements will be instances of a date which will be formatted 
+     *  according the to setup in the passed facet parameter.
+     * 
+     *  The steps for formatting a period are always the same:
+     *  - put the start delimiter
+     *  - put start element
+     *  - put the separator 
+     *  - put either last or end element depending on range settings
+     *  - put end delimeter depending on range settings
+     *
+     *  Thus for a typical date period the result might look like this:
+     *@code
+     *
+     *    [March 01, 2004/June 07, 2004]   <-- closed range
+     *    [March 01, 2004/June 08, 2004)   <-- open range
+     *
+     *@endcode
+     */
+    template<class period_type, class facet_type>
+    OutItrT put_period(OutItrT next, 
+                       std::ios_base& a_ios, 
+                       char_type a_fill, 
+                       const period_type& p,
+                       const facet_type& facet) const {
+      put_period_start_delimeter(next);
+      next = facet.put(next, a_ios, a_fill, p.begin());
+      put_period_separator(next);
+      if (m_range_option == AS_CLOSED_RANGE) {
+        facet.put(next, a_ios, a_fill, p.last());
+      }
+      else {
+        facet.put(next, a_ios, a_fill, p.end());
+      }
+      put_period_end_delimeter(next);
+      return next;
+    }
+
+      
+  private:
+    range_display_options m_range_option;    
+    string_type m_period_separator;
+    string_type m_period_start_delimeter;
+    string_type m_open_range_end_delimeter;
+    string_type m_closed_range_end_delimeter;
+  };
+
+  template <class CharT, class OutItrT>  
+  const typename period_formatter<CharT, OutItrT>::char_type 
+  period_formatter<CharT, OutItrT>::default_period_separator[2] = {'/'};
+
+  template <class CharT, class OutItrT>  
+  const typename period_formatter<CharT, OutItrT>::char_type 
+  period_formatter<CharT, OutItrT>::default_period_start_delimeter[2] = {'['};
+
+  template <class CharT, class OutItrT>  
+  const typename period_formatter<CharT, OutItrT>::char_type 
+  period_formatter<CharT, OutItrT>::default_period_open_range_end_delimeter[2] = {')'};
+
+  template <class CharT, class OutItrT>  
+  const typename period_formatter<CharT, OutItrT>::char_type 
+  period_formatter<CharT, OutItrT>::default_period_closed_range_end_delimeter[2] = {']'};
+
+ } } //namespace boost::date_time
+
+#endif

+ 198 - 0
ext/boost/date_time/period_parser.hpp

@@ -0,0 +1,198 @@
+
+#ifndef DATETIME_PERIOD_PARSER_HPP___
+#define DATETIME_PERIOD_PARSER_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <boost/throw_exception.hpp>
+#include <boost/date_time/string_parse_tree.hpp>
+#include <boost/date_time/string_convert.hpp>
+
+
+namespace boost { namespace date_time {
+
+
+  //! Not a facet, but a class used to specify and control period parsing 
+  /*! Provides settings for the following:
+   *   - period_separator -- default '/'
+   *   - period_open_start_delimeter -- default '['
+   *   - period_open_range_end_delimeter -- default ')' 
+   *   - period_closed_range_end_delimeter -- default ']' 
+   *   - display_as_open_range, display_as_closed_range -- default closed_range
+   *
+   *  For a typical date_period, the contents of the input stream would be
+   *@code
+   *  [2004-Jan-04/2004-Feb-01]
+   *@endcode
+   * where the date format is controlled by the date facet
+   */
+  template<class date_type, typename CharT>
+  class period_parser {
+  public:
+    typedef std::basic_string<CharT> string_type;
+    typedef CharT                    char_type;
+    //typedef typename std::basic_string<char_type>::const_iterator const_itr_type;
+    typedef std::istreambuf_iterator<CharT> stream_itr_type;
+    typedef string_parse_tree<CharT> parse_tree_type;
+    typedef typename parse_tree_type::parse_match_result_type match_results;
+    typedef std::vector<std::basic_string<CharT> > collection_type;
+
+    static const char_type default_period_separator[2];
+    static const char_type default_period_start_delimeter[2];
+    static const char_type default_period_open_range_end_delimeter[2];
+    static const char_type default_period_closed_range_end_delimeter[2];
+
+    enum period_range_option { AS_OPEN_RANGE, AS_CLOSED_RANGE };
+
+    //! Constructor that sets up period parser options
+    period_parser(period_range_option range_opt = AS_CLOSED_RANGE,
+                  const char_type* const period_separator = default_period_separator,
+                  const char_type* const period_start_delimeter = default_period_start_delimeter,
+                  const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter,
+                  const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter)
+      : m_range_option(range_opt)
+    {
+      delimiters.push_back(string_type(period_separator));
+      delimiters.push_back(string_type(period_start_delimeter));
+      delimiters.push_back(string_type(period_open_range_end_delimeter));
+      delimiters.push_back(string_type(period_closed_range_end_delimeter));
+    }
+
+    period_parser(const period_parser<date_type,CharT>& p_parser)
+    {
+      this->delimiters = p_parser.delimiters;
+      this->m_range_option = p_parser.m_range_option;
+    }
+
+    period_range_option range_option() const
+    {
+      return m_range_option;
+    }
+    void range_option(period_range_option option)
+    {
+      m_range_option = option;
+    }
+    collection_type delimiter_strings() const
+    {
+      return delimiters;
+    }
+    void delimiter_strings(const string_type& separator,
+                           const string_type& start_delim,
+                           const string_type& open_end_delim,
+                           const string_type& closed_end_delim)
+    {
+      delimiters.clear();
+      delimiters.push_back(separator);
+      delimiters.push_back(start_delim);
+      delimiters.push_back(open_end_delim);
+      delimiters.push_back(closed_end_delim);
+    }
+
+    //! Generic code to parse a period -- no matter the period type.
+    /*! This generic code will parse any period using a facet to
+     *  to get the 'elements'.  For example, in the case of a date_period
+     *  the elements will be instances of a date which will be parsed
+     *  according the to setup in the passed facet parameter.
+     * 
+     *  The steps for parsing a period are always the same:
+     *  - consume the start delimiter
+     *  - get start element
+     *  - consume the separator 
+     *  - get either last or end element depending on range settings
+     *  - consume the end delimeter depending on range settings
+     *
+     *  Thus for a typical date period the contents of the input stream
+     *  might look like this:
+     *@code
+     *
+     *    [March 01, 2004/June 07, 2004]   <-- closed range
+     *    [March 01, 2004/June 08, 2004)   <-- open range
+     *
+     *@endcode
+     */
+    template<class period_type, class duration_type, class facet_type>
+    period_type get_period(stream_itr_type& sitr, 
+                           stream_itr_type& stream_end,
+                           std::ios_base& a_ios, 
+                           const period_type& /* p */,
+                           const duration_type& dur_unit,
+                           const facet_type& facet) const 
+    {
+      // skip leading whitespace
+      while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } 
+
+      typedef typename period_type::point_type point_type;
+      point_type p1(not_a_date_time), p2(not_a_date_time);
+
+
+      consume_delim(sitr, stream_end, delimiters[START]);       // start delim
+      facet.get(sitr, stream_end, a_ios, p1);                   // first point
+      consume_delim(sitr, stream_end, delimiters[SEPARATOR]);   // separator
+      facet.get(sitr, stream_end, a_ios, p2);                   // second point
+
+      // period construction parameters are always open range [begin, end)
+      if (m_range_option == AS_CLOSED_RANGE) {
+        consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim
+        // add 1 duration unit to p2 to make range open
+        p2 += dur_unit;
+      }
+      else {
+        consume_delim(sitr, stream_end, delimiters[OPEN_END]);  // end delim
+      }
+
+      return period_type(p1, p2);
+    }
+
+  private:
+    collection_type delimiters; 
+    period_range_option m_range_option;
+
+    enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END };
+
+    //! throws ios_base::failure if delimiter and parsed data do not match
+    void consume_delim(stream_itr_type& sitr,
+                       stream_itr_type& stream_end,
+                       const string_type& delim) const
+    {
+      /* string_parse_tree will not parse a string of punctuation characters 
+       * without knowing exactly how many characters to process
+       * Ex [2000. Will not parse out the '[' string without knowing 
+       * to process only one character. By using length of the delimiter 
+       * string we can safely iterate past it. */
+      string_type s;
+      for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) {
+        s += *sitr;
+        ++sitr;
+      }
+      if(s != delim) {
+        boost::throw_exception(std::ios_base::failure("Parse failed. Expected '"
+          + convert_string_type<char_type,char>(delim) + "' but found '" + convert_string_type<char_type,char>(s) + "'"));
+      }
+    }
+  };
+
+  template <class date_type, class char_type>  
+  const typename period_parser<date_type, char_type>::char_type 
+  period_parser<date_type, char_type>::default_period_separator[2] = {'/'};
+
+  template <class date_type, class char_type>  
+  const typename period_parser<date_type, char_type>::char_type 
+  period_parser<date_type, char_type>::default_period_start_delimeter[2] = {'['};
+
+  template <class date_type, class char_type>  
+  const typename period_parser<date_type, char_type>::char_type 
+  period_parser<date_type, char_type>::default_period_open_range_end_delimeter[2] = {')'};
+
+  template <class date_type, class char_type>  
+  const typename period_parser<date_type, char_type>::char_type 
+  period_parser<date_type, char_type>::default_period_closed_range_end_delimeter[2] = {']'};
+
+ } } //namespace boost::date_time
+
+#endif // DATETIME_PERIOD_PARSER_HPP___

+ 91 - 0
ext/boost/date_time/posix_time/conversion.hpp

@@ -0,0 +1,91 @@
+#ifndef POSIX_TIME_CONVERSION_HPP___
+#define POSIX_TIME_CONVERSION_HPP___
+
+/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include "boost/date_time/posix_time/ptime.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/filetime_functions.hpp"
+#include "boost/date_time/c_time.hpp"
+#include "boost/date_time/gregorian/conversion.hpp"
+
+namespace boost {
+
+namespace posix_time {
+
+
+  //! Function that converts a time_t into a ptime.
+  inline
+  ptime from_time_t(std::time_t t)
+  {
+    ptime start(gregorian::date(1970,1,1));
+    return start + seconds(static_cast<long>(t));
+  }
+
+  //! Convert a time to a tm structure truncating any fractional seconds 
+  inline
+  std::tm to_tm(const boost::posix_time::ptime& t) {
+    std::tm timetm = boost::gregorian::to_tm(t.date());
+    boost::posix_time::time_duration td = t.time_of_day();
+    timetm.tm_hour = td.hours(); 
+    timetm.tm_min = td.minutes(); 
+    timetm.tm_sec = td.seconds();
+    timetm.tm_isdst = -1; // -1 used when dst info is unknown 
+    return timetm;
+  }
+  //! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components 
+  inline
+  std::tm to_tm(const boost::posix_time::time_duration& td) {
+    std::tm timetm = {};
+    timetm.tm_hour = date_time::absolute_value(td.hours());
+    timetm.tm_min = date_time::absolute_value(td.minutes());
+    timetm.tm_sec = date_time::absolute_value(td.seconds());
+    timetm.tm_isdst = -1; // -1 used when dst info is unknown
+    return timetm;
+  }
+
+  //! Convert a tm struct to a ptime ignoring is_dst flag
+  inline
+  ptime ptime_from_tm(const std::tm& timetm) {
+    boost::gregorian::date d = boost::gregorian::date_from_tm(timetm);
+    return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec));
+  }
+
+
+#if defined(BOOST_HAS_FTIME)
+  
+  //! Function to create a time object from an initialized FILETIME struct.
+  /*! Function to create a time object from an initialized FILETIME struct.
+   * A FILETIME struct holds 100-nanosecond units (0.0000001). When 
+   * built with microsecond resolution the FILETIME's sub second value 
+   * will be truncated. Nanosecond resolution has no truncation. 
+   *
+   * \note FILETIME is part of the Win32 API, so it is not portable to non-windows
+   * platforms.
+   *
+   * \note The function is templated on the FILETIME type, so that
+   *       it can be used with both native FILETIME and the ad-hoc
+   *       boost::date_time::winapi::file_time type.
+   */
+  template< typename TimeT, typename FileTimeT >
+  inline
+  TimeT from_ftime(const FileTimeT& ft)
+  {
+    return boost::date_time::time_from_ftime<TimeT>(ft);
+  }
+
+#endif // BOOST_HAS_FTIME
+
+} } //namespace boost::posix_time
+
+
+
+
+#endif
+

+ 114 - 0
ext/boost/date_time/posix_time/date_duration_operators.hpp

@@ -0,0 +1,114 @@
+#ifndef DATE_DURATION_OPERATORS_HPP___
+#define DATE_DURATION_OPERATORS_HPP___
+                                                                                
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or 
+ * http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/greg_duration_types.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+
+namespace boost {
+namespace posix_time {
+  
+  /*!@file date_duration_operators.hpp Operators for ptime and 
+   * optional gregorian types. Operators use snap-to-end-of-month behavior. 
+   * Further details on this behavior can be found in reference for 
+   * date_time/date_duration_types.hpp and documentation for 
+   * month and year iterators.
+   */
+ 
+
+  /*! Adds a months object and a ptime. Result will be same 
+   * day-of-month as ptime unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  ptime 
+  operator+(const ptime& t, const boost::gregorian::months& m)
+  {
+    return t + m.get_offset(t.date());
+  }
+  
+  /*! Adds a months object to a ptime. Result will be same 
+   * day-of-month as ptime unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  ptime 
+  operator+=(ptime& t, const boost::gregorian::months& m)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t += m.get_offset(t.date());
+  }
+
+  /*! Subtracts a months object and a ptime. Result will be same 
+   * day-of-month as ptime unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  ptime 
+  operator-(const ptime& t, const boost::gregorian::months& m)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t + m.get_neg_offset(t.date());
+  }
+  
+  /*! Subtracts a months object from a ptime. Result will be same 
+   * day-of-month as ptime unless original day was the last day of month.
+   * see date_time::months_duration for more details */
+  inline
+  ptime 
+  operator-=(ptime& t, const boost::gregorian::months& m)
+  {
+    return t += m.get_neg_offset(t.date());
+  }
+
+  // ptime & years
+  
+  /*! Adds a years object and a ptime. Result will be same 
+   * month and day-of-month as ptime unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  ptime 
+  operator+(const ptime& t, const boost::gregorian::years& y)
+  {
+    return t + y.get_offset(t.date());
+  }
+
+  /*! Adds a years object to a ptime. Result will be same 
+   * month and day-of-month as ptime unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  ptime 
+  operator+=(ptime& t, const boost::gregorian::years& y)
+  {
+    return t += y.get_offset(t.date());
+  }
+
+  /*! Subtracts a years object and a ptime. Result will be same 
+   * month and day-of-month as ptime unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  ptime 
+  operator-(const ptime& t, const boost::gregorian::years& y)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t + y.get_neg_offset(t.date());
+  }
+
+  /*! Subtracts a years object from a ptime. Result will be same 
+   * month and day-of-month as ptime unless original day was the 
+   * last day of month. see date_time::years_duration for more details */
+  inline
+  ptime 
+  operator-=(ptime& t, const boost::gregorian::years& y)
+  {
+    // get_neg_offset returns a negative duration, so we add
+    return t += y.get_neg_offset(t.date());
+  }
+
+}} // namespaces
+
+#endif // DATE_DURATION_OPERATORS_HPP___

+ 39 - 0
ext/boost/date_time/posix_time/posix_time.hpp

@@ -0,0 +1,39 @@
+#ifndef POSIX_TIME_HPP___
+#define POSIX_TIME_HPP___
+
+/* Copyright (c) 2002-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+/*!@file posix_time.hpp Global header file to get all of posix time types 
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/posix_time/date_duration_operators.hpp"
+#endif
+
+// output functions
+#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS)
+#include "boost/date_time/posix_time/time_formatters_limited.hpp"
+#else
+#include "boost/date_time/posix_time/time_formatters.hpp"
+#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS
+
+// streaming operators
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+#include "boost/date_time/posix_time/posix_time_legacy_io.hpp"
+#else
+#include "boost/date_time/posix_time/posix_time_io.hpp"
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+
+#include "boost/date_time/posix_time/time_parsers.hpp"
+#include "boost/date_time/posix_time/conversion.hpp"
+
+
+#endif
+

+ 178 - 0
ext/boost/date_time/posix_time/posix_time_config.hpp

@@ -0,0 +1,178 @@
+#ifndef POSIX_TIME_CONFIG_HPP___
+#define POSIX_TIME_CONFIG_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 07:52:28 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <cstdlib> //for MCW 7.2 std::abs(long long)
+#include <boost/limits.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/config/no_tr1/cmath.hpp>
+#include <boost/date_time/time_duration.hpp>
+#include <boost/date_time/time_resolution_traits.hpp>
+#include <boost/date_time/gregorian/gregorian_types.hpp>
+#include <boost/date_time/wrapping_int.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace posix_time {
+
+//Remove the following line if you want 64 bit millisecond resolution time
+//#define BOOST_GDTL_POSIX_TIME_STD_CONFIG
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+  // set up conditional test compilations
+#define BOOST_DATE_TIME_HAS_MILLISECONDS
+#define BOOST_DATE_TIME_HAS_MICROSECONDS
+#define BOOST_DATE_TIME_HAS_NANOSECONDS
+  typedef date_time::time_resolution_traits<boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::nano,
+    1000000000, 9 > time_res_traits;
+#else
+  // set up conditional test compilations
+#define BOOST_DATE_TIME_HAS_MILLISECONDS
+#define BOOST_DATE_TIME_HAS_MICROSECONDS
+#undef  BOOST_DATE_TIME_HAS_NANOSECONDS
+  typedef date_time::time_resolution_traits<
+    boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro,
+                                            1000000, 6 > time_res_traits;
+
+
+// #undef BOOST_DATE_TIME_HAS_MILLISECONDS
+// #undef BOOST_DATE_TIME_HAS_MICROSECONDS
+// #undef BOOST_DATE_TIME_HAS_NANOSECONDS
+//   typedef date_time::time_resolution_traits<boost::int64_t, boost::date_time::tenth,
+//                                              10, 0 > time_res_traits;
+
+#endif
+
+
+  //! Base time duration type
+  /*! \ingroup time_basics
+   */
+  class time_duration :
+    public date_time::time_duration<time_duration, time_res_traits>
+  {
+  public:
+    typedef time_res_traits rep_type;
+    typedef time_res_traits::day_type day_type;
+    typedef time_res_traits::hour_type hour_type;
+    typedef time_res_traits::min_type min_type;
+    typedef time_res_traits::sec_type sec_type;
+    typedef time_res_traits::fractional_seconds_type fractional_seconds_type;
+    typedef time_res_traits::tick_type tick_type;
+    typedef time_res_traits::impl_type impl_type;
+    time_duration(hour_type hour,
+                  min_type min,
+                  sec_type sec,
+                  fractional_seconds_type fs=0) :
+      date_time::time_duration<time_duration, time_res_traits>(hour,min,sec,fs)
+    {}
+    time_duration() :
+      date_time::time_duration<time_duration, time_res_traits>(0,0,0)
+    {}
+    //! Construct from special_values
+    time_duration(boost::date_time::special_values sv) :
+      date_time::time_duration<time_duration, time_res_traits>(sv)
+    {}
+    //Give duration access to ticks constructor -- hide from users
+    friend class date_time::time_duration<time_duration, time_res_traits>;
+  private:
+    explicit time_duration(impl_type tick_count) :
+      date_time::time_duration<time_duration, time_res_traits>(tick_count)
+    {}
+  };
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+
+  //! Simple implementation for the time rep
+  struct simple_time_rep
+  {
+    typedef gregorian::date      date_type;
+    typedef time_duration        time_duration_type;
+    simple_time_rep(date_type d, time_duration_type tod) :
+      day(d),
+      time_of_day(tod)
+    {
+      // make sure we have sane values for date & time
+      if(!day.is_special() && !time_of_day.is_special()){
+        if(time_of_day >= time_duration_type(24,0,0)) {
+          while(time_of_day >= time_duration_type(24,0,0)) {
+            day += date_type::duration_type(1);
+            time_of_day -= time_duration_type(24,0,0);
+          }
+        }
+        else if(time_of_day.is_negative()) {
+          while(time_of_day.is_negative()) {
+            day -= date_type::duration_type(1);
+            time_of_day += time_duration_type(24,0,0);
+          }
+        }
+      }
+    }
+    date_type day;
+    time_duration_type time_of_day;
+    bool is_special()const
+    {
+      return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time());
+    }
+    bool is_pos_infinity()const
+    {
+      return(day.is_pos_infinity() || time_of_day.is_pos_infinity());
+    }
+    bool is_neg_infinity()const
+    {
+      return(day.is_neg_infinity() || time_of_day.is_neg_infinity());
+    }
+    bool is_not_a_date_time()const
+    {
+      return(day.is_not_a_date() || time_of_day.is_not_a_date_time());
+    }
+  };
+
+  class posix_time_system_config
+  {
+   public:
+    typedef simple_time_rep time_rep_type;
+    typedef gregorian::date date_type;
+    typedef gregorian::date_duration date_duration_type;
+    typedef time_duration time_duration_type;
+    typedef time_res_traits::tick_type int_type;
+    typedef time_res_traits resolution_traits;
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
+#else
+    BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000);
+#endif
+  };
+
+#else
+
+  class millisec_posix_time_system_config
+  {
+   public:
+    typedef boost::int64_t time_rep_type;
+    //typedef time_res_traits::tick_type time_rep_type;
+    typedef gregorian::date date_type;
+    typedef gregorian::date_duration date_duration_type;
+    typedef time_duration time_duration_type;
+    typedef time_res_traits::tick_type int_type;
+    typedef time_res_traits::impl_type impl_type;
+    typedef time_res_traits resolution_traits;
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers
+#else
+    BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000);
+#endif
+  };
+
+#endif
+
+} }//namespace posix_time
+
+
+#endif
+
+

+ 82 - 0
ext/boost/date_time/posix_time/posix_time_duration.hpp

@@ -0,0 +1,82 @@
+#ifndef POSIX_TIME_DURATION_HPP___
+#define POSIX_TIME_DURATION_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/posix_time/posix_time_config.hpp"
+
+namespace boost {
+namespace posix_time {
+
+  //! Allows expression of durations as an hour count
+  /*! \ingroup time_basics
+   */
+  class hours : public time_duration
+  {
+  public:
+    explicit hours(long h) :
+      time_duration(h,0,0)
+    {}
+  };
+
+  //! Allows expression of durations as a minute count
+  /*! \ingroup time_basics
+   */
+  class minutes : public time_duration
+  {
+  public:
+    explicit minutes(long m) :
+      time_duration(0,m,0)
+    {}
+  };
+
+  //! Allows expression of durations as a seconds count
+  /*! \ingroup time_basics
+   */
+  class seconds : public time_duration
+  {
+  public:
+    explicit seconds(long s) :
+      time_duration(0,0,s)
+    {}
+  };
+
+
+  //! Allows expression of durations as milli seconds
+  /*! \ingroup time_basics
+   */
+  typedef date_time::subsecond_duration<time_duration,1000> millisec;
+  typedef date_time::subsecond_duration<time_duration,1000> milliseconds;
+
+  //! Allows expression of durations as micro seconds
+  /*! \ingroup time_basics
+   */
+  typedef date_time::subsecond_duration<time_duration,1000000> microsec;
+  typedef date_time::subsecond_duration<time_duration,1000000> microseconds;
+
+  //This is probably not needed anymore...
+#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS)
+
+  //! Allows expression of durations as nano seconds
+  /*! \ingroup time_basics
+   */
+  typedef date_time::subsecond_duration<time_duration,1000000000> nanosec;
+  typedef date_time::subsecond_duration<time_duration,1000000000> nanoseconds;
+
+
+#endif
+
+
+
+
+} }//namespace posix_time
+
+
+#endif
+

+ 239 - 0
ext/boost/date_time/posix_time/posix_time_io.hpp

@@ -0,0 +1,239 @@
+#ifndef DATE_TIME_POSIX_TIME_IO_HPP__
+#define DATE_TIME_POSIX_TIME_IO_HPP__
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-13 14:05:31 -0500 (Thu, 13 Nov 2008) $
+ */
+
+#include <locale>
+#include <iostream>
+#include <iterator> // i/ostreambuf_iterator
+#include <boost/io/ios_state.hpp>
+#include <boost/date_time/time_facet.hpp>
+#include <boost/date_time/period_formatter.hpp>
+#include <boost/date_time/posix_time/ptime.hpp>
+#include <boost/date_time/posix_time/time_period.hpp>
+#include <boost/date_time/posix_time/posix_time_duration.hpp>
+#include <boost/date_time/posix_time/conversion.hpp> // to_tm will be needed in the facets
+
+namespace boost {
+namespace posix_time {
+
+
+  //! wptime_facet is depricated and will be phased out. use wtime_facet instead
+  //typedef boost::date_time::time_facet<ptime, wchar_t> wptime_facet;
+  //! ptime_facet is depricated and will be phased out. use time_facet instead
+  //typedef boost::date_time::time_facet<ptime, char>     ptime_facet;
+
+  //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead
+  //typedef boost::date_time::time_input_facet<ptime,wchar_t> wptime_input_facet;
+  //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead
+  //typedef boost::date_time::time_input_facet<ptime,char>     ptime_input_facet;
+
+  typedef boost::date_time::time_facet<ptime, wchar_t>     wtime_facet;
+  typedef boost::date_time::time_facet<ptime, char>         time_facet;
+
+  typedef boost::date_time::time_input_facet<ptime, wchar_t>     wtime_input_facet;
+  typedef boost::date_time::time_input_facet<ptime, char>         time_input_facet;
+
+  template <class CharT, class TraitsT>
+  inline
+  std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os,
+             const ptime& p) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+    typedef std::time_put<CharT>                  std_ptime_facet;
+    std::ostreambuf_iterator<CharT> oitr(os);
+    if (std::has_facet<custom_ptime_facet>(os.getloc()))
+      std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+    else {
+      //instantiate a custom facet for dealing with times since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every time period
+      //if the locale did not already exist.  Of course this will be overridden
+      //if the user imbues as some later point.
+      custom_ptime_facet* f = new custom_ptime_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(oitr, os, os.fill(), p);
+    }
+    return os;
+  }
+
+  //! input operator for ptime
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, ptime& pt)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<time_input_facet>(is.getloc())) {
+          std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, pt);
+        }
+        else {
+          time_input_facet* f = new time_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, pt);
+        }
+      }
+      catch(...) {
+        // mask tells us what exceptions are turned on
+        std::ios_base::iostate exception_mask = is.exceptions();
+        // if the user wants exceptions on failbit, we'll rethrow our 
+        // date_time exception & set the failbit
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); }
+          catch(std::ios_base::failure&) {} // ignore this one
+          throw; // rethrow original exception
+        }
+        else {
+          // if the user want's to fail quietly, we simply set the failbit
+          is.setstate(std::ios_base::failbit);
+        }
+      }
+    }
+    return is;
+  }
+
+
+  template <class CharT, class TraitsT>
+  inline 
+  std::basic_ostream<CharT, TraitsT>&
+  operator<<(std::basic_ostream<CharT, TraitsT>& os,
+             const boost::posix_time::time_period& p) {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+    typedef std::time_put<CharT>                  std_time_facet;
+    std::ostreambuf_iterator<CharT> oitr(os);
+    if (std::has_facet<custom_ptime_facet>(os.getloc())) {
+      std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), p);
+    }
+    else {
+      //instantiate a custom facet for dealing with periods since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every time period
+      //if the local did not already exist.  Of course this will be overridden
+      //if the user imbues as some later point.
+      custom_ptime_facet* f = new custom_ptime_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(oitr, os, os.fill(), p);
+    }
+    return os;
+  }
+
+  //! input operator for time_period
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, time_period& tp)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<time_input_facet>(is.getloc())) {
+          std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, tp);
+        }
+        else {
+          time_input_facet* f = new time_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, tp);
+        }
+      }
+      catch(...) {
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); }
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit);
+        }
+      }
+    }
+    return is;
+  }
+
+
+  //! ostream operator for posix_time::time_duration 
+  //  todo fix to use facet --  place holder for now...
+  template <class CharT, class Traits>
+  inline
+  std::basic_ostream<CharT, Traits>&
+  operator<<(std::basic_ostream<CharT, Traits>& os, const time_duration& td)
+  {
+    boost::io::ios_flags_saver iflags(os);
+    typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
+    typedef std::time_put<CharT>                  std_ptime_facet;
+    std::ostreambuf_iterator<CharT> oitr(os);
+    if (std::has_facet<custom_ptime_facet>(os.getloc()))
+      std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os, os.fill(), td);
+    else {
+      //instantiate a custom facet for dealing with times since the user
+      //has not put one in the stream so far.  This is for efficiency 
+      //since we would always need to reconstruct for every time period
+      //if the locale did not already exist.  Of course this will be overridden
+      //if the user imbues as some later point.
+      custom_ptime_facet* f = new custom_ptime_facet();
+      std::locale l = std::locale(os.getloc(), f);
+      os.imbue(l);
+      f->put(oitr, os, os.fill(), td);
+    }
+    return os;
+  }
+
+  //! input operator for time_duration
+  template <class CharT, class Traits>
+  inline
+  std::basic_istream<CharT, Traits>&
+  operator>>(std::basic_istream<CharT, Traits>& is, time_duration& td)
+  {
+    boost::io::ios_flags_saver iflags(is);
+    typename std::basic_istream<CharT, Traits>::sentry strm_sentry(is, false);
+    if (strm_sentry) {
+      try {
+        typedef typename date_time::time_input_facet<ptime, CharT> time_input_facet;
+        std::istreambuf_iterator<CharT,Traits> sit(is), str_end;
+        if(std::has_facet<time_input_facet>(is.getloc())) {
+          std::use_facet<time_input_facet>(is.getloc()).get(sit, str_end, is, td);
+        }
+        else {
+          time_input_facet* f = new time_input_facet();
+          std::locale l = std::locale(is.getloc(), f);
+          is.imbue(l);
+          f->get(sit, str_end, is, td);
+        }
+      }
+      catch(...) {
+        std::ios_base::iostate exception_mask = is.exceptions();
+        if(std::ios_base::failbit & exception_mask) {
+          try { is.setstate(std::ios_base::failbit); }
+          catch(std::ios_base::failure&) {}
+          throw; // rethrow original exception
+        }
+        else {
+          is.setstate(std::ios_base::failbit);
+        }
+      }
+    }
+    return is;
+  }
+
+} } // namespaces
+#endif // DATE_TIME_POSIX_TIME_IO_HPP__

+ 153 - 0
ext/boost/date_time/posix_time/posix_time_legacy_io.hpp

@@ -0,0 +1,153 @@
+#ifndef POSIX_TIME_PRE133_OPERATORS_HPP___
+#define POSIX_TIME_PRE133_OPERATORS_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file posix_time_pre133_operators.hpp
+ * These input and output operators are for use with the 
+ * pre 1.33 version of the date_time libraries io facet code. 
+ * The operators used in version 1.33 and later can be found 
+ * in posix_time_io.hpp */
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#include "boost/date_time/posix_time/time_period.hpp"
+#include "boost/date_time/time_parsing.hpp"
+
+namespace boost {
+namespace posix_time {
+
+
+//The following code is removed for configurations with poor std::locale support (eg: MSVC6, gcc 2.9x)
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO)
+  //! ostream operator for posix_time::time_duration
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const time_duration& td)
+  {
+    typedef boost::date_time::ostream_time_duration_formatter<time_duration, charT> duration_formatter;
+    duration_formatter::duration_put(td, os);
+    return os;
+  }
+
+  //! ostream operator for posix_time::ptime
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const ptime& t)
+  {
+    typedef boost::date_time::ostream_time_formatter<ptime, charT> time_formatter;
+    time_formatter::time_put(t, os);
+    return os;
+  }
+
+  //! ostream operator for posix_time::time_period
+  template <class charT, class traits>
+  inline
+  std::basic_ostream<charT, traits>&
+  operator<<(std::basic_ostream<charT, traits>& os, const time_period& tp)
+  {
+    typedef boost::date_time::ostream_time_period_formatter<time_period, charT> period_formatter;
+    period_formatter::period_put(tp, os);
+    return os;
+  }
+#endif // USE_DATE_TIME_PRE_1_33_FACET_IO
+/******** input streaming ********/
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_duration& td)
+  {
+    // need to create a std::string and parse it
+    std::basic_string<charT> inp_s;
+    std::stringstream out_ss;
+    is >> inp_s;
+    typename std::basic_string<charT>::iterator b = inp_s.begin();
+    // need to use both iterators because there is no requirement
+    // for the data held by a std::basic_string<> be terminated with
+    // any marker (such as '\0').
+    typename std::basic_string<charT>::iterator e = inp_s.end();
+    while(b != e){
+      out_ss << out_ss.narrow(*b, 0);
+      ++b;
+    }
+
+    td = date_time::parse_delimited_time_duration<time_duration>(out_ss.str());
+    return is;
+  }
+
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, ptime& pt)
+  {
+    gregorian::date d(not_a_date_time);
+    time_duration td(0,0,0);
+    is >> d >> td;
+    pt = ptime(d, td);
+
+    return is;
+  }
+
+  /** operator>> for time_period. time_period must be in 
+   * "[date time_duration/date time_duration]" format. */
+  template<class charT>
+  inline
+  std::basic_istream<charT>& operator>>(std::basic_istream<charT>& is, time_period& tp)
+  {
+    gregorian::date d(not_a_date_time);
+    time_duration td(0,0,0);
+    ptime beg(d, td);
+    ptime end(beg);
+    std::basic_string<charT> s;
+    // get first date string and remove leading '['
+    is >> s;
+    {
+      std::basic_stringstream<charT> ss;
+      ss << s.substr(s.find('[')+1);
+      ss >> d;
+    }
+    // get first time_duration & second date string, remove the '/'
+    // and split into 2 strings
+    is >> s; 
+    {
+      std::basic_stringstream<charT> ss;
+      ss << s.substr(0, s.find('/'));
+      ss >> td;
+    }
+    beg = ptime(d, td);
+    {
+      std::basic_stringstream<charT> ss;
+      ss << s.substr(s.find('/')+1);
+      ss >> d;
+    }
+    // get last time_duration and remove the trailing ']'
+    is >> s;
+    {
+      std::basic_stringstream<charT> ss;
+      ss << s.substr(0, s.find(']'));
+      ss >> td;
+    }
+    end = ptime(d, td);
+
+    tp = time_period(beg,end);
+    return is;
+  }
+
+
+#endif //BOOST_DATE_TIME_NO_LOCALE
+
+} } // namespaces
+
+#endif // POSIX_TIME_PRE133_OPERATORS_HPP___

+ 68 - 0
ext/boost/date_time/posix_time/posix_time_system.hpp

@@ -0,0 +1,68 @@
+#ifndef POSIX_TIME_SYSTEM_HPP___
+#define POSIX_TIME_SYSTEM_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include "boost/date_time/posix_time/posix_time_config.hpp"
+#include "boost/date_time/time_system_split.hpp"
+#include "boost/date_time/time_system_counted.hpp"
+#include "boost/date_time/compiler_config.hpp"
+
+
+namespace boost {
+namespace posix_time { 
+
+#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG
+
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers 
+  typedef date_time::split_timedate_system<posix_time_system_config, 1000000000> posix_time_system;
+#else
+  typedef date_time::split_timedate_system<posix_time_system_config> posix_time_system;
+#endif
+
+#else
+
+  typedef date_time::counted_time_rep<millisec_posix_time_system_config> int64_time_rep;
+  typedef date_time::counted_time_system<int64_time_rep> posix_time_system;
+
+#endif
+
+} }//namespace posix_time
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 55 - 0
ext/boost/date_time/posix_time/posix_time_types.hpp

@@ -0,0 +1,55 @@
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ */
+#ifndef POSIX_TIME_TYPES_HPP___
+#define POSIX_TIME_TYPES_HPP___
+
+#include "boost/date_time/time_clock.hpp"
+#include "boost/date_time/microsec_time_clock.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES)
+#include "boost/date_time/posix_time/date_duration_operators.hpp"
+#endif
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/posix_time_system.hpp"
+#include "boost/date_time/posix_time/time_period.hpp"
+#include "boost/date_time/time_iterator.hpp"
+#include "boost/date_time/dst_rules.hpp"
+
+namespace boost {
+
+//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties
+namespace posix_time {
+
+  //! Iterator over a defined time duration
+  /*! \ingroup time_basics
+   */
+  typedef date_time::time_itr<ptime> time_iterator;
+  //! A time clock that has a resolution of one second
+  /*! \ingroup time_basics
+   */
+  typedef date_time::second_clock<ptime> second_clock;
+
+#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK
+  //! A time clock that has a resolution of one microsecond
+  /*! \ingroup time_basics
+   */
+  typedef date_time::microsec_clock<ptime> microsec_clock;
+#endif
+
+  //! Define a dst null dst rule for the posix_time system
+  typedef date_time::null_dst_rules<ptime::date_type, time_duration> no_dst;
+  //! Define US dst rule calculator for the posix_time system
+  typedef date_time::us_dst_rules<ptime::date_type, time_duration> us_dst;
+
+
+} } //namespace posix_time
+
+
+
+
+#endif
+

+ 65 - 0
ext/boost/date_time/posix_time/ptime.hpp

@@ -0,0 +1,65 @@
+#ifndef POSIX_PTIME_HPP___
+#define POSIX_PTIME_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/posix_time/posix_time_system.hpp"
+#include "boost/date_time/time.hpp"
+
+namespace boost {
+
+namespace posix_time {
+ 
+  //bring special enum values into the namespace
+  using date_time::special_values;
+  using date_time::not_special;
+  using date_time::neg_infin;
+  using date_time::pos_infin;
+  using date_time::not_a_date_time;
+  using date_time::max_date_time;
+  using date_time::min_date_time; 
+  
+  //! Time type with no timezone or other adjustments
+  /*! \ingroup time_basics
+   */
+  class ptime : public date_time::base_time<ptime, posix_time_system>
+  {
+  public:
+    typedef posix_time_system time_system_type;
+    typedef time_system_type::time_rep_type time_rep_type;
+    typedef time_system_type::time_duration_type time_duration_type;
+    typedef ptime time_type;
+    //! Construct with date and offset in day
+    ptime(gregorian::date d,time_duration_type td) : date_time::base_time<time_type,time_system_type>(d,td)
+    {}
+    //! Construct a time at start of the given day (midnight)
+    explicit ptime(gregorian::date d) : date_time::base_time<time_type,time_system_type>(d,time_duration_type(0,0,0))
+    {}
+    //! Copy from time_rep
+    ptime(const time_rep_type& rhs):
+      date_time::base_time<time_type,time_system_type>(rhs)
+    {}
+    //! Construct from special value
+    ptime(const special_values sv) : date_time::base_time<time_type,time_system_type>(sv)
+    {}
+#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR)
+    // Default constructor constructs to not_a_date_time
+    ptime() : date_time::base_time<time_type,time_system_type>(gregorian::date(not_a_date_time), time_duration_type(not_a_date_time))
+    {}
+#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR
+      
+  };
+
+
+
+} }//namespace posix_time
+
+
+#endif
+

+ 289 - 0
ext/boost/date_time/posix_time/time_formatters.hpp

@@ -0,0 +1,289 @@
+#ifndef POSIXTIME_FORMATTERS_HPP___
+#define POSIXTIME_FORMATTERS_HPP___
+
+/* Copyright (c) 2002-2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+#include "boost/date_time/time_formatting_streams.hpp"
+
+#include "boost/date_time/time_parsing.hpp"
+
+/* NOTE: The "to_*_string" code for older compilers, ones that define 
+ * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in 
+ * formatters_limited.hpp
+ */
+
+namespace boost {
+
+namespace posix_time {
+
+  // template function called by wrapper functions:
+  // to_*_string(time_duration) & to_*_wstring(time_duration)
+  template<class charT>
+  inline std::basic_string<charT> to_simple_string_type(time_duration td) {
+    std::basic_ostringstream<charT> ss;
+    if(td.is_special()) {
+      /* simply using 'ss << td.get_rep()' won't work on compilers
+       * that don't support locales. This way does. */
+      // switch copied from date_names_put.hpp
+      switch(td.get_rep().as_special())
+      {
+      case not_a_date_time:
+        //ss << "not-a-number";
+        ss << "not-a-date-time";
+        break;
+      case pos_infin:
+        ss << "+infinity";
+        break;
+      case neg_infin:
+        ss << "-infinity";
+        break;
+      default:
+        ss << "";
+      }
+    }
+    else {
+      charT fill_char = '0';
+      if(td.is_negative()) {
+        ss << '-';
+      }
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.hours()) << ":";
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.minutes()) << ":";
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.seconds());
+      //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+      boost::int64_t frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+      // JDG [7/6/02 VC++ compatibility]
+      charT buff[32];
+      _i64toa(frac_sec, buff, 10);
+#else
+      time_duration::fractional_seconds_type frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+#endif
+      if (frac_sec != 0) {
+        ss  << "." << std::setw(time_duration::num_fractional_digits())
+            << std::setfill(fill_char)
+          
+          // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+            << buff;
+#else
+        << frac_sec;
+#endif
+      }
+    }// else
+    return ss.str();
+  }
+  //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+  /*!\ingroup time_format
+   */
+  inline std::string to_simple_string(time_duration td) {
+    return to_simple_string_type<char>(td);
+  }
+
+
+  // template function called by wrapper functions:
+  // to_*_string(time_duration) & to_*_wstring(time_duration)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_string_type(time_duration td) 
+  {
+    std::basic_ostringstream<charT> ss;
+    if(td.is_special()) {
+      /* simply using 'ss << td.get_rep()' won't work on compilers
+       * that don't support locales. This way does. */
+      // switch copied from date_names_put.hpp
+      switch(td.get_rep().as_special()) {
+      case not_a_date_time:
+        //ss << "not-a-number";
+        ss << "not-a-date-time";
+        break;
+      case pos_infin:
+        ss << "+infinity";
+        break;
+      case neg_infin:
+        ss << "-infinity";
+        break;
+      default:
+        ss << "";
+      }
+    }
+    else {
+      charT fill_char = '0';
+      if(td.is_negative()) {
+        ss << '-';
+      }
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.hours());
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.minutes());
+      ss  << std::setw(2) << std::setfill(fill_char) 
+          << date_time::absolute_value(td.seconds());
+      //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+      boost::int64_t frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+      // JDG [7/6/02 VC++ compatibility]
+      charT buff[32];
+      _i64toa(frac_sec, buff, 10);
+#else
+      time_duration::fractional_seconds_type frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+#endif
+      if (frac_sec != 0) {
+        ss  << "." << std::setw(time_duration::num_fractional_digits())
+            << std::setfill(fill_char)
+          
+          // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+            << buff;
+#else
+        << frac_sec;
+#endif
+      }
+    }// else
+    return ss.str();
+  }
+  //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+  /*!\ingroup time_format
+   */
+  inline std::string to_iso_string(time_duration td){
+    return to_iso_string_type<char>(td);
+  }
+
+  //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
+  /*!\ingroup time_format
+   */
+  template<class charT>
+  inline std::basic_string<charT> to_simple_string_type(ptime t) 
+  {
+    // can't use this w/gcc295, no to_simple_string_type<>(td) available
+    std::basic_string<charT> ts = gregorian::to_simple_string_type<charT>(t.date());// + " ";
+    if(!t.time_of_day().is_special()) {
+      charT space = ' ';
+      return ts + space + to_simple_string_type<charT>(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+  inline std::string to_simple_string(ptime t){
+    return to_simple_string_type<char>(t);
+  }
+
+  // function called by wrapper functions to_*_string(time_period) 
+  // & to_*_wstring(time_period)
+  template<class charT>
+  inline std::basic_string<charT> to_simple_string_type(time_period tp) 
+  {
+    charT beg = '[', mid = '/', end = ']';
+    std::basic_string<charT> d1(to_simple_string_type<charT>(tp.begin()));
+    std::basic_string<charT> d2(to_simple_string_type<charT>(tp.last()));
+    return std::basic_string<charT>(beg + d1 + mid + d2 + end);
+  }
+  //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+  /*!\ingroup time_format
+   */
+  inline std::string to_simple_string(time_period tp){
+    return to_simple_string_type<char>(tp);
+  }
+
+  // function called by wrapper functions to_*_string(time_period) 
+  // & to_*_wstring(time_period)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_string_type(ptime t) 
+  {
+    std::basic_string<charT> ts = gregorian::to_iso_string_type<charT>(t.date());// + "T";
+    if(!t.time_of_day().is_special()) {
+      charT sep = 'T';
+      return ts + sep + to_iso_string_type<charT>(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+  //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline std::string to_iso_string(ptime t){
+    return to_iso_string_type<char>(t);
+  }
+
+
+  // function called by wrapper functions to_*_string(time_period) 
+  // & to_*_wstring(time_period)
+  template<class charT>
+  inline std::basic_string<charT> to_iso_extended_string_type(ptime t) 
+  {
+    std::basic_string<charT> ts = gregorian::to_iso_extended_string_type<charT>(t.date());// + "T";
+    if(!t.time_of_day().is_special()) {
+      charT sep = 'T';
+      return ts + sep + to_simple_string_type<charT>(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+  //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline std::string to_iso_extended_string(ptime t){
+    return to_iso_extended_string_type<char>(t);
+  }
+
+#if !defined(BOOST_NO_STD_WSTRING)
+  //! Time duration to wstring -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+  /*!\ingroup time_format
+   */
+  inline std::wstring to_simple_wstring(time_duration td) {
+    return to_simple_string_type<wchar_t>(td);
+  }
+  //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+  /*!\ingroup time_format
+   */
+  inline std::wstring to_iso_wstring(time_duration td){
+    return to_iso_string_type<wchar_t>(td);
+  }
+    inline std::wstring to_simple_wstring(ptime t){
+    return to_simple_string_type<wchar_t>(t);
+  }
+  //! Convert to wstring of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+  /*!\ingroup time_format
+   */
+  inline std::wstring to_simple_wstring(time_period tp){
+    return to_simple_string_type<wchar_t>(tp);
+  }
+  //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline std::wstring to_iso_wstring(ptime t){
+    return to_iso_string_type<wchar_t>(t);
+  }
+  //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline std::wstring to_iso_extended_wstring(ptime t){
+    return to_iso_extended_string_type<wchar_t>(t);
+  }
+
+#endif // BOOST_NO_STD_WSTRING
+
+
+} } //namespace posix_time
+
+
+#endif
+

+ 211 - 0
ext/boost/date_time/posix_time/time_formatters_limited.hpp

@@ -0,0 +1,211 @@
+#ifndef POSIXTIME_FORMATTERS_LIMITED_HPP___
+#define POSIXTIME_FORMATTERS_LIMITED_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/iso_format.hpp"
+#include "boost/date_time/date_format_simple.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+#include "boost/date_time/time_formatting_streams.hpp"
+ 
+namespace boost {
+
+namespace posix_time {
+
+  //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456
+  /*!\ingroup time_format
+   */
+  inline std::string to_simple_string(time_duration td) {
+    std::ostringstream ss;
+    if(td.is_special()) {
+      /* simply using 'ss << td.get_rep()' won't work on compilers
+       * that don't support locales. This way does. */
+      // switch copied from date_names_put.hpp
+      switch(td.get_rep().as_special())
+      {
+      case not_a_date_time:
+        //ss << "not-a-number";
+        ss << "not-a-date-time";
+        break;
+      case pos_infin:
+        ss << "+infinity";
+        break;
+      case neg_infin:
+        ss << "-infinity";
+        break;
+      default:
+        ss << "";
+      }
+    }
+    else {
+      if(td.is_negative()) {
+        ss << '-';
+      }
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.hours()) << ":";
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.minutes()) << ":";
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.seconds());
+      //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+      boost::int64_t frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+      // JDG [7/6/02 VC++ compatibility]
+      char buff[32];
+      _i64toa(frac_sec, buff, 10);
+#else
+      time_duration::fractional_seconds_type frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+#endif
+      if (frac_sec != 0) {
+        ss  << "." << std::setw(time_duration::num_fractional_digits())
+            << std::setfill('0')
+          
+          // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+            << buff;
+#else
+        << frac_sec;
+#endif
+      }
+    }// else
+    return ss.str();
+  }
+
+  //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456
+  /*!\ingroup time_format
+   */
+  inline 
+  std::string 
+  to_iso_string(time_duration td) 
+  {
+    std::ostringstream ss;
+    if(td.is_special()) {
+      /* simply using 'ss << td.get_rep()' won't work on compilers
+       * that don't support locales. This way does. */
+      // switch copied from date_names_put.hpp
+      switch(td.get_rep().as_special()) {
+      case not_a_date_time:
+        //ss << "not-a-number";
+        ss << "not-a-date-time";
+        break;
+      case pos_infin:
+        ss << "+infinity";
+        break;
+      case neg_infin:
+        ss << "-infinity";
+        break;
+      default:
+        ss << "";
+      }
+    }
+    else {
+      if(td.is_negative()) {
+        ss << '-';
+      }
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.hours());
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.minutes());
+      ss  << std::setw(2) << std::setfill('0') 
+          << date_time::absolute_value(td.seconds());
+      //TODO the following is totally non-generic, yelling FIXME
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+      boost::int64_t frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+      // JDG [7/6/02 VC++ compatibility]
+      char buff[32];
+      _i64toa(frac_sec, buff, 10);
+#else
+      time_duration::fractional_seconds_type frac_sec = 
+        date_time::absolute_value(td.fractional_seconds());
+#endif
+      if (frac_sec != 0) {
+        ss  << "." << std::setw(time_duration::num_fractional_digits())
+            << std::setfill('0')
+          
+          // JDG [7/6/02 VC++ compatibility]
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+            << buff;
+#else
+        << frac_sec;
+#endif
+      }
+    }// else
+    return ss.str();
+  }
+
+  //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff
+  /*!\ingroup time_format
+   */
+  inline 
+  std::string 
+  to_simple_string(ptime t) 
+  {
+    std::string ts = gregorian::to_simple_string(t.date());// + " ";
+    if(!t.time_of_day().is_special()) {
+      return ts + " " + to_simple_string(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+
+  //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff]
+  /*!\ingroup time_format
+   */
+  inline 
+  std::string 
+  to_simple_string(time_period tp) 
+  {
+    std::string d1(to_simple_string(tp.begin()));
+    std::string d2(to_simple_string(tp.last()));
+    return std::string("[" + d1 + "/" + d2 +"]");
+  }
+
+  //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline 
+  std::string to_iso_string(ptime t) 
+  {
+    std::string ts = gregorian::to_iso_string(t.date());// + "T";
+    if(!t.time_of_day().is_special()) {
+      return ts + "T" + to_iso_string(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+
+  //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator
+  /*!\ingroup time_format
+   */
+  inline 
+  std::string 
+  to_iso_extended_string(ptime t) 
+  {
+    std::string ts = gregorian::to_iso_extended_string(t.date());// + "T";
+    if(!t.time_of_day().is_special()) {
+      return ts + "T" + to_simple_string(t.time_of_day());
+    }
+    else {
+      return ts;
+    }
+  }
+
+
+} } //namespace posix_time
+
+
+#endif
+

+ 44 - 0
ext/boost/date_time/posix_time/time_parsers.hpp

@@ -0,0 +1,44 @@
+#ifndef POSIXTIME_PARSERS_HPP___
+#define POSIXTIME_PARSERS_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/gregorian/gregorian.hpp"
+#include "boost/date_time/time_parsing.hpp"
+#include "boost/date_time/posix_time/posix_time_types.hpp"
+
+ 
+namespace boost {
+
+namespace posix_time {
+
+  //! Creates a time_duration object from a delimited string
+  /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+   * A negative duration will be created if the first character in
+   * string is a '-', all other '-' will be treated as delimiters.
+   * Accepted delimiters are "-:,.". */
+  inline time_duration duration_from_string(const std::string& s) {
+    return date_time::parse_delimited_time_duration<time_duration>(s);
+  }
+
+  inline ptime time_from_string(const std::string& s) {
+    return date_time::parse_delimited_time<ptime>(s, ' ');
+  }
+
+  inline ptime from_iso_string(const std::string& s) {
+    return date_time::parse_iso_time<ptime>(s, 'T');
+  }
+
+
+
+} } //namespace posix_time
+
+
+#endif
+

+ 29 - 0
ext/boost/date_time/posix_time/time_period.hpp

@@ -0,0 +1,29 @@
+#ifndef POSIX_TIME_PERIOD_HPP___
+#define POSIX_TIME_PERIOD_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/period.hpp"
+#include "boost/date_time/posix_time/posix_time_duration.hpp"
+#include "boost/date_time/posix_time/ptime.hpp"
+
+namespace boost {
+namespace posix_time {
+
+  //! Time period type
+  /*! \ingroup time_basics
+   */
+  typedef date_time::period<ptime, time_duration> time_period;
+
+
+} }//namespace posix_time
+
+
+#endif
+

+ 200 - 0
ext/boost/date_time/posix_time/time_serialize.hpp

@@ -0,0 +1,200 @@
+#ifndef POSIX_TIME_SERIALIZE_HPP___
+#define POSIX_TIME_SERIALIZE_HPP___
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include "boost/date_time/gregorian/greg_serialize.hpp"
+#include "boost/serialization/split_free.hpp"
+
+
+// macros to split serialize functions into save & load functions
+// NOTE: these macros define template functions in the boost::serialization namespace.
+// They must be expanded *outside* of any namespace
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::ptime)
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_duration)
+BOOST_SERIALIZATION_SPLIT_FREE(boost::posix_time::time_period)
+
+namespace boost {
+namespace serialization {
+
+
+/*** time_duration ***/
+
+//! Function to save posix_time::time_duration objects using serialization lib
+/*! time_duration objects are broken down into 4 parts for serialization:
+ * types are hour_type, min_type, sec_type, and fractional_seconds_type
+ * as defined in the time_duration class
+ */
+template<class Archive>
+void save(Archive & ar, 
+          const posix_time::time_duration& td, 
+          unsigned int /*version*/)
+{
+  // serialize a bool so we know how to read this back in later
+  bool is_special = td.is_special();
+  ar & make_nvp("is_special", is_special);
+  if(is_special) {
+    std::string s = to_simple_string(td);
+    ar & make_nvp("sv_time_duration", s);
+  }
+  else {
+    typename posix_time::time_duration::hour_type h = td.hours();
+    typename posix_time::time_duration::min_type m = td.minutes();
+    typename posix_time::time_duration::sec_type s = td.seconds();
+    typename posix_time::time_duration::fractional_seconds_type fs = td.fractional_seconds();
+    ar & make_nvp("time_duration_hours", h);
+    ar & make_nvp("time_duration_minutes", m);
+    ar & make_nvp("time_duration_seconds", s);
+    ar & make_nvp("time_duration_fractional_seconds", fs);
+  }
+}
+
+//! Function to load posix_time::time_duration objects using serialization lib
+/*! time_duration objects are broken down into 4 parts for serialization:
+ * types are hour_type, min_type, sec_type, and fractional_seconds_type
+ * as defined in the time_duration class
+ */
+template<class Archive>
+void load(Archive & ar, 
+          posix_time::time_duration & td, 
+          unsigned int /*version*/)
+{
+  bool is_special = false;
+  ar & make_nvp("is_special", is_special);
+  if(is_special) {
+    std::string s;
+    ar & make_nvp("sv_time_duration", s);
+    posix_time::special_values sv = gregorian::special_value_from_string(s);
+    td = posix_time::time_duration(sv);
+  }
+  else {
+    typename posix_time::time_duration::hour_type h(0);
+    typename posix_time::time_duration::min_type m(0);
+    typename posix_time::time_duration::sec_type s(0);
+    typename posix_time::time_duration::fractional_seconds_type fs(0);
+    ar & make_nvp("time_duration_hours", h);
+    ar & make_nvp("time_duration_minutes", m);
+    ar & make_nvp("time_duration_seconds", s);
+    ar & make_nvp("time_duration_fractional_seconds", fs);
+    td = posix_time::time_duration(h,m,s,fs);
+  }
+}
+
+// no load_construct_data function provided as time_duration provides a
+// default constructor
+
+/*** ptime ***/
+
+//! Function to save posix_time::ptime objects using serialization lib
+/*! ptime objects are broken down into 2 parts for serialization:
+ * a date object and a time_duration onject
+ */
+template<class Archive>
+void save(Archive & ar, 
+          const posix_time::ptime& pt, 
+          unsigned int /*version*/)
+{
+  // from_iso_string does not include fractional seconds
+  // therefore date and time_duration are used
+  typename posix_time::ptime::date_type d = pt.date();
+  ar & make_nvp("ptime_date", d);
+  if(!pt.is_special()) {
+    typename posix_time::ptime::time_duration_type td = pt.time_of_day();
+    ar & make_nvp("ptime_time_duration", td);
+  }
+}
+
+//! Function to load posix_time::ptime objects using serialization lib
+/*! ptime objects are broken down into 2 parts for serialization:
+ * a date object and a time_duration onject
+ */
+template<class Archive>
+void load(Archive & ar, 
+          posix_time::ptime & pt, 
+          unsigned int /*version*/)
+{
+  // from_iso_string does not include fractional seconds
+  // therefore date and time_duration are used
+  typename posix_time::ptime::date_type d(posix_time::not_a_date_time);
+  typename posix_time::ptime::time_duration_type td;
+  ar & make_nvp("ptime_date", d);
+  if(!d.is_special()) {
+    ar & make_nvp("ptime_time_duration", td);
+    pt = boost::posix_time::ptime(d,td);
+  }
+  else {
+    pt = boost::posix_time::ptime(d.as_special());
+  }
+    
+}
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                posix_time::ptime* pt, 
+                                const unsigned int /*file_version*/)
+{
+  // retrieve data from archive required to construct new 
+  // invoke inplace constructor to initialize instance of date
+  new(pt) boost::posix_time::ptime(boost::posix_time::not_a_date_time);
+}
+
+/*** time_period ***/
+
+//! Function to save posix_time::time_period objects using serialization lib
+/*! time_period objects are broken down into 2 parts for serialization:
+ * a begining ptime object and an ending ptime object
+ */
+template<class Archive>
+void save(Archive & ar, 
+          const posix_time::time_period& tp, 
+          unsigned int /*version*/)
+{
+  posix_time::ptime beg(tp.begin().date(), tp.begin().time_of_day());
+  posix_time::ptime end(tp.end().date(), tp.end().time_of_day());
+  ar & make_nvp("time_period_begin", beg);
+  ar & make_nvp("time_period_end", end);
+}
+
+//! Function to load posix_time::time_period objects using serialization lib
+/*! time_period objects are broken down into 2 parts for serialization:
+ * a begining ptime object and an ending ptime object
+ */
+template<class Archive>
+void load(Archive & ar, 
+          boost::posix_time::time_period & tp, 
+          unsigned int /*version*/)
+{
+  posix_time::time_duration td(1,0,0);
+  gregorian::date d(gregorian::not_a_date_time);
+  posix_time::ptime beg(d,td);
+  posix_time::ptime end(d,td);
+  ar & make_nvp("time_period_begin", beg);
+  ar & make_nvp("time_period_end", end);
+  tp = boost::posix_time::time_period(beg, end);
+}
+
+//!override needed b/c no default constructor
+template<class Archive>
+inline void load_construct_data(Archive & ar, 
+                                boost::posix_time::time_period* tp, 
+                                const unsigned int /*file_version*/)
+{
+  posix_time::time_duration td(1,0,0);
+  gregorian::date d(gregorian::not_a_date_time);
+  posix_time::ptime beg(d,td);
+  posix_time::ptime end(d,td);
+  new(tp) boost::posix_time::time_period(beg,end);
+}
+
+} // namespace serialization
+} // namespace boost
+
+#endif

+ 25 - 0
ext/boost/date_time/special_defs.hpp

@@ -0,0 +1,25 @@
+#ifndef DATE_TIME_SPECIAL_DEFS_HPP__
+#define DATE_TIME_SPECIAL_DEFS_HPP__
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+namespace boost {
+namespace date_time {
+
+    enum special_values {not_a_date_time, 
+                         neg_infin, pos_infin, 
+                         min_date_time,  max_date_time,
+                         not_special, NumSpecialValues};
+
+
+} } //namespace date_time
+
+
+#endif
+

+ 96 - 0
ext/boost/date_time/special_values_formatter.hpp

@@ -0,0 +1,96 @@
+
+#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
+#define DATETIME_SPECIAL_VALUE_FORMATTER_HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include <vector>
+#include <string>
+#include "boost/date_time/special_defs.hpp"
+
+namespace boost { namespace date_time {
+
+
+  //! Class that provides generic formmatting ostream formatting for special values
+  /*! This class provides for the formmating of special values to an output stream.
+   *  In particular, it produces strings for the values of negative and positive
+   *  infinity as well as not_a_date_time.  
+   *
+   *  While not a facet, this class is used by the date and time facets for formatting
+   *  special value types.
+   *
+   */
+  template <class CharT, class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
+  class special_values_formatter  
+  {
+  public:
+    typedef std::basic_string<CharT> string_type;
+    typedef CharT                    char_type;
+    typedef std::vector<string_type> collection_type;
+    static const char_type default_special_value_names[3][17];
+
+    //! Construct special values formatter using default strings.
+    /*! Default strings are not-a-date-time -infinity +infinity
+     */
+    special_values_formatter() 
+    {
+      std::copy(&default_special_value_names[0], 
+                &default_special_value_names[3], 
+                std::back_inserter(m_special_value_names));      
+    }
+
+    //! Construct special values formatter from array of strings
+    /*! This constructor will take pair of iterators from an array of strings
+     *  that represent the special values and copy them for use in formatting
+     *  special values.  
+     *@code
+     *  const char* const special_value_names[]={"nadt","-inf","+inf" };
+     *
+     *  special_value_formatter svf(&special_value_names[0], &special_value_names[3]);
+     *@endcode
+     */
+    special_values_formatter(const char_type* const* begin, const char_type* const* end) 
+    {
+      std::copy(begin, end, std::back_inserter(m_special_value_names));
+    }
+    special_values_formatter(typename collection_type::iterator beg, typename collection_type::iterator end)
+    {
+      std::copy(beg, end, std::back_inserter(m_special_value_names));
+    }
+
+    OutItrT put_special(OutItrT next, 
+                        const boost::date_time::special_values& value) const 
+    {
+      
+      unsigned int index = value;
+      if (index < m_special_value_names.size()) {
+        std::copy(m_special_value_names[index].begin(), 
+                  m_special_value_names[index].end(),
+                  next);
+      }
+      return next;
+    }
+  protected:
+    collection_type m_special_value_names;
+  };
+
+  //! Storage for the strings used to indicate special values 
+  /* using c_strings to initialize these worked fine in testing, however,
+   * a project that compiled its objects separately, then linked in a separate
+   * step wound up with redefinition errors for the values in this array.
+   * Initializing individual characters eliminated this problem */
+  template <class CharT, class OutItrT>  
+  const typename special_values_formatter<CharT, OutItrT>::char_type special_values_formatter<CharT, OutItrT>::default_special_value_names[3][17] = { 
+    {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'},
+    {'-','i','n','f','i','n','i','t','y'},
+    {'+','i','n','f','i','n','i','t','y'} };
+
+ } } //namespace boost::date_time
+
+#endif

+ 159 - 0
ext/boost/date_time/special_values_parser.hpp

@@ -0,0 +1,159 @@
+
+#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+
+/* Copyright (c) 2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 
+ */
+
+
+#include "boost/date_time/string_parse_tree.hpp"
+#include "boost/date_time/special_defs.hpp"
+#include <string>
+#include <vector>
+
+namespace boost { namespace date_time {
+
+  //! Class for special_value parsing 
+  /*! 
+   * TODO: add doc-comments for which elements can be changed
+   * Parses input stream for strings representing special_values. 
+   * Special values parsed are:
+   *  - not_a_date_time
+   *  - neg_infin
+   *  - pod_infin
+   *  - min_date_time
+   *  - max_date_time
+   */
+  template<class date_type, typename charT>
+  class special_values_parser
+  {
+   public:
+    typedef std::basic_string<charT>        string_type;
+    //typedef std::basic_stringstream<charT>  stringstream_type;
+    typedef std::istreambuf_iterator<charT> stream_itr_type;
+    //typedef typename string_type::const_iterator const_itr;
+    //typedef typename date_type::year_type  year_type;
+    //typedef typename date_type::month_type month_type;
+    typedef typename date_type::duration_type duration_type;
+    //typedef typename date_type::day_of_week_type day_of_week_type;
+    //typedef typename date_type::day_type day_type;
+    typedef string_parse_tree<charT> parse_tree_type;
+    typedef typename parse_tree_type::parse_match_result_type match_results;
+    typedef std::vector<std::basic_string<charT> > collection_type;
+
+    typedef charT char_type;
+    static const char_type nadt_string[16];
+    static const char_type neg_inf_string[10];
+    static const char_type pos_inf_string[10];
+    static const char_type min_date_time_string[18];
+    static const char_type max_date_time_string[18];
+   
+    //! Creates a special_values_parser with the default set of "sv_strings"
+    special_values_parser()
+    {
+      sv_strings(string_type(nadt_string),
+                 string_type(neg_inf_string),
+                 string_type(pos_inf_string),
+                 string_type(min_date_time_string),
+                 string_type(max_date_time_string));
+    }
+
+    //! Creates a special_values_parser using a user defined set of element strings
+    special_values_parser(const string_type& nadt_str,
+                          const string_type& neg_inf_str,
+                          const string_type& pos_inf_str,
+                          const string_type& min_dt_str,
+                          const string_type& max_dt_str)
+    {
+      sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str);
+    }
+
+    special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end)
+    {
+      collection_type phrases;
+      std::copy(beg, end, std::back_inserter(phrases));
+      m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
+    }
+
+    special_values_parser(const special_values_parser<date_type,charT>& svp)
+    {
+      this->m_sv_strings = svp.m_sv_strings;
+    }
+
+    //! Replace special value strings
+    void sv_strings(const string_type& nadt_str,
+                    const string_type& neg_inf_str,
+                    const string_type& pos_inf_str,
+                    const string_type& min_dt_str,
+                    const string_type& max_dt_str)
+    {
+      collection_type phrases;
+      phrases.push_back(nadt_str);
+      phrases.push_back(neg_inf_str);
+      phrases.push_back(pos_inf_str);
+      phrases.push_back(min_dt_str);
+      phrases.push_back(max_dt_str);
+      m_sv_strings = parse_tree_type(phrases, static_cast<int>(not_a_date_time));
+    }
+
+    /* Does not return a special_value because if the parsing fails, 
+     * the return value will always be not_a_date_time 
+     * (mr.current_match retains its default value of -1 on a failed 
+     * parse and that casts to not_a_date_time). */
+    //! Sets match_results.current_match to the corresponding special_value or -1
+    bool match(stream_itr_type& sitr, 
+                        stream_itr_type& str_end,
+                        match_results& mr) const
+    {
+      unsigned int level = 0;
+      m_sv_strings.match(sitr, str_end, mr, level);
+      return (mr.current_match != match_results::PARSE_ERROR);
+    }
+    /*special_values match(stream_itr_type& sitr, 
+                        stream_itr_type& str_end,
+                        match_results& mr) const
+    {
+      unsigned int level = 0;
+      m_sv_strings.match(sitr, str_end, mr, level);
+      if(mr.current_match == match_results::PARSE_ERROR) {
+        throw std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'");
+      }
+      return static_cast<special_values>(mr.current_match);
+    }*/
+                     
+
+   private:
+    parse_tree_type m_sv_strings;
+    
+  };
+
+  template<class date_type, class CharT>
+  const typename special_values_parser<date_type, CharT>::char_type
+  special_values_parser<date_type, CharT>::nadt_string[16] =
+  {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'};
+  template<class date_type, class CharT>
+  const typename special_values_parser<date_type, CharT>::char_type
+  special_values_parser<date_type, CharT>::neg_inf_string[10] =
+  {'-','i','n','f','i','n','i','t','y'};
+  template<class date_type, class CharT>
+  const typename special_values_parser<date_type, CharT>::char_type
+  special_values_parser<date_type, CharT>::pos_inf_string[10] =
+  {'+','i','n','f','i','n','i','t','y'};
+  template<class date_type, class CharT>
+  const typename special_values_parser<date_type, CharT>::char_type
+  special_values_parser<date_type, CharT>::min_date_time_string[18] =
+  {'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
+  template<class date_type, class CharT>
+  const typename special_values_parser<date_type, CharT>::char_type
+  special_values_parser<date_type, CharT>::max_date_time_string[18] =
+  {'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'};
+
+} } //namespace
+
+#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__
+

+ 33 - 0
ext/boost/date_time/string_convert.hpp

@@ -0,0 +1,33 @@
+#ifndef _STRING_CONVERT_HPP___
+#define _STRING_CONVERT_HPP___
+
+/* Copyright (c) 2005 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/date_time/compiler_config.hpp"
+#include <string>
+
+namespace boost {
+namespace date_time {
+
+  //! Converts a string from one value_type to another
+  /*! Converts a wstring to a string (or a string to wstring). If both template parameters 
+   * are of same type, a copy of the input string is returned. */
+  template<class InputT, class OutputT>
+  inline
+  std::basic_string<OutputT> convert_string_type(const std::basic_string<InputT>& inp_str)
+  {
+    typedef std::basic_string<InputT> input_type;
+    typedef std::basic_string<OutputT> output_type;
+    output_type result;
+    result.insert(result.begin(), inp_str.begin(), inp_str.end());
+    return result;
+  }
+  
+}} // namespace boost::date_time
+
+#endif // _STRING_CONVERT_HPP___

+ 278 - 0
ext/boost/date_time/string_parse_tree.hpp

@@ -0,0 +1,278 @@
+#ifndef BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__
+#define BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__
+
+/* Copyright (c) 2004-2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+#include "boost/lexical_cast.hpp" //error without?
+#include "boost/algorithm/string/case_conv.hpp"
+#include <map>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+namespace boost { namespace date_time {
+
+
+template<typename charT>
+struct parse_match_result
+{
+  parse_match_result() :
+    match_depth(0),
+    current_match(-1)// -1 is match_not-found value
+  {}
+  typedef std::basic_string<charT> string_type;
+  string_type remaining() const
+  {
+    if (match_depth == cache.size()) {
+      return string_type();
+    }
+    if (current_match == -1) {
+      return cache;
+    }
+    //some of the cache was used return the rest
+    return string_type(cache, match_depth);
+  }
+  charT last_char() const
+  {
+    return cache[cache.size()-1];
+  }
+  //! Returns true if more characters were parsed than was necessary
+  /*! Should be used in conjunction with last_char()
+   *  to get the remaining character.
+   */
+  bool has_remaining() const
+  {
+    return (cache.size() > match_depth);
+  }
+
+  // cache will hold characters that have been read from the stream
+  string_type cache;
+  unsigned short match_depth;
+  short current_match;
+  enum PARSE_STATE { PARSE_ERROR= -1 };
+};
+
+  //for debug -- really only char streams...
+template<typename charT>
+std::basic_ostream<charT>&
+operator<<(std::basic_ostream<charT>& os, parse_match_result<charT>& mr)
+{
+  os << "cm: " << mr.current_match
+     << " C: '" << mr.cache
+     << "' md: " << mr.match_depth
+     << " R: " << mr.remaining();
+  return os;
+}
+
+
+
+//! Recursive data structure to allow efficient parsing of various strings
+/*! This class provides a quick lookup by building what amounts to a
+ *  tree data structure.  It also features a match function which can
+ *  can handle nasty input interators by caching values as it recurses
+ *  the tree so that it can backtrack as needed.
+ */
+template<typename charT>
+struct string_parse_tree
+{
+#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
+  typedef std::multimap<charT, string_parse_tree< charT> > ptree_coll;
+#else
+  typedef std::multimap<charT, string_parse_tree > ptree_coll;
+#endif
+  typedef typename ptree_coll::value_type value_type;
+  typedef typename ptree_coll::iterator iterator;
+  typedef typename ptree_coll::const_iterator const_iterator;
+  typedef std::basic_string<charT> string_type;
+  typedef std::vector<std::basic_string<charT> > collection_type;
+  typedef parse_match_result<charT> parse_match_result_type;
+
+  /*! Parameter "starting_point" designates where the numbering begins.
+   * A starting_point of zero will start the numbering at zero
+   * (Sun=0, Mon=1, ...) were a starting_point of one starts the
+   * numbering at one (Jan=1, Feb=2, ...). The default is zero,
+   * negative vaules are not allowed */
+  string_parse_tree(collection_type names, unsigned int starting_point=0)
+  {
+    // iterate thru all the elements and build the tree
+    unsigned short index = 0;
+    while (index != names.size() ) {
+      string_type s = boost::algorithm::to_lower_copy(names[index]);
+      insert(s, static_cast<unsigned short>(index + starting_point));
+      index++;
+    }
+    //set the last tree node = index+1  indicating a value
+    index++;
+  }
+
+
+  string_parse_tree(short value = -1) :
+    m_value(value)
+  {}
+  ptree_coll m_next_chars;
+  short m_value;
+
+  void insert(const string_type& s, unsigned short value)
+  {
+    unsigned int i = 0;
+    iterator ti;
+    while(i < s.size()) {
+      if (i==0) {
+        if (i == (s.size()-1)) {
+          ti = m_next_chars.insert(value_type(s[i],
+                                              string_parse_tree<charT>(value)));
+        }
+        else {
+          ti = m_next_chars.insert(value_type(s[i],
+                                              string_parse_tree<charT>()));
+        }
+      }
+      else {
+        if (i == (s.size()-1)) {
+          ti = ti->second.m_next_chars.insert(value_type(s[i],
+                                                         string_parse_tree<charT>(value)));
+        }
+
+        else {
+          ti = ti->second.m_next_chars.insert(value_type(s[i],
+                                                         string_parse_tree<charT>()));
+        }
+
+      }
+      i++;
+    }
+  }
+
+
+  //! Recursive function that finds a matching string in the tree.
+  /*! Must check match_results::has_remaining() after match() is
+   * called. This is required so the user can determine if
+   * stream iterator is already pointing to the expected
+   * character or not (match() might advance sitr to next char in stream).
+   *
+   * A parse_match_result that has been returned from a failed match
+   * attempt can be sent in to the match function of a different
+   * string_parse_tree to attempt a match there. Use the iterators
+   * for the partially consumed stream, the parse_match_result object,
+   * and '0' for the level parameter. */
+  short
+  match(std::istreambuf_iterator<charT>& sitr,
+        std::istreambuf_iterator<charT>& stream_end,
+        parse_match_result_type& result,
+        unsigned int& level)  const
+  {
+
+    level++;
+    charT c;
+    // if we conditionally advance sitr, we won't have
+    // to consume the next character past the input
+    bool adv_itr = true;
+    if (level > result.cache.size()) {
+      if (sitr == stream_end) return 0; //bail - input exhausted
+      c = static_cast<charT>(std::tolower(*sitr));
+      //result.cache += c;
+      //sitr++;
+    }
+    else {
+      // if we're looking for characters from the cache,
+      // we don't want to increment sitr
+      adv_itr = false;
+      c = static_cast<charT>(std::tolower(result.cache[level-1]));
+    }
+    const_iterator litr = m_next_chars.lower_bound(c);
+    const_iterator uitr = m_next_chars.upper_bound(c);
+    while (litr != uitr) { // equal if not found
+      if(adv_itr) {
+        sitr++;
+        result.cache += c;
+      }
+      if (litr->second.m_value != -1) { // -1 is default value
+        if (result.match_depth < level) {
+          result.current_match = litr->second.m_value;
+          result.match_depth = static_cast<unsigned short>(level);
+        }
+        litr->second.match(sitr, stream_end,
+                           result, level);
+        level--;
+      }
+      else {
+        litr->second.match(sitr, stream_end,
+                           result, level);
+        level--;
+      }
+
+      if(level <= result.cache.size()) {
+        adv_itr = false;
+      }
+
+      litr++;
+    }
+    return result.current_match;
+
+  }
+
+  /*! Must check match_results::has_remaining() after match() is
+   * called. This is required so the user can determine if
+   * stream iterator is already pointing to the expected
+   * character or not (match() might advance sitr to next char in stream).
+   */
+  parse_match_result_type
+  match(std::istreambuf_iterator<charT>& sitr,
+        std::istreambuf_iterator<charT>& stream_end) const
+  {
+    // lookup to_lower of char in tree.
+    unsigned int level = 0;
+    //    string_type cache;
+    parse_match_result_type result;
+    match(sitr, stream_end, result, level);
+    return result;
+  }
+
+  void printme(std::ostream& os, int& level)
+  {
+    level++;
+    iterator itr = m_next_chars.begin();
+    iterator end = m_next_chars.end();
+    //    os << "starting level: " << level << std::endl;
+    while (itr != end) {
+      os << "level:  " << level
+         << " node:  " << itr->first
+         << " value: " << itr->second.m_value
+         << std::endl;
+      itr->second.printme(os, level);
+      itr++;
+    }
+    level--;
+  }
+
+  void print(std::ostream& os)
+  {
+    int level = 0;
+    printme(os, level);
+  }
+
+  void printmatch(std::ostream& os, charT c)
+  {
+    iterator litr = m_next_chars.lower_bound(c);
+    iterator uitr = m_next_chars.upper_bound(c);
+    os << "matches for: " << c << std::endl;
+    while (litr != uitr) {
+      os << " node:  " << litr->first
+         << " value: " << litr->second.m_value
+         << std::endl;
+      litr++;
+    }
+  }
+
+};
+
+
+} } //namespace
+#endif

+ 125 - 0
ext/boost/date_time/strings_from_facet.hpp

@@ -0,0 +1,125 @@
+#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___
+#define DATE_TIME_STRINGS_FROM_FACET__HPP___
+
+/* Copyright (c) 2004 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland
+ * $Date: 2009-02-01 06:29:43 -0500 (Sun, 01 Feb 2009) $
+ */
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include <locale>
+
+namespace boost { namespace date_time {
+
+//! This function gathers up all the month strings from a std::locale
+/*! Using the time_put facet, this function creates a collection of
+ *  all the month strings from a locale.  This is handy when building
+ *  custom date parsers or formatters that need to be localized.
+ *
+ *@param charT The type of char to use when gathering typically char
+ *             or wchar_t.
+ *@param locale The locale to use when gathering the strings
+ *@param short_strings True(default) to gather short strings,
+ *                     false for long strings.
+ *@return A vector of strings containing the strings in order. eg:
+ *        Jan, Feb, Mar, etc.
+ */
+template<typename charT>
+std::vector<std::basic_string<charT> >
+gather_month_strings(const std::locale& locale, bool short_strings=true)
+{
+  typedef std::basic_string<charT> string_type;
+  typedef std::vector<string_type> collection_type;
+  typedef std::basic_ostringstream<charT> ostream_type;
+  typedef std::ostreambuf_iterator<charT> ostream_iter_type;
+  typedef std::basic_ostringstream<charT> stringstream_type;
+  typedef std::time_put<charT>           time_put_facet_type;
+  charT short_fmt[3] = { '%', 'b' };
+  charT long_fmt[3]  = { '%', 'B' };
+  collection_type months;
+  string_type outfmt(short_fmt);
+  if (!short_strings) {
+    outfmt = long_fmt;
+  }
+  {
+    //grab the needed strings by using the locale to
+    //output each month
+    const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
+    for (int m=0; m < 12; m++) {
+      tm tm_value;
+      tm_value.tm_mon = m;
+      stringstream_type ss;
+      ostream_iter_type oitr(ss);
+      std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
+                                                      &tm_value,
+                                                      p_outfmt,
+                                                      p_outfmt_end);
+      months.push_back(ss.str());
+    }
+  }
+  return months;
+}
+
+//! This function gathers up all the weekday strings from a std::locale
+/*! Using the time_put facet, this function creates a collection of
+ *  all the weekday strings from a locale starting with the string for
+ *  'Sunday'.  This is handy when building custom date parsers or
+ *  formatters that need to be localized.
+ *
+ *@param charT The type of char to use when gathering typically char
+ *             or wchar_t.
+ *@param locale The locale to use when gathering the strings
+ *@param short_strings True(default) to gather short strings,
+ *                     false for long strings.
+ *@return A vector of strings containing the weekdays in order. eg:
+ *        Sun, Mon, Tue, Wed, Thu, Fri, Sat
+ */
+template<typename charT>
+std::vector<std::basic_string<charT> >
+gather_weekday_strings(const std::locale& locale, bool short_strings=true)
+{
+  typedef std::basic_string<charT> string_type;
+  typedef std::vector<string_type> collection_type;
+  typedef std::basic_ostringstream<charT> ostream_type;
+  typedef std::ostreambuf_iterator<charT> ostream_iter_type;
+  typedef std::basic_ostringstream<charT> stringstream_type;
+  typedef std::time_put<charT>           time_put_facet_type;
+  charT short_fmt[3] = { '%', 'a' };
+  charT long_fmt[3]  = { '%', 'A' };
+
+  collection_type weekdays;
+
+
+  string_type outfmt(short_fmt);
+  if (!short_strings) {
+    outfmt = long_fmt;
+  }
+  {
+    //grab the needed strings by using the locale to
+    //output each month / weekday
+    const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size();
+    for (int i=0; i < 7; i++) {
+      tm tm_value;
+      tm_value.tm_wday = i;
+      stringstream_type ss;
+      ostream_iter_type oitr(ss);
+      std::use_facet<time_put_facet_type>(locale).put(oitr, ss, ss.fill(),
+                                                      &tm_value,
+                                                      p_outfmt,
+                                                      p_outfmt_end);
+
+      weekdays.push_back(ss.str());
+    }
+  }
+  return weekdays;
+}
+
+} } //namespace
+
+
+#endif

+ 191 - 0
ext/boost/date_time/time.hpp

@@ -0,0 +1,191 @@
+#ifndef DATE_TIME_TIME_HPP___
+#define DATE_TIME_TIME_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+/*! @file time.hpp
+  This file contains the interface for the time associated classes.
+*/
+#include <string>
+#include <boost/operators.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/special_defs.hpp>
+
+namespace boost {
+namespace date_time {
+
+  //! Representation of a precise moment in time, including the date.
+  /*! 
+    This class is a skeleton for the interface of a temporal type
+    with a resolution that is higher than a day.  It is intended that 
+    this class be the base class and that the actual time 
+    class be derived using the BN pattern.  In this way, the derived 
+    class can make decisions such as 'should there be a default constructor' 
+    and what should it set its value to, should there be optional constructors
+    say allowing only an time_durations that generate a time from a clock,etc.
+    So, in fact multiple time types can be created for a time_system with
+    different construction policies, and all of them can perform basic
+    operations by only writing a copy constructor.  Finally, compiler 
+    errors are also shorter. 
+    
+    The real behavior of the time class is provided by the time_system
+    template parameter.  This class must provide all the logic
+    for addition, subtraction, as well as define all the interface
+    types.
+    
+  */
+
+  template <class T, class time_system>
+  class base_time : private
+      boost::less_than_comparable<T
+    , boost::equality_comparable<T
+      > >
+  {
+  public:
+    typedef T time_type;
+    typedef typename time_system::time_rep_type time_rep_type;
+    typedef typename time_system::date_type date_type;
+    typedef typename time_system::date_duration_type date_duration_type;
+    typedef typename time_system::time_duration_type time_duration_type;
+    //typedef typename time_system::hms_type hms_type;
+    
+    base_time(const date_type& day, 
+              const time_duration_type& td, 
+              dst_flags dst=not_dst) :
+      time_(time_system::get_time_rep(day, td, dst))
+    {}
+    base_time(special_values sv) :
+      time_(time_system::get_time_rep(sv))
+    {}
+    base_time(const time_rep_type& rhs) :
+      time_(rhs)
+    {}
+    date_type date() const
+    {
+      return time_system::get_date(time_);
+    }
+    time_duration_type time_of_day() const
+    {
+      return time_system::get_time_of_day(time_);
+    }
+    /*! Optional bool parameter will return time zone as an offset 
+     * (ie "+07:00"). Empty string is returned for classes that do 
+     * not use a time_zone */
+    std::string zone_name(bool /*as_offset*/=false) const
+    {
+      return time_system::zone_name(time_);
+    }
+    /*! Optional bool parameter will return time zone as an offset 
+     * (ie "+07:00"). Empty string is returned for classes that do 
+     * not use a time_zone */
+    std::string zone_abbrev(bool /*as_offset*/=false) const
+    {
+      return time_system::zone_name(time_);
+    }
+    //! An empty string is returned for classes that do not use a time_zone
+    std::string zone_as_posix_string() const
+    {
+      return std::string();
+    }
+
+    //! check to see if date is not a value
+    bool is_not_a_date_time()  const
+    {
+      return time_.is_not_a_date_time();
+    }
+    //! check to see if date is one of the infinity values
+    bool is_infinity()  const
+    {
+      return (is_pos_infinity() || is_neg_infinity()); 
+    }
+    //! check to see if date is greater than all possible dates
+    bool is_pos_infinity()  const
+    {
+      return time_.is_pos_infinity();
+    }
+    //! check to see if date is greater than all possible dates
+    bool is_neg_infinity()  const
+    {
+      return time_.is_neg_infinity();
+    }
+    //! check to see if time is a special value
+    bool is_special() const
+    {
+      return(is_not_a_date_time() || is_infinity());
+    }
+    //!Equality operator -- others generated by boost::equality_comparable
+    bool operator==(const time_type& rhs) const
+    {
+      return time_system::is_equal(time_,rhs.time_);
+    }
+    //!Equality operator -- others generated by boost::less_than_comparable
+    bool operator<(const time_type& rhs) const
+    {
+      return time_system::is_less(time_,rhs.time_);
+    }
+    //! difference between two times
+    time_duration_type operator-(const time_type& rhs) const
+    {
+      return time_system::subtract_times(time_, rhs.time_);
+    }
+    //! add date durations
+    time_type operator+(const date_duration_type& dd) const
+    {
+      return time_system::add_days(time_, dd);
+    }
+    time_type operator+=(const date_duration_type& dd)
+    {
+      time_ = (time_system::get_time_rep(date() + dd, time_of_day()));
+      return time_type(time_);
+    }
+    //! subtract date durations
+    time_type operator-(const date_duration_type& dd) const
+    {
+      return time_system::subtract_days(time_, dd);
+    }
+    time_type operator-=(const date_duration_type& dd)
+    {
+      time_ = (time_system::get_time_rep(date() - dd, time_of_day()));
+      return time_type(time_);
+    }
+    //! add time durations
+    time_type operator+(const time_duration_type& td) const
+    {
+      return time_type(time_system::add_time_duration(time_, td));
+    }
+    time_type operator+=(const time_duration_type& td)
+    {
+      time_ = (time_system::get_time_rep(date(), time_of_day() + td));
+      return time_type(time_);
+    }
+    //! subtract time durations
+    time_type operator-(const time_duration_type& rhs) const
+    {
+      return time_system::subtract_time_duration(time_, rhs);
+    }
+    time_type operator-=(const time_duration_type& td) 
+    {
+      time_ = (time_system::get_time_rep(date(), time_of_day() - td));
+      return time_type(time_);
+    }
+    
+  protected:
+    time_rep_type time_;
+  };
+
+
+
+
+
+} } //namespace date_time::boost
+
+
+#endif
+

+ 83 - 0
ext/boost/date_time/time_clock.hpp

@@ -0,0 +1,83 @@
+#ifndef DATE_TIME_TIME_CLOCK_HPP___
+#define DATE_TIME_TIME_CLOCK_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+/*! @file time_clock.hpp
+  This file contains the interface for clock devices.
+*/
+
+#include "boost/date_time/c_time.hpp"
+#include "boost/shared_ptr.hpp"
+
+namespace boost {
+namespace date_time {
+
+
+  //! A clock providing time level services based on C time_t capabilities
+  /*! This clock provides resolution to the 1 second level
+   */
+  template<class time_type>
+  class second_clock
+  {
+  public:
+    typedef typename time_type::date_type date_type;
+    typedef typename time_type::time_duration_type time_duration_type;
+
+    static time_type local_time()
+    {
+      ::std::time_t t;
+      ::std::time(&t);
+      ::std::tm curr, *curr_ptr;
+      //curr_ptr = ::std::localtime(&t);
+      curr_ptr = c_time::localtime(&t, &curr);
+      return create_time(curr_ptr);
+    }
+
+
+    //! Get the current day in universal date as a ymd_type
+    static time_type universal_time()
+    {
+
+      ::std::time_t t;
+      ::std::time(&t);
+      ::std::tm curr, *curr_ptr;
+      //curr_ptr = ::std::gmtime(&t);
+      curr_ptr = c_time::gmtime(&t, &curr);
+      return create_time(curr_ptr);
+    }
+
+    template<class time_zone_type>
+    static time_type local_time(boost::shared_ptr<time_zone_type> tz_ptr)
+    {
+      typedef typename time_type::utc_time_type utc_time_type;
+      utc_time_type utc_time = second_clock<utc_time_type>::universal_time();
+      return time_type(utc_time, tz_ptr);
+    }
+
+
+  private:
+    static time_type create_time(::std::tm* current)
+    {
+      date_type d(static_cast<unsigned short>(current->tm_year + 1900),
+                  static_cast<unsigned short>(current->tm_mon + 1),
+                  static_cast<unsigned short>(current->tm_mday));
+      time_duration_type td(current->tm_hour,
+                            current->tm_min,
+                            current->tm_sec);
+      return time_type(d,td);
+    }
+
+  };
+
+
+} } //namespace date_time
+
+
+#endif

+ 43 - 0
ext/boost/date_time/time_defs.hpp

@@ -0,0 +1,43 @@
+#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP
+#define DATE_TIME_TIME_PRECISION_LIMITS_HPP
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland 
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+
+
+/*! \file time_defs.hpp 
+  This file contains nice definitions for handling the resoluion of various time
+  reprsentations.
+*/
+
+namespace boost {
+namespace date_time {
+
+  //!Defines some nice types for handling time level resolutions
+  enum time_resolutions {
+    sec,
+    tenth,
+    hundreth, // deprecated misspelled version of hundredth
+    hundredth = hundreth,
+    milli,
+    ten_thousandth,
+    micro,
+    nano,
+    NumResolutions
+  };
+
+  //! Flags for daylight savings or summer time
+  enum dst_flags {not_dst, is_dst, calculate};
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 282 - 0
ext/boost/date_time/time_duration.hpp

@@ -0,0 +1,282 @@
+#ifndef DATE_TIME_TIME_DURATION_HPP___
+#define DATE_TIME_TIME_DURATION_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-04 04:24:49 -0400 (Thu, 04 Jun 2009) $
+ */
+
+#include <boost/cstdint.hpp>
+#include <boost/operators.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/special_defs.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+  //! Represents some amount of elapsed time measure to a given resolution
+  /*! This class represents a standard set of capabilities for all
+      counted time durations.  Time duration implementations should derive
+      from this class passing their type as the first template parameter.
+      This design allows the subclass duration types to provide custom
+      construction policies or other custom features not provided here.
+
+      @param T The subclass type
+      @param rep_type The time resolution traits for this duration type.
+  */
+  template<class T, typename rep_type>
+  class time_duration : private
+      boost::less_than_comparable<T
+    , boost::equality_comparable<T
+    > >
+  /* dividable, addable, and subtractable operator templates
+   * won't work with this class (MSVC++ 6.0). return type
+   * from '+=' is different than expected return type
+   * from '+'. multipliable probably wont work
+   * either (haven't tried) */
+  {
+  public:
+    typedef T duration_type;  //the subclass
+    typedef rep_type traits_type;
+    typedef typename rep_type::day_type  day_type;
+    typedef typename rep_type::hour_type hour_type;
+    typedef typename rep_type::min_type  min_type;
+    typedef typename rep_type::sec_type  sec_type;
+    typedef typename rep_type::fractional_seconds_type fractional_seconds_type;
+    typedef typename rep_type::tick_type tick_type;
+    typedef typename rep_type::impl_type impl_type;
+
+    time_duration() : ticks_(0) {}
+    time_duration(hour_type hours_in,
+                  min_type minutes_in,
+                  sec_type seconds_in=0,
+                  fractional_seconds_type frac_sec_in = 0) :
+      ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in))
+    {}
+    // copy constructor required for dividable<>
+    //! Construct from another time_duration (Copy constructor)
+    time_duration(const time_duration<T, rep_type>& other)
+      : ticks_(other.ticks_)
+    {}
+    //! Construct from special_values
+    time_duration(special_values sv) : ticks_(impl_type::from_special(sv))
+    {}
+    //! Returns smallest representable duration
+    static duration_type unit()
+    {
+      return duration_type(0,0,0,1);
+    }
+    //! Return the number of ticks in a second
+    static tick_type ticks_per_second()
+    {
+      return rep_type::res_adjust();
+    }
+    //! Provide the resolution of this duration type
+    static time_resolutions resolution()
+    {
+      return rep_type::resolution();
+    }
+    //! Returns number of hours in the duration
+    hour_type hours()   const
+    {
+      return static_cast<hour_type>(ticks() / (3600*ticks_per_second()));
+    }
+    //! Returns normalized number of minutes
+    min_type minutes() const
+    {
+      return static_cast<min_type>((ticks() / (60*ticks_per_second())) % 60);
+    }
+    //! Returns normalized number of seconds (0..60)
+    sec_type seconds() const
+    {
+      return static_cast<sec_type>((ticks()/ticks_per_second()) % 60);
+    }
+    //! Returns total number of seconds truncating any fractional seconds
+    sec_type total_seconds() const
+    {
+      return static_cast<sec_type>(ticks() / ticks_per_second());
+    }
+    //! Returns total number of milliseconds truncating any fractional seconds
+    tick_type total_milliseconds() const
+    {
+      if (ticks_per_second() < 1000) {
+        return ticks() * (static_cast<tick_type>(1000) / ticks_per_second());
+      }
+      return ticks() / (ticks_per_second() / static_cast<tick_type>(1000)) ;
+    }
+    //! Returns total number of nanoseconds truncating any sub millisecond values
+    tick_type total_nanoseconds() const
+    {
+      if (ticks_per_second() < 1000000000) {
+        return ticks() * (static_cast<tick_type>(1000000000) / ticks_per_second());
+      }
+      return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000000)) ;
+    }
+    //! Returns total number of microseconds truncating any sub microsecond values
+    tick_type total_microseconds() const
+    {
+      if (ticks_per_second() < 1000000) {
+        return ticks() * (static_cast<tick_type>(1000000) / ticks_per_second());
+      }
+      return ticks() / (ticks_per_second() / static_cast<tick_type>(1000000)) ;
+    }
+    //! Returns count of fractional seconds at given resolution
+    fractional_seconds_type fractional_seconds() const
+    {
+      return (ticks() % ticks_per_second());
+    }
+    //! Returns number of possible digits in fractional seconds
+    static unsigned short num_fractional_digits()
+    {
+      return rep_type::num_fractional_digits();
+    }
+    duration_type invert_sign() const
+    {
+      return duration_type(ticks_ * (-1));
+    }
+    bool is_negative() const
+    {
+      return ticks_ < 0;
+    }
+    bool operator<(const time_duration& rhs)  const
+    {
+      return ticks_ <  rhs.ticks_;
+    }
+    bool operator==(const time_duration& rhs)  const
+    {
+      return ticks_ ==  rhs.ticks_;
+    }
+    //! unary- Allows for time_duration td = -td1
+    duration_type operator-()const
+    {
+      return duration_type(ticks_ * (-1));
+    }
+    duration_type operator-(const duration_type& d) const
+    {
+      return duration_type(ticks_ - d.ticks_);
+    }
+    duration_type operator+(const duration_type& d) const
+    {
+      return duration_type(ticks_ + d.ticks_);
+    }
+    duration_type operator/(int divisor) const
+    {
+      return duration_type(ticks_ / divisor);
+    }
+    duration_type operator-=(const duration_type& d)
+    {
+      ticks_ = ticks_ - d.ticks_;
+      return duration_type(ticks_);
+    }
+    duration_type operator+=(const duration_type& d)
+    {
+      ticks_ = ticks_ + d.ticks_;
+      return duration_type(ticks_);
+    }
+    //! Division operations on a duration with an integer.
+    duration_type operator/=(int divisor) 
+    {
+      ticks_ = ticks_ / divisor;
+      return duration_type(ticks_);
+    }
+    //! Multiplication operations an a duration with an integer
+    duration_type operator*(int rhs) const
+    {
+      return duration_type(ticks_ * rhs);
+    }
+    duration_type operator*=(int divisor)
+    {
+      ticks_ = ticks_ * divisor;
+      return duration_type(ticks_);
+    }
+    tick_type ticks() const
+    {
+      return traits_type::as_number(ticks_);
+    }
+
+    //! Is ticks_ a special value?
+    bool is_special()const
+    {
+      if(traits_type::is_adapted())
+      {
+        return ticks_.is_special();
+      }
+      else{
+        return false;
+      }
+    }
+    //! Is duration pos-infinity
+    bool is_pos_infinity()const
+    {
+      if(traits_type::is_adapted())
+      {
+        return ticks_.is_pos_infinity();
+      }
+      else{
+        return false;
+      }
+    }
+    //! Is duration neg-infinity
+    bool is_neg_infinity()const
+    {
+      if(traits_type::is_adapted())
+      {
+        return ticks_.is_neg_infinity();
+      }
+      else{
+        return false;
+      }
+    }
+    //! Is duration not-a-date-time
+    bool is_not_a_date_time()const
+    {
+      if(traits_type::is_adapted())
+      {
+        return ticks_.is_nan();
+      }
+      else{
+        return false;
+      }
+    }
+
+    //! Used for special_values output
+    impl_type get_rep()const
+    {
+      return ticks_;
+    }
+
+  protected:
+    explicit time_duration(impl_type in) : ticks_(in) {};
+    impl_type ticks_;
+  };
+
+
+
+  //! Template for instantiating derived adjusting durations
+  /* These templates are designed to work with multiples of
+   * 10 for frac_of_second and resoultion adjustment
+   */
+  template<class base_duration, boost::int64_t frac_of_second>
+  class subsecond_duration : public base_duration
+  {
+  public:
+    typedef typename base_duration::traits_type traits_type;
+    explicit subsecond_duration(boost::int64_t ss) :
+      base_duration(0,0,0,ss*traits_type::res_adjust()/frac_of_second)
+    {}
+  };
+
+
+
+} } //namespace date_time
+
+
+
+
+#endif
+

File diff suppressed because it is too large
+ 1327 - 0
ext/boost/date_time/time_facet.hpp


+ 122 - 0
ext/boost/date_time/time_formatting_streams.hpp

@@ -0,0 +1,122 @@
+#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
+#define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-12 14:37:53 -0500 (Wed, 12 Nov 2008) $
+ */
+
+#include <boost/date_time/compiler_config.hpp>
+
+#ifndef BOOST_DATE_TIME_NO_LOCALE
+
+#include <locale>
+#include <iomanip>
+#include <iostream>
+#include <boost/date_time/date_formatting_locales.hpp>
+#include <boost/date_time/time_resolution_traits.hpp>
+
+namespace boost {
+namespace date_time {
+
+
+  //! Put a time type into a stream using appropriate facets
+  template<class time_duration_type,
+           class charT = char>
+  class ostream_time_duration_formatter
+  {
+  public:
+    typedef std::basic_ostream<charT> ostream_type;
+    typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
+
+    //! Put time into an ostream 
+    static void duration_put(const time_duration_type& td, 
+                             ostream_type& os)
+    {
+      if(td.is_special()) {
+        os << td.get_rep(); 
+      }
+      else {
+        charT fill_char = '0';
+        if(td.is_negative()) {
+          os << '-';
+        }
+        os  << std::setw(2) << std::setfill(fill_char) 
+            << absolute_value(td.hours()) << ":";
+        os  << std::setw(2) << std::setfill(fill_char) 
+            << absolute_value(td.minutes()) << ":";
+        os  << std::setw(2) << std::setfill(fill_char) 
+            << absolute_value(td.seconds());
+        fractional_seconds_type frac_sec = 
+          absolute_value(td.fractional_seconds());
+        if (frac_sec != 0) {
+          os  << "." 
+              << std::setw(time_duration_type::num_fractional_digits())
+              << std::setfill(fill_char)
+              << frac_sec;
+        }
+      } // else
+    } // duration_put
+  }; //class ostream_time_duration_formatter
+
+  //! Put a time type into a stream using appropriate facets
+  template<class time_type,
+           class charT = char>
+  class ostream_time_formatter
+  {
+  public:
+    typedef std::basic_ostream<charT> ostream_type;
+    typedef typename time_type::date_type date_type;
+    typedef typename time_type::time_duration_type time_duration_type;
+    typedef ostream_time_duration_formatter<time_duration_type, charT> duration_formatter;
+
+    //! Put time into an ostream 
+    static void time_put(const time_type& t, 
+                         ostream_type& os)
+    {
+      date_type d = t.date();
+      os << d;
+      if(!d.is_infinity() && !d.is_not_a_date())
+      {
+        os << " "; //TODO: fix the separator here.
+        duration_formatter::duration_put(t.time_of_day(), os);
+      }
+      
+    } // time_to_ostream    
+  }; //class ostream_time_formatter
+
+
+  //! Put a time period into a stream using appropriate facets
+  template<class time_period_type,
+           class charT = char>
+  class ostream_time_period_formatter
+  {
+  public:
+    typedef std::basic_ostream<charT> ostream_type;
+    typedef typename time_period_type::point_type time_type;
+    typedef ostream_time_formatter<time_type, charT> time_formatter;
+
+    //! Put time into an ostream 
+    static void period_put(const time_period_type& tp, 
+                           ostream_type& os)
+    {
+      os << '['; //TODO: facet or manipulator for periods?
+      time_formatter::time_put(tp.begin(), os);
+      os << '/'; //TODO: facet or manipulator for periods?
+      time_formatter::time_put(tp.last(), os);
+      os << ']'; 
+
+    } // period_put
+
+  }; //class ostream_time_period_formatter
+
+
+  
+} } //namespace date_time
+
+#endif //BOOST_DATE_TIME_NO_LOCALE
+
+#endif

+ 52 - 0
ext/boost/date_time/time_iterator.hpp

@@ -0,0 +1,52 @@
+#ifndef DATE_TIME_TIME_ITERATOR_HPP___
+#define DATE_TIME_TIME_ITERATOR_HPP___
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+namespace boost {
+namespace date_time {
+  
+
+  //! Simple time iterator skeleton class
+  template<class time_type>
+  class time_itr {
+  public:
+    typedef typename time_type::time_duration_type time_duration_type;
+    time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {};
+    time_itr& operator++() 
+    {
+      current_ = current_ + offset_;
+      return *this;
+    }
+    time_itr& operator--() 
+    {
+      current_ = current_ - offset_;
+      return *this;
+    }
+    time_type operator*() {return current_;};
+    time_type* operator->() {return &current_;};
+    bool operator<  (const time_type& t) {return current_ < t;};
+    bool operator<= (const time_type& t) {return current_ <= t;};
+    bool operator!=  (const time_type& t) {return current_ != t;};
+    bool operator== (const time_type& t) {return current_ == t;};
+    bool operator>  (const time_type& t) {return current_ > t;};
+    bool operator>= (const time_type& t) {return current_ >= t;};
+    
+  private:
+    time_type current_;
+    time_duration_type offset_;
+  };
+  
+
+  
+} }//namespace date_time
+
+
+#endif

+ 321 - 0
ext/boost/date_time/time_parsing.hpp

@@ -0,0 +1,321 @@
+#ifndef _DATE_TIME_TIME_PARSING_HPP___
+#define _DATE_TIME_TIME_PARSING_HPP___
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+#include "boost/tokenizer.hpp"
+#include "boost/lexical_cast.hpp"
+#include "boost/date_time/date_parsing.hpp"
+#include "boost/cstdint.hpp"
+#include <iostream>
+
+namespace boost {
+namespace date_time {
+
+  //! computes exponential math like 2^8 => 256, only works with positive integers
+  //Not general purpose, but needed b/c std::pow is not available 
+  //everywehere. Hasn't been tested with negatives and zeros
+  template<class int_type>
+  inline
+  int_type power(int_type base, int_type exponent)
+  {
+    int_type result = 1;
+    for(int i = 0; i < exponent; ++i){
+      result *= base;
+    }
+    return result;
+  }
+  
+  //! Creates a time_duration object from a delimited string
+  /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+   * If the number of fractional digits provided is greater than the 
+   * precision of the time duration type then the extra digits are 
+   * truncated.
+   *
+   * A negative duration will be created if the first character in
+   * string is a '-', all other '-' will be treated as delimiters.
+   * Accepted delimiters are "-:,.". 
+   */
+  template<class time_duration, class char_type>
+  inline
+  time_duration
+  str_from_delimited_time_duration(const std::basic_string<char_type>& s)
+  {
+    unsigned short min=0, sec =0;
+    int hour =0; 
+    bool is_neg = (s.at(0) == '-');
+    boost::int64_t fs=0;
+    int pos = 0;
+      
+    typedef typename std::basic_string<char_type>::traits_type traits_type;
+    typedef boost::char_separator<char_type, traits_type> char_separator_type;
+    typedef boost::tokenizer<char_separator_type,
+                             typename std::basic_string<char_type>::const_iterator,
+                             std::basic_string<char_type> > tokenizer;
+    typedef typename boost::tokenizer<char_separator_type,
+                             typename std::basic_string<char_type>::const_iterator,
+                             typename std::basic_string<char_type> >::iterator tokenizer_iterator;
+   
+    char_type sep_chars[5] = {'-',':',',','.'};
+    char_separator_type sep(sep_chars);
+    tokenizer tok(s,sep);
+    for(tokenizer_iterator beg=tok.begin(); beg!=tok.end();++beg){
+      switch(pos) {
+      case 0: {
+        hour = boost::lexical_cast<int>(*beg);
+        break;
+      }
+      case 1: {
+        min = boost::lexical_cast<unsigned short>(*beg);
+        break;
+      }
+      case 2: {
+        sec = boost::lexical_cast<unsigned short>(*beg);
+        break;
+      };
+      case 3: {
+        int digits = static_cast<int>(beg->length());
+        //Works around a bug in MSVC 6 library that does not support
+        //operator>> thus meaning lexical_cast will fail to compile.
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+        // msvc wouldn't compile 'time_duration::num_fractional_digits()' 
+        // (required template argument list) as a workaround a temp 
+        // time_duration object was used
+        time_duration td(hour,min,sec,fs);
+        int precision = td.num_fractional_digits();
+        // _atoi64 is an MS specific function
+        if(digits >= precision) {
+          // drop excess digits
+          fs = _atoi64(beg->substr(0, precision).c_str());
+        }
+        else {
+          fs = _atoi64(beg->c_str());
+        }
+#else
+        int precision = time_duration::num_fractional_digits();
+        if(digits >= precision) {
+          // drop excess digits
+          fs = boost::lexical_cast<boost::int64_t>(beg->substr(0, precision));
+        }
+        else {
+          fs = boost::lexical_cast<boost::int64_t>(*beg);
+        }
+#endif
+        if(digits < precision){
+          // trailing zeros get dropped from the string, 
+          // "1:01:01.1" would yield .000001 instead of .100000
+          // the power() compensates for the missing decimal places
+          fs *= power(10, precision - digits); 
+        }
+        
+        break;
+      }
+      }//switch
+      pos++;
+    }
+    if(is_neg) {
+      return -time_duration(hour, min, sec, fs);
+    }
+    else {
+      return time_duration(hour, min, sec, fs);
+    }
+  }
+  
+  //! Creates a time_duration object from a delimited string
+  /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]".
+   * If the number of fractional digits provided is greater than the 
+   * precision of the time duration type then the extra digits are 
+   * truncated.
+   *
+   * A negative duration will be created if the first character in
+   * string is a '-', all other '-' will be treated as delimiters.
+   * Accepted delimiters are "-:,.". 
+   */
+  template<class time_duration>
+  inline
+  time_duration
+  parse_delimited_time_duration(const std::string& s)
+  {
+    return str_from_delimited_time_duration<time_duration,char>(s);
+  }
+
+  //! Utility function to split appart string
+  inline
+  bool 
+  split(const std::string& s,
+        char sep,
+        std::string& first,
+        std::string& second)
+  {
+    int sep_pos = static_cast<int>(s.find(sep));
+    first = s.substr(0,sep_pos);
+    second = s.substr(sep_pos+1);
+    return true;
+  }
+
+
+  template<class time_type>
+  inline
+  time_type
+  parse_delimited_time(const std::string& s, char sep)
+  {
+    typedef typename time_type::time_duration_type time_duration;
+    typedef typename time_type::date_type date_type;
+
+    //split date/time on a unique delimiter char such as ' ' or 'T'
+    std::string date_string, tod_string;
+    split(s, sep, date_string, tod_string);
+    //call parse_date with first string
+    date_type d = parse_date<date_type>(date_string);
+    //call parse_time_duration with remaining string
+    time_duration td = parse_delimited_time_duration<time_duration>(tod_string);
+    //construct a time
+    return time_type(d, td);
+
+  }
+
+  //! Parse time duration part of an iso time of form: [-]hhmmss[.fff...] (eg: 120259.123 is 12 hours, 2 min, 59 seconds, 123000 microseconds)
+  template<class time_duration>
+  inline
+  time_duration
+  parse_undelimited_time_duration(const std::string& s)
+  {
+    int precision = 0;
+    {
+      // msvc wouldn't compile 'time_duration::num_fractional_digits()' 
+      // (required template argument list) as a workaround, a temp 
+      // time_duration object was used
+      time_duration tmp(0,0,0,1);
+      precision = tmp.num_fractional_digits();
+    }
+    // 'precision+1' is so we grab all digits, plus the decimal
+    int offsets[] = {2,2,2, precision+1};
+    int pos = 0, sign = 0;
+    int hours = 0;
+    short min=0, sec=0;
+    boost::int64_t fs=0;
+    // increment one position if the string was "signed"
+    if(s.at(sign) == '-')
+    {
+      ++sign;
+    }
+    // stlport choked when passing s.substr() to tokenizer
+    // using a new string fixed the error
+    std::string remain = s.substr(sign);
+    /* We do not want the offset_separator to wrap the offsets, we 
+     * will never want to  process more than: 
+     * 2 char, 2 char, 2 char, frac_sec length.
+     * We *do* want the offset_separator to give us a partial for the
+     * last characters if there were not enough provided in the input string. */
+    bool wrap_off = false;
+    bool ret_part = true;
+    boost::offset_separator osf(offsets, offsets+4, wrap_off, ret_part); 
+    typedef boost::tokenizer<boost::offset_separator,
+                             std::basic_string<char>::const_iterator,
+                             std::basic_string<char> > tokenizer;
+    typedef boost::tokenizer<boost::offset_separator,
+                             std::basic_string<char>::const_iterator,
+                             std::basic_string<char> >::iterator tokenizer_iterator;
+    tokenizer tok(remain, osf);
+    for(tokenizer_iterator ti=tok.begin(); ti!=tok.end();++ti){
+      switch(pos) {
+        case 0: 
+          {
+            hours = boost::lexical_cast<int>(*ti); 
+            break;
+          }
+        case 1: 
+          {
+            min = boost::lexical_cast<short>(*ti); 
+            break;
+          }
+        case 2: 
+          {
+            sec = boost::lexical_cast<short>(*ti); 
+            break;
+          }
+        case 3:
+          {
+            std::string char_digits(ti->substr(1)); // digits w/no decimal
+            int digits = static_cast<int>(char_digits.length());
+            
+            //Works around a bug in MSVC 6 library that does not support
+            //operator>> thus meaning lexical_cast will fail to compile.
+#if (defined(BOOST_MSVC) && (_MSC_VER <= 1200))  // 1200 == VC++ 6.0
+            // _atoi64 is an MS specific function
+            if(digits >= precision) {
+              // drop excess digits
+              fs = _atoi64(char_digits.substr(0, precision).c_str());
+            }
+            else if(digits == 0) {
+              fs = 0; // just in case _atoi64 doesn't like an empty string
+            }
+            else {
+              fs = _atoi64(char_digits.c_str());
+            }
+#else
+            if(digits >= precision) {
+              // drop excess digits
+              fs = boost::lexical_cast<boost::int64_t>(char_digits.substr(0, precision));
+            }
+            else if(digits == 0) {
+              fs = 0; // lexical_cast doesn't like empty strings
+            }
+            else {
+              fs = boost::lexical_cast<boost::int64_t>(char_digits);
+            }
+#endif
+            if(digits < precision){
+              // trailing zeros get dropped from the string, 
+              // "1:01:01.1" would yield .000001 instead of .100000
+              // the power() compensates for the missing decimal places
+              fs *= power(10, precision - digits); 
+            }
+            
+            break;
+          }
+      };
+      pos++;
+    }
+    if(sign) {
+      return -time_duration(hours, min, sec, fs);
+    }
+    else {
+      return time_duration(hours, min, sec, fs);
+    }
+  }
+
+  //! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time
+  template<class time_type>
+  inline
+  time_type
+  parse_iso_time(const std::string& s, char sep)
+  {
+    typedef typename time_type::time_duration_type time_duration;
+    typedef typename time_type::date_type date_type;
+
+    //split date/time on a unique delimiter char such as ' ' or 'T'
+    std::string date_string, tod_string;
+    split(s, sep, date_string, tod_string);
+    //call parse_date with first string
+    date_type d = parse_undelimited_date<date_type>(date_string);
+    //call parse_time_duration with remaining string
+    time_duration td = parse_undelimited_time_duration<time_duration>(tod_string);
+    //construct a time
+    return time_type(d, td);
+  }
+
+
+
+} }//namespace date_time
+
+
+
+
+#endif

+ 144 - 0
ext/boost/date_time/time_resolution_traits.hpp

@@ -0,0 +1,144 @@
+#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
+#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2009-06-06 07:25:55 -0400 (Sat, 06 Jun 2009) $
+ */
+
+
+#include <boost/cstdint.hpp>
+#include <boost/date_time/time_defs.hpp>
+#include <boost/date_time/int_adapter.hpp>
+#include <boost/date_time/compiler_config.hpp>
+
+namespace boost {
+namespace date_time {
+
+  //! Simple function to calculate absolute value of a numeric type
+  template <typename T>
+  // JDG [7/6/02 made a template],
+  // moved here from time_duration.hpp 2003-Sept-4.
+  inline T absolute_value(T x)
+  {
+    return x < 0 ? -x : x;
+  }
+
+  //! traits struct for time_resolution_traits implementation type
+  struct time_resolution_traits_bi32_impl {
+    typedef boost::int32_t int_type;
+    typedef boost::int32_t impl_type;
+    static int_type as_number(impl_type i){ return i;}
+    //! Used to determine if implemented type is int_adapter or int
+    static bool is_adapted() { return false;}
+  };
+  //! traits struct for time_resolution_traits implementation type
+  struct time_resolution_traits_adapted32_impl {
+    typedef boost::int32_t int_type;
+    typedef boost::date_time::int_adapter<boost::int32_t> impl_type;
+    static int_type as_number(impl_type i){ return i.as_number();}
+    //! Used to determine if implemented type is int_adapter or int
+    static bool is_adapted() { return true;}
+  };
+  //! traits struct for time_resolution_traits implementation type
+  struct time_resolution_traits_bi64_impl {
+    typedef boost::int64_t int_type;
+    typedef boost::int64_t impl_type;
+    static int_type as_number(impl_type i){ return i;}
+    //! Used to determine if implemented type is int_adapter or int
+    static bool is_adapted() { return false;}
+  };
+  //! traits struct for time_resolution_traits implementation type
+  struct time_resolution_traits_adapted64_impl {
+    typedef boost::int64_t int_type;
+    typedef boost::date_time::int_adapter<boost::int64_t> impl_type;
+    static int_type as_number(impl_type i){ return i.as_number();}
+    //! Used to determine if implemented type is int_adapter or int
+    static bool is_adapted() { return true;}
+  };
+
+  template<typename frac_sec_type,
+           time_resolutions res,
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+           boost::int64_t resolution_adjust,
+#else
+           typename frac_sec_type::int_type resolution_adjust,
+#endif
+           unsigned short frac_digits,
+           typename v_type = boost::int32_t >
+  class time_resolution_traits {
+  public:
+    typedef typename frac_sec_type::int_type fractional_seconds_type;
+    typedef typename frac_sec_type::int_type tick_type;
+    typedef typename frac_sec_type::impl_type impl_type;
+    typedef v_type  day_type;
+    typedef v_type  hour_type;
+    typedef v_type  min_type;
+    typedef v_type  sec_type;
+
+    // bring in function from frac_sec_type traits structs
+    static fractional_seconds_type as_number(impl_type i)
+    {
+      return frac_sec_type::as_number(i);
+    }
+    static bool is_adapted()
+    {
+      return frac_sec_type::is_adapted();
+    }
+
+    //Would like this to be frac_sec_type, but some compilers complain
+#if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
+    BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust);
+#else
+    BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust);
+#endif
+
+    static time_resolutions resolution()
+    {
+      return res;
+    }
+    static unsigned short num_fractional_digits()
+    {
+      return frac_digits;
+    }
+    static fractional_seconds_type res_adjust()
+    {
+      return resolution_adjust;
+    }
+    //! Any negative argument results in a negative tick_count
+    static tick_type to_tick_count(hour_type hours,
+                                   min_type  minutes,
+                                   sec_type  seconds,
+                                   fractional_seconds_type  fs)
+    {
+      if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0)
+      {
+        hours = absolute_value(hours);
+        minutes = absolute_value(minutes);
+        seconds = absolute_value(seconds);
+        fs = absolute_value(fs);
+        return (((((fractional_seconds_type(hours)*3600)
+                   + (fractional_seconds_type(minutes)*60)
+                   + seconds)*res_adjust()) + fs) * -1);
+      }
+
+      return (((fractional_seconds_type(hours)*3600)
+               + (fractional_seconds_type(minutes)*60)
+               + seconds)*res_adjust()) + fs;
+    }
+
+  };
+
+  typedef time_resolution_traits<time_resolution_traits_adapted32_impl, milli, 1000, 3 > milli_res;
+  typedef time_resolution_traits<time_resolution_traits_adapted64_impl, micro, 1000000, 6 > micro_res;
+  typedef time_resolution_traits<time_resolution_traits_adapted64_impl, nano,  1000000000, 9 > nano_res;
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 254 - 0
ext/boost/date_time/time_system_counted.hpp

@@ -0,0 +1,254 @@
+#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP
+#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP
+
+/* Copyright (c) 2002,2003 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+
+#include "boost/date_time/time_defs.hpp"
+#include <string>
+
+
+namespace boost {
+namespace date_time {
+
+  //! Time representation that uses a single integer count
+  template<class config>
+  struct counted_time_rep
+  {
+    typedef typename config::int_type   int_type;
+    typedef typename config::date_type  date_type;
+    typedef typename config::impl_type  impl_type;
+    typedef typename date_type::duration_type date_duration_type;
+    typedef typename date_type::calendar_type calendar_type;
+    typedef typename date_type::ymd_type ymd_type;
+    typedef typename config::time_duration_type time_duration_type;
+    typedef typename config::resolution_traits   resolution_traits;
+    
+    counted_time_rep(const date_type& d, const time_duration_type& time_of_day) 
+      : time_count_(1)
+    {
+      if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) {
+        time_count_ = time_of_day.get_rep() + d.day_count();
+        //std::cout << time_count_ << std::endl;
+      }
+      else {    
+        time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks();
+      }
+    }
+    explicit counted_time_rep(int_type count) :
+      time_count_(count)
+    {}
+    explicit counted_time_rep(impl_type count) :
+      time_count_(count)
+    {}
+    date_type date() const
+    {
+      if(time_count_.is_special()) {
+        return date_type(time_count_.as_special());
+      }
+      else {
+        typename calendar_type::date_int_type dc = day_count();
+        //std::cout << "time_rep here:" << dc << std::endl;
+        ymd_type ymd = calendar_type::from_day_number(dc);
+        return date_type(ymd);
+      }
+    }
+    //int_type day_count() const
+    unsigned long day_count() const
+    {
+      /* resolution_traits::as_number returns a boost::int64_t & 
+       * frac_sec_per_day is also a boost::int64_t so, naturally, 
+       * the division operation returns a boost::int64_t. 
+       * The static_cast to an unsigned long is ok (results in no data loss) 
+       * because frac_sec_per_day is either the number of 
+       * microseconds per day, or the number of nanoseconds per day. 
+       * Worst case scenario: resolution_traits::as_number returns the 
+       * maximum value an int64_t can hold and frac_sec_per_day 
+       * is microseconds per day (lowest possible value). 
+       * The division operation will then return a value of 106751991 - 
+       * easily fitting in an unsigned long. 
+       */
+      return static_cast<unsigned long>(resolution_traits::as_number(time_count_) / frac_sec_per_day());
+    }
+    int_type time_count() const
+    {
+      return resolution_traits::as_number(time_count_);
+    }
+    int_type tod() const
+    {
+      return resolution_traits::as_number(time_count_) % frac_sec_per_day();
+    }
+    static int_type frac_sec_per_day()
+    {
+      int_type seconds_per_day = 60*60*24;
+      int_type fractional_sec_per_sec(resolution_traits::res_adjust());
+      return seconds_per_day*fractional_sec_per_sec;
+    }
+    bool is_pos_infinity()const
+    {
+      return impl_type::is_pos_inf(time_count_.as_number());
+    }
+    bool is_neg_infinity()const
+    {
+      return impl_type::is_neg_inf(time_count_.as_number());
+    }
+    bool is_not_a_date_time()const
+    {
+      return impl_type::is_not_a_number(time_count_.as_number());
+    }
+    bool is_special()const
+    {
+      return time_count_.is_special();
+    }
+    impl_type get_rep()const
+    {
+      return time_count_;
+    }
+  private:
+    impl_type time_count_;
+  };
+
+  //! An unadjusted time system implementation.
+  template<class time_rep>
+  class counted_time_system
+  {
+   public:
+    typedef time_rep time_rep_type;
+    typedef typename time_rep_type::impl_type impl_type;
+    typedef typename time_rep_type::time_duration_type time_duration_type;
+    typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type;
+    typedef typename time_rep_type::date_type date_type;
+    typedef typename time_rep_type::date_duration_type date_duration_type;
+
+
+    template<class T> static void unused_var(const T&) {}
+
+    static time_rep_type get_time_rep(const date_type& day,
+                                      const time_duration_type& tod,
+                                      date_time::dst_flags dst=not_dst)
+    {
+      unused_var(dst);
+      return time_rep_type(day, tod);
+    }
+
+    static time_rep_type get_time_rep(special_values sv)
+    {
+      switch (sv) {
+      case not_a_date_time:
+        return time_rep_type(date_type(not_a_date_time),
+                             time_duration_type(not_a_date_time));
+      case pos_infin:
+        return time_rep_type(date_type(pos_infin), 
+                             time_duration_type(pos_infin));
+      case neg_infin:
+        return time_rep_type(date_type(neg_infin), 
+                             time_duration_type(neg_infin));
+      case max_date_time: {
+        time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
+        return time_rep_type(date_type(max_date_time), td);
+      }
+      case min_date_time:
+        return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
+
+      default:
+        return time_rep_type(date_type(not_a_date_time),
+                             time_duration_type(not_a_date_time));
+        
+      }
+
+    }
+
+    static date_type get_date(const time_rep_type& val)
+    {
+      return val.date();
+    }
+    static time_duration_type get_time_of_day(const time_rep_type& val)
+    {
+      if(val.is_special()) {
+        return time_duration_type(val.get_rep().as_special());
+      }
+      else{
+        return time_duration_type(0,0,0,val.tod()); 
+      }
+    }
+    static std::string zone_name(const time_rep_type&)
+    {
+      return "";
+    }
+    static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
+    {
+      return (lhs.time_count() == rhs.time_count());
+    }
+    static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
+    {
+      return (lhs.time_count() < rhs.time_count());
+    }
+    static time_rep_type add_days(const time_rep_type& base,
+                                  const date_duration_type& dd)
+    {
+      if(base.is_special() || dd.is_special()) {
+        return(time_rep_type(base.get_rep() + dd.get_rep()));
+      }
+      else {
+        return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day()));
+      }
+    }
+    static time_rep_type subtract_days(const time_rep_type& base,
+                                       const date_duration_type& dd)
+    {
+      if(base.is_special() || dd.is_special()) {
+        return(time_rep_type(base.get_rep() - dd.get_rep()));
+      }
+      else{
+        return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day()));
+      }
+    }
+    static time_rep_type subtract_time_duration(const time_rep_type& base,
+                                                const time_duration_type& td)
+    {
+      if(base.is_special() || td.is_special()) {
+        return(time_rep_type(base.get_rep() - td.get_rep()));
+      }
+      else {
+        return time_rep_type(base.time_count() - td.ticks());
+      }
+    }
+    static time_rep_type add_time_duration(const time_rep_type& base,
+                                           time_duration_type td)
+    {
+      if(base.is_special() || td.is_special()) {
+        return(time_rep_type(base.get_rep() + td.get_rep()));
+      }
+      else {
+        return time_rep_type(base.time_count() + td.ticks());
+      }
+    }
+    static time_duration_type subtract_times(const time_rep_type& lhs,
+                                             const time_rep_type& rhs)
+    {
+      if(lhs.is_special() || rhs.is_special()) {
+        return(time_duration_type(
+          impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number())));
+      }
+      else {
+        fractional_seconds_type fs = lhs.time_count() - rhs.time_count();
+        return time_duration_type(0,0,0,fs); 
+      }
+    }
+    
+  };
+
+
+} } //namespace date_time
+
+
+
+#endif
+

+ 207 - 0
ext/boost/date_time/time_system_split.hpp

@@ -0,0 +1,207 @@
+#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP
+#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP
+
+/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc.
+ * Use, modification and distribution is subject to the 
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-11-13 15:10:23 -0500 (Thu, 13 Nov 2008) $
+ */
+
+
+#include <string>
+#include "boost/date_time/compiler_config.hpp"
+#include "boost/date_time/special_defs.hpp"
+
+namespace boost {
+namespace date_time {
+
+  //! An unadjusted time system implementation.
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))  
+  template<typename config, boost::int32_t ticks_per_second>
+#else
+  template<typename config>
+#endif
+  class split_timedate_system
+  {
+   public:
+    typedef typename config::time_rep_type time_rep_type;
+    typedef typename config::date_type     date_type;
+    typedef typename config::time_duration_type time_duration_type;
+    typedef typename config::date_duration_type date_duration_type;
+    typedef typename config::int_type int_type;
+    typedef typename config::resolution_traits   resolution_traits;
+
+    //86400 is number of seconds in a day...
+#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT))  
+    typedef date_time::wrapping_int<int_type, INT64_C(86400) * ticks_per_second > wrap_int_type;
+#else
+   private:
+     BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second);
+   public:
+# if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0X581) )
+    typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type;
+# else
+    typedef date_time::wrapping_int<int_type, ticks_per_day> wrap_int_type;
+#endif
+#endif
+
+    static time_rep_type get_time_rep(special_values sv)
+    {
+      switch (sv) {
+      case not_a_date_time:
+        return time_rep_type(date_type(not_a_date_time),
+                             time_duration_type(not_a_date_time));
+      case pos_infin:
+        return time_rep_type(date_type(pos_infin), 
+                             time_duration_type(pos_infin));
+      case neg_infin:
+        return time_rep_type(date_type(neg_infin), 
+                             time_duration_type(neg_infin));
+      case max_date_time: {
+        time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1);
+        return time_rep_type(date_type(max_date_time), td);
+      }
+      case min_date_time:
+        return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0));
+
+      default:
+        return time_rep_type(date_type(not_a_date_time),
+                             time_duration_type(not_a_date_time));
+        
+      }
+
+    }
+
+    static time_rep_type get_time_rep(const date_type& day,
+                                      const time_duration_type& tod,
+                                      date_time::dst_flags /* dst */ = not_dst)
+    {
+      if(day.is_special() || tod.is_special()) {
+        if(day.is_not_a_date() || tod.is_not_a_date_time()) {
+          return time_rep_type(date_type(not_a_date_time),
+                               time_duration_type(not_a_date_time));
+        }
+        else if(day.is_pos_infinity()) {
+          if(tod.is_neg_infinity()) {
+            return time_rep_type(date_type(not_a_date_time),
+                                 time_duration_type(not_a_date_time));
+          }
+          else {
+            return time_rep_type(day, time_duration_type(pos_infin));
+          }
+        }
+        else if(day.is_neg_infinity()) {
+          if(tod.is_pos_infinity()) {
+            return time_rep_type(date_type(not_a_date_time),
+                                 time_duration_type(not_a_date_time));
+          }
+          else {
+            return time_rep_type(day, time_duration_type(neg_infin));
+          }
+        }
+        else if(tod.is_pos_infinity()) {
+          if(day.is_neg_infinity()) {
+            return time_rep_type(date_type(not_a_date_time),
+                                 time_duration_type(not_a_date_time));
+          }
+          else {
+            return time_rep_type(date_type(pos_infin), tod);
+          }
+        }
+        else if(tod.is_neg_infinity()) {
+          if(day.is_pos_infinity()) {
+            return time_rep_type(date_type(not_a_date_time),
+                                 time_duration_type(not_a_date_time));
+          }
+          else {
+            return time_rep_type(date_type(neg_infin), tod);
+          }
+        }
+      }
+      return time_rep_type(day, tod);
+    }
+    static date_type get_date(const time_rep_type& val)
+    {
+      return date_type(val.day);
+    }
+    static time_duration_type get_time_of_day(const time_rep_type& val)
+    {
+      return time_duration_type(val.time_of_day);
+    }
+    static std::string zone_name(const time_rep_type&)
+    {
+      return std::string();
+    }
+    static bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs)
+    {
+      return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day));
+    }
+    static bool is_less(const time_rep_type& lhs, const time_rep_type& rhs)
+    {
+      if (lhs.day < rhs.day) return true;
+      if (lhs.day > rhs.day) return false;
+      return (lhs.time_of_day < rhs.time_of_day);
+    }
+    static time_rep_type add_days(const time_rep_type& base,
+                                  const date_duration_type& dd)
+    {
+      return time_rep_type(base.day+dd, base.time_of_day);
+    }
+    static time_rep_type subtract_days(const time_rep_type& base,
+                                       const date_duration_type& dd)
+    {
+      return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day);
+    }
+    static time_rep_type subtract_time_duration(const time_rep_type& base,
+                                                const time_duration_type& td)
+    {
+      if(base.day.is_special() || td.is_special())
+      {
+        return split_timedate_system::get_time_rep(base.day, -td);
+      }
+      if (td.is_negative()) {
+        time_duration_type td1 = td.invert_sign();
+        return add_time_duration(base,td1);
+      }
+
+      wrap_int_type  day_offset(base.time_of_day.ticks());
+      date_duration_type day_overflow(static_cast<typename date_duration_type::duration_rep_type>(day_offset.subtract(td.ticks())));
+
+      return time_rep_type(base.day-day_overflow,
+                           time_duration_type(0,0,0,day_offset.as_int()));
+    }
+    static time_rep_type add_time_duration(const time_rep_type& base,
+                                           time_duration_type td)
+    {
+      if(base.day.is_special() || td.is_special()) {
+        return split_timedate_system::get_time_rep(base.day, td);
+      }
+      if (td.is_negative()) {
+        time_duration_type td1 = td.invert_sign();
+        return subtract_time_duration(base,td1);
+      }
+
+      wrap_int_type day_offset(base.time_of_day.ticks());      
+      date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks())));
+
+      return time_rep_type(base.day+day_overflow,
+                           time_duration_type(0,0,0,day_offset.as_int()));
+    }
+    static time_duration_type subtract_times(const time_rep_type& lhs,
+                                             const time_rep_type& rhs)
+    {
+      date_duration_type dd = lhs.day - rhs.day;
+      time_duration_type td(dd.days()*24,0,0); //days * 24 hours
+      time_duration_type td2 = lhs.time_of_day - rhs.time_of_day;
+      return td+td2;
+      // return time_rep_type(base.day-dd, base.time_of_day);
+    }
+    
+  };
+
+} } //namespace date_time
+
+
+#endif

+ 99 - 0
ext/boost/date_time/time_zone_base.hpp

@@ -0,0 +1,99 @@
+#ifndef _DATE_TIME_TIME_ZONE_BASE__
+#define _DATE_TIME_TIME_ZONE_BASE__
+
+/* Copyright (c) 2003-2005 CrystalClear Software, Inc.
+ * Subject to the Boost Software License, Version 1.0. 
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ * Author: Jeff Garland, Bart Garst
+ * $Date: 2008-02-27 15:00:24 -0500 (Wed, 27 Feb 2008) $
+ */
+
+
+#include <string>
+#include <sstream>
+
+namespace boost {
+namespace date_time {
+
+
+
+  //! Interface class for dynamic time zones.
+  /*! This class represents the base interface for all timezone
+   *  representations.  Subclasses may provide different systems
+   *  for identifying a particular zone.  For example some may
+   *  provide a geographical based zone construction while others
+   *  may specify the offset from GMT.  Another possible implementation
+   *  would be to convert from POSIX timezone strings.  Regardless of
+   *  the construction technique, this is the interface that these
+   *  time zone types must provide.
+   * 
+   * Note that this class is intended to be used as a shared
+   * resource (hence the derivation from boost::counted_base.  
+   */
+  template<typename time_type, typename CharT>
+  class time_zone_base  {
+  public:
+    typedef CharT char_type;
+    typedef std::basic_string<CharT> string_type;
+    typedef std::basic_ostringstream<CharT> stringstream_type;
+    typedef typename time_type::date_type::year_type year_type;
+    typedef typename time_type::time_duration_type time_duration_type;
+
+    time_zone_base() {};
+    virtual ~time_zone_base() {};
+    //!String for the timezone when in daylight savings (eg: EDT)
+    virtual string_type dst_zone_abbrev() const=0;
+    //!String for the zone when not in daylight savings (eg: EST)
+    virtual string_type std_zone_abbrev() const=0;
+    //!String for the timezone when in daylight savings (eg: Eastern Daylight Time)
+    virtual string_type dst_zone_name() const=0;
+    //!String for the zone when not in daylight savings (eg: Eastern Standard Time)
+    virtual string_type std_zone_name() const=0;
+    //! True if zone uses daylight savings adjustments otherwise false
+    virtual bool has_dst() const=0;
+    //! Local time that DST starts -- undefined if has_dst is false
+    virtual time_type dst_local_start_time(year_type y) const=0;
+    //! Local time that DST ends -- undefined if has_dst is false
+    virtual time_type dst_local_end_time(year_type y) const=0;
+    //! Base offset from UTC for zone (eg: -07:30:00)
+    virtual time_duration_type base_utc_offset() const=0;
+    //! Adjustment forward or back made while DST is in effect
+    virtual time_duration_type dst_offset() const=0;
+    //! Returns a POSIX time_zone string for this object
+    virtual string_type to_posix_string() const =0;
+    
+  private:
+    
+  };
+
+
+  //! Structure which holds the time offsets associated with daylight savings time
+  /*!
+   *@param time_duration_type A type used to represent the offset
+   */
+  template<class time_duration_type>
+  class dst_adjustment_offsets
+  {
+  public:
+    dst_adjustment_offsets(const time_duration_type& dst_adjust,
+                           const time_duration_type& dst_start_offset,
+                           const time_duration_type& dst_end_offset) :
+      dst_adjust_(dst_adjust),
+      dst_start_offset_(dst_start_offset),
+      dst_end_offset_(dst_end_offset)
+    {}
+    
+    //! Amount DST adjusts the clock eg: plus one hour
+    time_duration_type dst_adjust_;
+    //! Time past midnight on start transition day that dst starts
+    time_duration_type dst_start_offset_;
+    //! Time past midnight on end transition day that dst ends
+    time_duration_type dst_end_offset_;
+  };
+
+
+} } //namespace date_time
+
+
+
+#endif

+ 0 - 0
ext/boost/date_time/time_zone_names.hpp


Some files were not shown because too many files changed in this diff