Time.h (4467B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This code is made available to you under your choice of the following sets 4 * of licensing terms: 5 */ 6 /* This Source Code Form is subject to the terms of the Mozilla Public 7 * License, v. 2.0. If a copy of the MPL was not distributed with this 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 */ 10 /* Copyright 2014 Mozilla Contributors 11 * 12 * Licensed under the Apache License, Version 2.0 (the "License"); 13 * you may not use this file except in compliance with the License. 14 * You may obtain a copy of the License at 15 * 16 * http://www.apache.org/licenses/LICENSE-2.0 17 * 18 * Unless required by applicable law or agreed to in writing, software 19 * distributed under the License is distributed on an "AS IS" BASIS, 20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21 * See the License for the specific language governing permissions and 22 * limitations under the License. 23 */ 24 25 #ifndef mozilla_pkix_Time_h 26 #define mozilla_pkix_Time_h 27 28 #include <stdint.h> 29 #include <ctime> 30 #include <limits> 31 32 #include "mozpkix/Result.h" 33 34 namespace mozilla { 35 namespace pkix { 36 37 // Time with a range from the first second of year 0 (AD) through at least the 38 // last second of year 9999, which is the range of legal times in X.509 and 39 // OCSP. This type has second-level precision. The time zone is always UTC. 40 // 41 // Pass by value, not by reference. 42 class Time final { 43 public: 44 // Construct an uninitialized instance. 45 // 46 // This will fail to compile because there is no default constructor: 47 // Time x; 48 // 49 // This will succeed, leaving the time uninitialized: 50 // Time x(Time::uninitialized); 51 enum Uninitialized { uninitialized }; 52 explicit Time(Uninitialized) {} 53 54 bool operator==(const Time& other) const { 55 return elapsedSecondsAD == other.elapsedSecondsAD; 56 } 57 bool operator>(const Time& other) const { 58 return elapsedSecondsAD > other.elapsedSecondsAD; 59 } 60 bool operator>=(const Time& other) const { 61 return elapsedSecondsAD >= other.elapsedSecondsAD; 62 } 63 bool operator<(const Time& other) const { 64 return elapsedSecondsAD < other.elapsedSecondsAD; 65 } 66 bool operator<=(const Time& other) const { 67 return elapsedSecondsAD <= other.elapsedSecondsAD; 68 } 69 70 Result AddSeconds(uint64_t seconds) { 71 if (std::numeric_limits<uint64_t>::max() - elapsedSecondsAD < seconds) { 72 return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow 73 } 74 elapsedSecondsAD += seconds; 75 return Success; 76 } 77 78 Result SubtractSeconds(uint64_t seconds) { 79 if (seconds > elapsedSecondsAD) { 80 return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow 81 } 82 elapsedSecondsAD -= seconds; 83 return Success; 84 } 85 86 static const uint64_t ONE_DAY_IN_SECONDS = 87 UINT64_C(24) * UINT64_C(60) * UINT64_C(60); 88 89 private: 90 // This constructor is hidden to prevent accidents like this: 91 // 92 // Time foo(time_t t) 93 // { 94 // // WRONG! 1970-01-01-00:00:00 == time_t(0), but not Time(0)! 95 // return Time(t); 96 // } 97 explicit Time(uint64_t aElapsedSecondsAD) 98 : elapsedSecondsAD(aElapsedSecondsAD) {} 99 friend Time TimeFromElapsedSecondsAD(uint64_t); 100 friend class Duration; 101 102 uint64_t elapsedSecondsAD; 103 }; 104 105 inline Time TimeFromElapsedSecondsAD(uint64_t aElapsedSecondsAD) { 106 return Time(aElapsedSecondsAD); 107 } 108 109 Time Now(); 110 111 // Note the epoch is the unix epoch (ie 00:00:00 UTC, 1 January 1970) 112 Time TimeFromEpochInSeconds(uint64_t secondsSinceEpoch); 113 114 // Note the epoch is the unix epoch (ie 00:00:00 UTC, 1 January 1970) 115 Result SecondsSinceEpochFromTime(Time time, uint64_t* outSeconds); 116 117 class Duration final { 118 public: 119 Duration(Time timeA, Time timeB) 120 : durationInSeconds( 121 timeA < timeB ? timeB.elapsedSecondsAD - timeA.elapsedSecondsAD 122 : timeA.elapsedSecondsAD - timeB.elapsedSecondsAD) {} 123 124 explicit Duration(uint64_t aDurationInSeconds) 125 : durationInSeconds(aDurationInSeconds) {} 126 127 bool operator>(const Duration& other) const { 128 return durationInSeconds > other.durationInSeconds; 129 } 130 bool operator<(const Duration& other) const { 131 return durationInSeconds < other.durationInSeconds; 132 } 133 134 private: 135 friend Result SecondsSinceEpochFromTime(Time time, uint64_t* outSeconds); 136 137 uint64_t durationInSeconds; 138 }; 139 } // namespace pkix 140 } // namespace mozilla 141 142 #endif // mozilla_pkix_Time_h