Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file SUMOTime.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Mirko Barthauer
19 : /// @date Fri, 29.04.2005
20 : ///
21 : // Variables, methods, and tools for internal time representation
22 : /****************************************************************************/
23 : #include <config.h>
24 :
25 : #include <sstream>
26 : #include <iostream>
27 : #include <iomanip>
28 : #include "SUMOTime.h"
29 : #include "StringTokenizer.h"
30 : #include "StringUtils.h"
31 : #include "StdDefs.h"
32 : #include "MsgHandler.h"
33 :
34 :
35 : // ===========================================================================
36 : // type definitions
37 : // ===========================================================================
38 : SUMOTime DELTA_T = 1000;
39 :
40 :
41 : // ===========================================================================
42 : // method definitions
43 : // ===========================================================================
44 :
45 : SUMOTime
46 11093809 : string2time(const std::string& r) {
47 11093809 : if (r.find(":") == std::string::npos) {
48 11093046 : const double time = StringUtils::toDouble(r);
49 11092839 : if (time > STEPS2TIME(SUMOTime_MAX)) {
50 18 : throw TimeFormatException("Input string '" + r + "' exceeds the time value range.");
51 : }
52 12397683 : return TIME2STEPS(time);
53 : } else {
54 : // try to parse dd:hh:mm:ss.s
55 2289 : std::vector<std::string> hrt = StringTokenizer(r, ":").getVector();
56 763 : if (hrt.size() == 3) {
57 : //std::cout << "parsed '" << r << "' as " << (3600 * string2time(hrt[0]) + 60 * string2time(hrt[1]) + string2time(hrt[2])) << "\n";
58 256 : return 3600 * string2time(hrt[0]) + 60 * string2time(hrt[1]) + string2time(hrt[2]);
59 507 : } else if (hrt.size() == 4) {
60 : //std::cout << "parsed '" << r << "' as " << (24 * 3600 * string2time(hrt[0]) + 3600 * string2time(hrt[1]) + 60 * string2time(hrt[2]) + string2time(hrt[3])) << "\n";
61 505 : return 24 * 3600 * string2time(hrt[0]) + 3600 * string2time(hrt[1]) + 60 * string2time(hrt[2]) + string2time(hrt[3]);
62 : }
63 6 : throw TimeFormatException("Input string '" + r + "' is not a valid time format (jj:HH:MM:SS.S).");
64 763 : }
65 : }
66 :
67 :
68 : bool
69 0 : isTime(const std::string& r) {
70 0 : if (r.find(":") == std::string::npos) {
71 0 : if (StringUtils::isDouble(r)) {
72 0 : return (StringUtils::toDouble(r) <= STEPS2TIME(SUMOTime_MAX));
73 : } else {
74 : return false;
75 : }
76 : } else {
77 : // try to parse dd:hh:mm:ss.s
78 0 : const std::vector<std::string> hrt = StringTokenizer(r, ":").getVector();
79 0 : if (hrt.size() == 3) {
80 0 : return StringUtils::isInt(hrt[0]) && StringUtils::isInt(hrt[1]) && StringUtils::isInt(hrt[2]);
81 0 : } else if (hrt.size() == 4) {
82 0 : return StringUtils::isInt(hrt[0]) && StringUtils::isInt(hrt[1]) && StringUtils::isInt(hrt[2]) && StringUtils::isDouble(hrt[3]);
83 : } else {
84 : return false;
85 : }
86 0 : }
87 : }
88 :
89 :
90 : std::string
91 17311794 : time2string(SUMOTime t, bool humanReadable) {
92 17311794 : std::ostringstream oss;
93 17311794 : if (t < 0) {
94 3376190 : oss << "-";
95 : }
96 : // needed for signed zero errors, see #5926
97 : // llabs(SUMOTime_MIN) would create overflow and must be handleed separately
98 17311794 : t = t == SUMOTime_MIN ? SUMOTime_MAX : (SUMOTime)llabs(t);
99 17311794 : SUMOTime scale = (SUMOTime)pow(10, MAX2(0, 3 - gPrecision));
100 17311794 : if (scale > 1) {
101 17300535 : if (t != SUMOTime_MAX) {
102 13926689 : t = (t + scale / 2) / scale;
103 : } else {
104 : scale = 1;
105 : }
106 : }
107 17311794 : const SUMOTime second = TIME2STEPS(1) / scale;
108 17311794 : if (humanReadable) {
109 1020 : const SUMOTime minute = 60 * second;
110 1020 : const SUMOTime hour = 60 * minute;
111 1020 : const SUMOTime day = 24 * hour;
112 : // 123456 -> "00:00:12.34"
113 1020 : if (t > day) {
114 304 : oss << t / day << ":";
115 304 : t %= day;
116 : }
117 : oss << std::setfill('0') << std::setw(2);
118 1020 : oss << t / hour << ":";
119 1020 : t %= hour;
120 1020 : oss << std::setw(2) << t / minute << ":";
121 1020 : t %= minute;
122 1020 : oss << std::setw(2) << t / second;
123 1020 : t %= second;
124 1020 : if (t != 0 || TS < 1.) {
125 260 : oss << ".";
126 260 : oss << std::setw(MIN2(3, gPrecision));
127 : oss << t;
128 : }
129 : } else {
130 17310774 : oss << t / second << ".";
131 17310774 : oss << std::setfill('0') << std::setw(MIN2(3, gPrecision));
132 17310774 : oss << t % second;
133 : }
134 17311794 : return oss.str();
135 17311794 : }
136 :
137 :
138 : std::string
139 17311794 : time2string(SUMOTime t) {
140 17311794 : return time2string(t, gHumanReadableTime);
141 : }
142 :
143 :
144 : std::string
145 32376 : elapsedMs2string(long long int t) {
146 32376 : if (gHumanReadableTime) {
147 56 : if (STEPS2TIME(t) > 60) {
148 : // round to seconds
149 0 : return time2string((t / 1000) * 1000);
150 : } else {
151 112 : return toString((double)t / 1000.0) + "s";
152 : }
153 : } else {
154 64640 : return time2string(t) + "s";
155 : }
156 : }
157 :
158 97937 : bool checkStepLengthMultiple(const SUMOTime t, const std::string& error, SUMOTime deltaT, SUMOTime begin) {
159 97937 : if (begin % deltaT == 0) {
160 97925 : if (t % deltaT != 0) {
161 656 : WRITE_WARNING("The given time value " + time2string(t) + " is not a multiple of the step length " + time2string(deltaT) + error + ".")
162 : }
163 : } else {
164 12 : if ((t - begin) % deltaT != 0) {
165 30 : WRITE_WARNING("The given time value " + time2string(t) + " is not reached with step length " + time2string(deltaT)
166 : + " and begin time " + time2string(begin) + error + ".")
167 : }
168 : }
169 : // next line used to fix build
170 97937 : return false;
171 : }
172 :
173 95928 : void checkTimeBounds(const double time) {
174 95928 : if (time > STEPS2TIME(SUMOTime_MAX)) {
175 0 : throw TimeFormatException("Input time " + toString(time) + "s exceeds the time value range.");
176 : }
177 95928 : }
178 :
179 :
180 : /****************************************************************************/
|