|
- //
- // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOSTER_POSIX_TIME_H
- #define BOOSTER_POSIX_TIME_H
-
- #include <booster/config.h>
- #include <ctime>
- #include <iosfwd>
- #include <math.h>
-
- namespace booster {
-
- ///
- /// \brief This class represents POSIX time.
- ///
- /// The time from Jan 1, 1970 in seconds in UTC (without leap seconds) similar to time_t.
- ///
- /// ptime internally holds 64 bit integer for seconds part and int for nanoseconds
- /// part which gives fine-grained time representation.
- ///
- class BOOSTER_API ptime {
- public:
- ///
- /// Create the POSIX time from seconds and nanoseconds.
- ///
- explicit
- ptime(long long seconds=0,int nano=0) :
- sec(seconds),
- nsec(nano)
- {
- normalize();
- }
-
- ///
- /// Get the seconds part of POSIX time
- ///
- long long get_seconds() const
- {
- return sec;
- }
- ///
- /// Get the nanoseconds fraction part of POSIX time
- ///
- int get_nanoseconds() const
- {
- return nsec;
- }
- ///
- /// Get the milliseconds fraction part of POSIX time (which is equal to get_nanoseconds() / 1,000,000)
- ///
- int get_milliseconds() const
- {
- return nsec / one_e6;
- }
- ///
- /// Get the microseconds fraction part of POSIX time (which is equal to get_nanoseconds() / 1,000)
- ///
- int get_microseconds() const
- {
- return nsec / one_e3;
- }
-
- ///
- /// Get amount of full seconds in \a p
- ///
- static long long seconds(ptime const &p)
- {
- return p.sec;
- }
- ///
- /// Convert a seconds \a v to ptime.
- ///
- static ptime seconds(long long v)
- {
- return ptime(v);
- }
-
- ///
- /// Get amount of full milliseconds in \a p.
- /// Not the same as p.get_milliseconds() as takes seconds as well
- ///
- static long long milliseconds(ptime const &p)
- {
- return p.get_seconds() * one_e3 + p.get_milliseconds();
- }
- ///
- /// Convert a milliseconds \a v to ptime.
- ///
- static ptime milliseconds(long long v)
- {
- return ptime(v/one_e3,v%one_e3 * one_e6);
- }
- ///
- /// Get amount of full microseconds in \a p.
- /// Not the same as p.get_microseconds() as takes seconds as well
- ///
- static long long microseconds(ptime const &p)
- {
- return p.get_seconds() * one_e6 + p.get_nanoseconds() / one_e3;
- }
- ///
- /// Convert a microseconds \a v to ptime.
- ///
- static ptime microseconds(long long v)
- {
- return ptime(v/one_e6,v%one_e6 * one_e3);
- }
- ///
- /// Get amount of nanoseconds in \a p
- /// Not the same as p.get_nanoseconds() as takes seconds as well
- ///
- static long long nanoseconds(ptime const &p)
- {
- return p.get_seconds() * one_e9 + p.get_nanoseconds();
- }
- ///
- /// Convert a nanoseconds \a v to ptime.
- ///
- static ptime nanoseconds(long long v)
- {
- return ptime(v/one_e9,v%one_e9);
- }
- ///
- /// Get amount of full minutes in \a p
- ///
- static ptime minutes(long long v)
- {
- return ptime(v*60);
- }
- ///
- /// Convert minutes \a v to ptime.
- ///
- static long long minutes(ptime const &p)
- {
- return p.get_seconds() / 60;
- }
- ///
- /// Get amount of full hours in \a p
- ///
- static long long hours(ptime const &p)
- {
- return p.get_seconds() / 3600;
- }
- ///
- /// Convert hours \a v to ptime.
- ///
- static ptime hours(long long v)
- {
- return ptime(v*3600);
- }
- ///
- /// Get amount of full days in \a p
- ///
- static long long days(ptime const &p)
- {
- return p.get_seconds() / (3600*24);
- }
- ///
- /// Convert days \a v to ptime.
- ///
- static ptime days(long long v)
- {
- return ptime(v*(3600*24));
- }
-
- ///
- /// Convert \a t to floating point number that represents POSIX time in seconds
- ///
- static double to_number(ptime const &t)
- {
- return double(t.sec) + double(t.nsec) * 1e-9;
- }
- ///
- /// Convert floating point number \a d that represents POSIX time in seconds to ptime
- ///
- static ptime from_number(double d)
- {
- double sec = floor(d);
- double subsec = d-sec;
- long long seconds = static_cast<long long>(sec);
- int nano = static_cast<int>(floor(subsec * 1e9));
- if(nano < 0) nano = 0;
- if(nano >= one_e9) nano = one_e9-1;
- return ptime(seconds,nano);
- }
-
- ///
- /// Add two POSIX time ranges (as numbers)
- ///
- ptime operator+(ptime const &other) const
- {
- return ptime(sec+other.sec,nsec+other.nsec);
- }
-
- ///
- /// Add two POSIX time ranges (as numbers)
- ///
- /// \ver{v1_2}
- ptime& operator+=(ptime const &other)
- {
- *this = ptime(sec+other.sec,nsec+other.nsec);
- return *this;
- }
-
- ///
- /// Subtract one time from other (as number)
- ///
- ptime operator-(ptime const &other) const
- {
- return ptime(sec-other.sec,nsec-other.nsec);
- }
-
- ///
- /// Subtract one time from other (as number)
- ///
- /// \ver{v1_2}
- ptime& operator-=(ptime const &other)
- {
- *this = ptime(sec-other.sec,nsec-other.nsec);
- return *this;
- }
-
- bool operator==(ptime const &other) const
- {
- return sec==other.sec && nsec == other.nsec;
- }
- bool operator!=(ptime const &other) const
- {
- return !((*this)==other);
- }
- bool operator<(ptime const &other) const
- {
- if(sec < other.sec)
- return true;
- if(sec > other.sec)
- return false;
- return nsec < other.nsec;
- }
- bool operator>(ptime const &other) const
- {
- return other < *this;
- }
- bool operator <= (ptime const &other) const
- {
- return !(*this > other);
- }
- bool operator >=(ptime const &other) const
- {
- return !(*this < other);
- }
-
- ///
- /// Convert local time to POSIX time similar to mktime
- ///
- static ptime local_time(std::tm const &v);
- ///
- /// Convert universal time to POSIX time similar to timegm or mktime in GMT timezone
- ///
- static ptime universal_time(std::tm const &v);
- ///
- /// Convert POSIX time \a v to a local time similar to localtime_r
- ///
- static std::tm local_time(ptime const &v);
- ///
- /// Convert POSIX time \a v to a GMT time similar to gmtime_r
- ///
- static std::tm universal_time(ptime const &v);
-
- ///
- /// Get current time
- ///
- static ptime now();
-
- ///
- /// Same as ptime() -- 0 in terms of POSIX time
- ///
- static ptime const zero;
-
- ///
- /// Sleep at least \a v milliseconds
- ///
- static void millisleep(long long v)
- {
- sleep(milliseconds(v));
- }
- ///
- /// Sleep at least \a v nanoseconds
- ///
- static void nanosleep(long long v)
- {
- sleep(nanoseconds(v));
- }
- ///
- /// Sleep at least \a v amount of time.
- ///
- static void sleep(ptime const &v );
-
- private:
- void normalize()
- {
- if(nsec > one_e9) {
- sec += nsec / one_e9;
- nsec = nsec % one_e9;
- }
- else if(nsec < 0) {
- while(nsec < 0) {
- nsec += one_e9;
- sec -= 1;
- }
- }
- }
- static const int one_e3 = 1000;
- static const int one_e6 = 1000000;
- static const int one_e9 = 1000000000;
- long long sec;
- int nsec;
- };
-
- ///
- /// Write ptime to stream. It is written as double, so it would give expected result when
- /// working with booster::locale::as::date_time formatter
- ///
- BOOSTER_API std::ostream &operator<<(std::ostream &,ptime const &);
- ///
- /// Read ptime from stream. It is read as double, so it would give expected result when
- /// working with booster::locale::as::date_time formatter
- ///
- BOOSTER_API std::istream &operator>>(std::istream &,ptime &);
-
- }
-
- #endif
|