1 /* 2 * Copyright (C) 2016 Open Source Robotics Foundation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 #ifndef IGNITION_COMMON_TIME_HH_ 18 #define IGNITION_COMMON_TIME_HH_ 19 20 #include <string> 21 #include <iostream> 22 23 #include <ignition/common/Export.hh> 24 #include <ignition/common/Util.hh> 25 26 namespace ignition 27 { 28 namespace common 29 { 30 /// \class Time Time.hh common/common.hh 31 /// \brief A Time class, can be used to hold wall- or sim-time. 32 /// stored as sec and nano-sec. 33 class IGNITION_COMMON_VISIBLE Time 34 { 35 /// \brief A static zero time variable set to common::Time(0, 0). 36 public: static const Time Zero; 37 38 /// \enum Format options 39 /// \brief Options for formatting time as a string. 40 public: enum class FormatOption 41 { 42 /// \brief Days 43 DAYS = 0, 44 /// \brief Hours 45 HOURS = 1, 46 /// \brief Minutes 47 MINUTES = 2, 48 /// \brief Seconds 49 SECONDS = 3, 50 /// \brief Milliseconds 51 MILLISECONDS = 4 52 }; 53 54 /// \brief Constructors 55 public: Time(); 56 57 /// \brief Copy constructor 58 /// \param[in] time Time to copy 59 public: Time(const Time &_time); 60 61 /// \brief Constructor 62 /// \param[in] _tv Time to initialize to 63 public: explicit Time(const struct timespec &_tv); 64 65 /// \brief Constructor 66 /// \param[in] _sec Seconds 67 /// \param[in] _nsec Nanoseconds 68 public: Time(int32_t _sec, int32_t _nsec); 69 70 /// \brief Constuctor 71 /// \param[in] _time Time in double format sec.nsec 72 public: explicit Time(double _time); 73 74 /// \brief Destructor 75 public: virtual ~Time(); 76 77 /// \brief Get the wall time 78 /// \return the current time 79 public: static const Time &SystemTime(); 80 81 /// \brief Set to sec and nsec 82 /// \param[in] _sec Seconds 83 /// \param[in] _nsec Nanoseconds 84 public: void Set(int32_t _sec, int32_t _nsec); 85 86 /// \brief Set to seconds 87 /// \param[in] _seconds Number of seconds 88 public: void Set(double _seconds); 89 90 /// \brief Get the time as a double 91 /// \return Time as a double in seconds 92 public: double Double() const; 93 94 /// \brief Get the time as a float 95 /// \return Time as a float in seconds 96 public: float Float() const; 97 98 /// \brief Sleep for the specified time 99 /// \param[in] _time Sleep time 100 /// \return Time actually slept 101 public: static Time Sleep(const common::Time &_time); 102 103 /// \brief Get the time as a string formatted as "DD hh:mm:ss.mmm", with 104 /// the option to choose the start/end. 105 /// \param[in] _start Start point. 106 /// \param[in] _end End point. 107 /// \return String representing time. 108 public: std::string FormattedString( 109 FormatOption _start = FormatOption::DAYS, 110 FormatOption _end = FormatOption::MILLISECONDS) const; 111 112 /// \brief Assignment operator 113 /// \param[in] _time the new time 114 /// \return a reference to this instance 115 public: Time &operator=(const Time &_time); 116 117 /// \brief Addition operators 118 /// \param[in] _time The time to add 119 /// \return a Time instance 120 public: Time operator+(const Time &_time) const; 121 122 /// \brief Addition assignemtn operator 123 /// \param[in] _time The time to add 124 /// \return a Time instance 125 public: const Time &operator +=(const Time &_time); 126 127 /// \brief Subtraction operator 128 /// \param[in] _tv The time to subtract 129 /// \return a Time instance 130 public: Time operator -(const struct timespec &_tv) const; 131 132 /// \brief Subtraction assignment operator 133 /// \param[in] _tv The time to subtract 134 /// \return a Time instance 135 public: const Time &operator -=(const struct timespec &_tv); 136 137 /// \brief Subtraction operator 138 /// \param[in] _time The time to subtract 139 /// \return a Time instance 140 public: Time operator -(const Time &_time) const; 141 142 /// \brief Subtraction assignment operator 143 /// \param[in] _time The time to subtract 144 /// \return a reference to this instance 145 public: const Time &operator -=(const Time &_time); 146 147 /// \brief Multiplication operator 148 /// \param[in] _tv the scaling duration 149 /// \return Time instance 150 public: Time operator *(const struct timespec &_tv) const; 151 152 /// \brief Multiplication assignment operator 153 /// \param[in] _tv the scaling duration 154 /// \return a reference to this instance 155 public: const Time &operator *=(const struct timespec &_tv); 156 157 /// \brief Multiplication operators 158 /// \param[in] _time the scaling factor 159 /// \return a scaled Time instance 160 public: Time operator *(const Time &_time) const; 161 162 /// \brief Multiplication operators 163 /// \param[in] _time scale factor 164 /// \return a scaled Time instance 165 public: const Time &operator *=(const Time &_time); 166 167 /// \brief Division assignment operator 168 /// \param[in] _tv a divisor 169 /// \return a Time instance 170 public: const Time &operator /=(const struct timespec &_tv); 171 172 /// \brief Division operator 173 /// \param[in] _time the divisor 174 /// \return a Time instance 175 public: Time operator /(const Time &_time) const; 176 177 /// \brief Division assignment operator 178 /// \param[in] time the divisor 179 /// \return a Time instance 180 public: const Time &operator /=(const Time &time); 181 182 /// \brief Equal to operator 183 /// \param[in] _time the time to compare to 184 /// \return true if values are the same, false otherwise 185 public: bool operator==(const Time &_time) const; 186 187 /// \brief Equal to operator 188 /// \param[in] _time the time to compare to 189 /// \return true if values are the same, false otherwise 190 public: bool operator==(double _time) const; 191 192 /// \brief Equal to operator 193 /// \param[in] _time the time to compare to 194 /// \return true if values are the same, false otherwise 195 public: bool operator!=(const Time &_time) const; 196 197 /// \brief Equal to operator 198 /// \param[in] _time the time to compare to 199 /// \return true if values are the same, false otherwise 200 public: bool operator!=(double _time) const; 201 202 /// \brief Less than operator 203 /// \param[in] _time the time to compare with 204 /// \return true if time is shorter than this, false otherwise 205 public: bool operator<(const Time &_time) const; 206 207 /// \brief Less than operator 208 /// \param[in] _time the time to compare with 209 /// \return true if time is shorter than this, false otherwise 210 public: bool operator<(double _time) const; 211 212 /// \brief Less than or equal to operator 213 /// \param[in] _time the time to compare with 214 /// \return true if time is shorter than or equal to this, false otherwise 215 public: bool operator<=(const Time &_time) const; 216 217 /// \brief Less than or equal to operator 218 /// \param[in] _time the time to compare with 219 /// \return true if time is shorter than or equal to this, false otherwise 220 public: bool operator<=(double _time) const; 221 222 /// \brief Greater than operator 223 /// \param[in] _tv the time to compare with 224 /// \return true if time is greater than this, false otherwise 225 public: bool operator>(const struct timespec &_tv) const; 226 227 /// \brief Greater than operator 228 /// \param[in] _time the time to compare with 229 /// \return true if time is greater than this, false otherwise 230 public: bool operator>(const Time &_time) const; 231 232 /// \brief Greater than operator 233 /// \param[in] _time the time to compare with 234 /// \return true if time is greater than this, false otherwise 235 public: bool operator>(double _time) const; 236 237 /// \brief Greater than or equal operator 238 /// \param[in] _time the time to compare with 239 /// \return true if time is greater than or equal to this, false otherwise 240 public: bool operator>=(const Time &_time) const; 241 242 /// \brief Greater than or equal operator 243 /// \param[in] _tv the time to compare with 244 /// \return true if tv is greater than or equal to this, false otherwise 245 public: bool operator>=(const struct timespec &_tv) const; 246 247 /// \brief Greater than or equal operator 248 /// \param[in] _time the time to compare with 249 /// \return true if time is greater than or equal to this, false otherwise 250 public: bool operator>=(double _time) const; 251 252 /// \brief Stream insertion operator 253 /// \param[in] _out the output stream 254 /// \param[in] _time time to write to the stream 255 /// \return the output stream operator <<(std::ostream & _out,const ignition::common::Time & _time)256 public: friend std::ostream &operator<<(std::ostream &_out, 257 const ignition::common::Time &_time) 258 { 259 _out << _time.sec << " " << _time.nsec; 260 return _out; 261 } 262 263 /// \brief Stream extraction operator 264 /// \param[in] _in the input stream 265 /// \param[in] _time time to read from to the stream 266 /// \return the input stream operator >>(std::istream & _in,ignition::common::Time & _time)267 public: friend std::istream &operator>>(std::istream &_in, 268 ignition::common::Time &_time) 269 { 270 // Skip white spaces 271 _in.setf(std::ios_base::skipws); 272 _in >> _time.sec >> _time.nsec; 273 return _in; 274 } 275 276 /// \brief Seconds 277 public: int32_t sec; 278 279 /// \brief Nanoseconds 280 public: int32_t nsec; 281 282 /// \brief a singleton value of the last GetWallTime() value 283 private: static Time wallTime; 284 285 /// \brief Correct the time so that small additions/substractions 286 /// preserve the internal seconds and nanoseconds separation Correct()287 private: inline void Correct() 288 { 289 // In the case sec and nsec have different signs, normalize 290 if (this->sec > 0 && this->nsec < 0) 291 { 292 int32_t n = abs(this->nsec / this->nsInSec) + 1; 293 this->sec -= n; 294 this->nsec += n * this->nsInSec; 295 } 296 if (this->sec < 0 && this->nsec > 0) 297 { 298 int32_t n = abs(this->nsec / this->nsInSec) + 1; 299 this->sec += n; 300 this->nsec -= n * this->nsInSec; 301 } 302 303 // Make any corrections 304 this->sec += this->nsec / this->nsInSec; 305 this->nsec = this->nsec % this->nsInSec; 306 } 307 308 /// \brief Constant multiplier to convert from nanoseconds to seconds. 309 private: static const int32_t nsInSec; 310 311 /// \brief Constant multiplier to convert from nanoseconds to 312 /// milliseconds. 313 private: static const int32_t nsInMs; 314 315 private: static struct timespec clockResolution; 316 }; 317 } 318 } 319 #endif 320