RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/types/date.h
00001 /* date.h                                                          -*- C++ -*-
00002    Jeremy Barnes, 18 July 2010
00003    Copyright (c) 2010 Datacratic.  All rights reserved.
00004 
00005    Basic class that holds and manipulates a date.  Not designed for ultimate
00006    accuracy, but shouldn't be too bad.
00007 */
00008 
00009 #pragma once
00010 
00011 #include <string>
00012 #include <iostream>
00013 #include <boost/date_time/gregorian/gregorian.hpp>
00014 #include <boost/date_time/posix_time/posix_time.hpp>
00015 #include "jml/db/persistent_fwd.h"
00016 #include <chrono>
00017 
00018 
00019 struct ACE_Time_Value;
00020 
00021 namespace Json {
00022 
00023 struct Value;
00024 
00025 } // namespace Json
00026 
00027 namespace ML {
00028 struct Parse_Context;
00029 } // namespace ML
00030 
00031 namespace Datacratic {
00032 
00033 using boost::posix_time::ptime;
00034 struct Opaque;
00035 
00036 namespace JS {
00037 struct JSValue;
00038 } // namespace JS
00039 
00040 /*****************************************************************************/
00041 /* DATE                                                                      */
00042 /*****************************************************************************/
00043 
00044 struct Date {
00045 
00046     Date()
00047         : secondsSinceEpoch_(0.0)
00048     {
00049     }
00050 
00051     explicit Date(const ptime & date);
00052     explicit Date(const Opaque & value);
00053     Date(int year, int month, int day,
00054          int hour = 0, int minute = 0, int second = 0,
00055          double fraction = 0.0);
00056     explicit Date(JS::JSValue & value);
00057     explicit Date(const Json::Value & value);
00058     explicit Date(const ACE_Time_Value & time);
00059 
00060     static Date fromSecondsSinceEpoch(double numSeconds)
00061     {
00062         Date result;
00063         result.secondsSinceEpoch_ = numSeconds;
00064         return result;
00065     }
00066 
00067     static Date parseSecondsSinceEpoch(const std::string & date);
00068 
00069     static Date parseDefaultUtc(const std::string & date);
00070     static Date parseIso8601(const std::string & date);
00071 
00072     static Date notADate();
00073     static Date positiveInfinity();
00074     static Date negativeInfinity();
00075     static Date now();
00076     static Date nowOld();
00077 
00078     bool isADate() const;
00079 
00080     double secondsSinceEpoch() const
00081     {
00082         return secondsSinceEpoch_;
00083     }
00084 
00085     std::string print(unsigned seconds_digits = 0) const;
00086     std::string print(const std::string & format) const;
00087     std::string printRfc2616() const;
00088     std::string printClassic() const;
00089 
00090     bool operator == (const Date & other) const
00091     {
00092         return secondsSinceEpoch_ == other.secondsSinceEpoch_;
00093     }
00094 
00095     bool operator != (const Date & other) const
00096     {
00097         return ! operator == (other);
00098     }
00099 
00100     bool operator <  (const Date & other) const
00101     {
00102         return secondsSinceEpoch_ < other.secondsSinceEpoch_;
00103     }
00104 
00105     bool operator <= (const Date & other) const
00106     {
00107         return secondsSinceEpoch_ <= other.secondsSinceEpoch_;
00108     }
00109 
00110     bool operator >  (const Date & other) const
00111     {
00112         return secondsSinceEpoch_ > other.secondsSinceEpoch_;
00113     }
00114 
00115     bool operator >= (const Date & other) const
00116     {
00117         return secondsSinceEpoch_ >= other.secondsSinceEpoch_;
00118     }
00119 
00120     double operator - (const Date & other) const
00121     {
00122         return secondsSinceEpoch_ - other.secondsSinceEpoch_;
00123     }
00124     
00125     Date & setMin(Date other)
00126     {
00127         secondsSinceEpoch_ = std::min(secondsSinceEpoch_,
00128                                       other.secondsSinceEpoch_);
00129         return *this;
00130     }
00131 
00132     Date & setMax(Date other)
00133     {
00134         secondsSinceEpoch_ = std::max(secondsSinceEpoch_,
00135                                       other.secondsSinceEpoch_);
00136         return *this;
00137     }
00138 
00142     Date quantized(double fraction) const;
00143     Date & quantize(double fraction);
00144 
00145     void addSeconds(double interval)
00146     {
00147         secondsSinceEpoch_ += interval;
00148     }
00149 
00150     void addMinutes(double interval)
00151     {
00152         secondsSinceEpoch_ += interval * 60.0;
00153     }
00154 
00155     void addHours(double interval)
00156     {
00157         secondsSinceEpoch_ += interval * 3600.0;
00158     }
00159 
00160     void addDays(double interval)
00161     {
00162         secondsSinceEpoch_ += interval * 3600.0 * 24.0;
00163     }
00164 
00165     Date plusSeconds(double interval) const
00166     {
00167         Date result = *this;
00168         result.addSeconds(interval);
00169         return result;
00170     }
00171 
00172     Date plusMinutes(double interval) const
00173     {
00174         Date result = *this;
00175         result.addSeconds(interval * 60.0);
00176         return result;
00177     }
00178 
00179     Date plusHours(double interval) const
00180     {
00181         Date result = *this;
00182         result.addSeconds(interval * 3600.0);
00183         return result;
00184     }
00185 
00186     Date plusDays(double interval) const
00187     {
00188         Date result = *this;
00189         result.addSeconds(interval * 3600.0 * 24.0);
00190         return result;
00191     }
00192 
00193     double secondsUntil(const Date & other) const
00194     {
00195         return other.secondsSinceEpoch_ - secondsSinceEpoch_;
00196     }
00197 
00198     double minutesUntil(const Date & other) const
00199     {
00200         static const double factor = 1.0 / 60.0;
00201         return secondsUntil(other) * factor;
00202     }
00203 
00204     double hoursUntil(const Date & other) const
00205     {
00206         static const double factor = 1.0 / 3600.0;
00207         return secondsUntil(other) * factor;
00208     }
00209 
00210     double daysUntil(const Date & other) const
00211     {
00212         static const double factor = 1.0 / 24.0 / 3600.0;
00213         return secondsUntil(other) * factor;
00214     }
00215 
00216     double secondsSince(const Date & other) const
00217     {
00218         return -secondsUntil(other);
00219     }
00220 
00221     double minutesSince(const Date & other) const
00222     {
00223         return -minutesUntil(other);
00224     }
00225 
00226     double hoursSince(const Date & other) const
00227     {
00228         return -hoursUntil(other);
00229     }
00230 
00231     double daysSince(const Date & other) const
00232     {
00233         return -daysUntil(other);
00234     }
00235 
00236     bool sameDay(const Date & other) const
00237     {
00238         return dayStart() == other.dayStart();
00239     }
00240 
00241     Date dayStart() const
00242     {
00243         static const double secPerDay = 24.0 * 3600.0;
00244         double day = secondsSinceEpoch_ / secPerDay;
00245         double startOfDay = floor(day);
00246         return fromSecondsSinceEpoch(startOfDay * secPerDay);
00247     }
00248 
00249     int hour() const;
00250     int minute() const;
00251     int second() const;
00252     int weekday() const;
00253     int dayOfMonth() const;
00254     int monthOfYear() const;
00255     int year() const;
00256 
00257     int hourOfWeek() const;
00258 
00259     double fractionalSeconds() const
00260     {
00261         double whole_seconds;
00262         return modf(secondsSinceEpoch_, &whole_seconds);
00263     }
00264 
00265     long long wholeSecondsSinceEpoch() const
00266     {
00267         double whole_seconds;
00268         modf(secondsSinceEpoch_, &whole_seconds);
00269         return whole_seconds;
00270     }
00271 
00272     std::string printMonth() const;
00273     std::string printWeekday() const;
00274     std::string printYearAndMonth() const;
00275 
00276     static const boost::posix_time::ptime epoch;
00277 
00278     static Date expect_date(ML::Parse_Context & context,
00279                             const std::string & format);
00280     static bool match_date(ML::Parse_Context & context, Date & date,
00281                            const std::string & format);
00282     
00283     static double expect_time(ML::Parse_Context & context,
00284                               const std::string & format);
00285     static bool match_time(ML::Parse_Context & context,
00286                            double & time,
00287                            const std::string & format);
00288 
00289     static Date expect_date_time(ML::Parse_Context & context,
00290                                  const std::string & date_format,
00291                                  const std::string & time_format);
00292 
00293     static bool match_date_time(ML::Parse_Context & context,
00294                                 Date & result,
00295                                 const std::string & date_format,
00296                                 const std::string & time_format);
00297 
00298     static Date parse_date_time(const std::string & date_time,
00299                                 const std::string & date_format,
00300                                 const std::string & time_format);
00301 
00302     size_t hash() const
00303     {
00304         return std::hash<double>() (secondsSinceEpoch_);
00305     }
00306 
00308     ACE_Time_Value toAce() const;
00309 
00311     boost::posix_time::ptime toBoost() const
00312     {
00313         return boost::posix_time::from_time_t(toTimeT())
00314             + boost::posix_time::microseconds
00315             (1000000 * fractionalSeconds());
00316     }
00317     
00321     std::chrono::time_point<std::chrono::system_clock>
00322     toStd() const
00323     {
00324         return std::chrono::system_clock::from_time_t(toTimeT())
00325             + std::chrono::microseconds(static_cast<long>(1000000 * fractionalSeconds()));
00326     }
00327 
00331     time_t toTimeT() const
00332     {
00333         return secondsSinceEpoch();
00334     }
00335 
00337     static Date fromTimeT(const time_t & time)
00338     {
00339         return Date::fromSecondsSinceEpoch(time);
00340     }
00341 
00343     tm toTm() const;
00344 
00346     static Date fromTm(const tm & t);
00347 
00349     void addFromString(std::string);
00350 
00351 private:
00352     double secondsSinceEpoch_;
00353     Date(double);
00354 };
00355 
00356 std::ostream & operator << (std::ostream & stream, const Date & date);
00357 std::istream & operator >> (std::istream & stream, Date & date);
00358 
00359 ML::DB::Store_Writer & operator << (ML::DB::Store_Writer & store, Date date);
00360 ML::DB::Store_Reader & operator >> (ML::DB::Store_Reader & store, Date & date);
00361 
00362 namespace JS {
00363 
00364 void to_js(JSValue & jsval, Date value);
00365 Date from_js(const JSValue & val, Date *);
00366 
00367 } // namespace JS
00368 
00369 } // namespace Datacratic
00370 
00371 namespace std {
00372 
00373 template<>
00374 struct hash<Datacratic::Date> {
00375     size_t operator () (const Datacratic::Date & date) const
00376     {
00377         return date.hash();
00378     }
00379 };
00380 
00381 } // namespace std
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator