Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/common/SUMOTime.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
string2time(const std::string& r) {
47
if (r.find(":") == std::string::npos) {
48
const double time = StringUtils::toDouble(r);
49
if (time > STEPS2TIME(SUMOTime_MAX)) {
50
throw TimeFormatException("Input string '" + r + "' exceeds the time value range.");
51
}
52
return TIME2STEPS(time);
53
} else {
54
// try to parse dd:hh:mm:ss.s
55
std::vector<std::string> hrt = StringTokenizer(r, ":").getVector();
56
if (hrt.size() == 3) {
57
//std::cout << "parsed '" << r << "' as " << (3600 * string2time(hrt[0]) + 60 * string2time(hrt[1]) + string2time(hrt[2])) << "\n";
58
return 3600 * string2time(hrt[0]) + 60 * string2time(hrt[1]) + string2time(hrt[2]);
59
} 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
return 24 * 3600 * string2time(hrt[0]) + 3600 * string2time(hrt[1]) + 60 * string2time(hrt[2]) + string2time(hrt[3]);
62
}
63
throw TimeFormatException("Input string '" + r + "' is not a valid time format (jj:HH:MM:SS.S).");
64
}
65
}
66
67
68
bool
69
isTime(const std::string& r) {
70
if (r.find(":") == std::string::npos) {
71
if (StringUtils::isDouble(r)) {
72
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
const std::vector<std::string> hrt = StringTokenizer(r, ":").getVector();
79
if (hrt.size() == 3) {
80
return StringUtils::isInt(hrt[0]) && StringUtils::isInt(hrt[1]) && StringUtils::isInt(hrt[2]);
81
} else if (hrt.size() == 4) {
82
return StringUtils::isInt(hrt[0]) && StringUtils::isInt(hrt[1]) && StringUtils::isInt(hrt[2]) && StringUtils::isDouble(hrt[3]);
83
} else {
84
return false;
85
}
86
}
87
}
88
89
90
std::string
91
time2string(SUMOTime t, bool humanReadable) {
92
std::ostringstream oss;
93
if (t < 0) {
94
oss << "-";
95
}
96
// needed for signed zero errors, see #5926
97
// llabs(SUMOTime_MIN) would create overflow and must be handleed separately
98
t = t == SUMOTime_MIN ? SUMOTime_MAX : (SUMOTime)llabs(t);
99
SUMOTime scale = (SUMOTime)pow(10, MAX2(0, 3 - gPrecision));
100
if (scale > 1) {
101
if (t != SUMOTime_MAX) {
102
t = (t + scale / 2) / scale;
103
} else {
104
scale = 1;
105
}
106
}
107
const SUMOTime second = TIME2STEPS(1) / scale;
108
if (humanReadable) {
109
const SUMOTime minute = 60 * second;
110
const SUMOTime hour = 60 * minute;
111
const SUMOTime day = 24 * hour;
112
// 123456 -> "00:00:12.34"
113
if (t > day) {
114
oss << t / day << ":";
115
t %= day;
116
}
117
oss << std::setfill('0') << std::setw(2);
118
oss << t / hour << ":";
119
t %= hour;
120
oss << std::setw(2) << t / minute << ":";
121
t %= minute;
122
oss << std::setw(2) << t / second;
123
t %= second;
124
if (t != 0 || TS < 1.) {
125
oss << ".";
126
oss << std::setw(MIN2(3, gPrecision));
127
oss << t;
128
}
129
} else {
130
oss << t / second << ".";
131
oss << std::setfill('0') << std::setw(MIN2(3, gPrecision));
132
oss << t % second;
133
}
134
return oss.str();
135
}
136
137
138
std::string
139
time2string(SUMOTime t) {
140
return time2string(t, gHumanReadableTime);
141
}
142
143
144
std::string
145
elapsedMs2string(long long int t) {
146
if (gHumanReadableTime) {
147
if (STEPS2TIME(t) > 60) {
148
// round to seconds
149
return time2string((t / 1000) * 1000);
150
} else {
151
return toString((double)t / 1000.0) + "s";
152
}
153
} else {
154
return time2string(t) + "s";
155
}
156
}
157
158
bool checkStepLengthMultiple(const SUMOTime t, const std::string& error, SUMOTime deltaT, SUMOTime begin) {
159
if (begin % deltaT == 0) {
160
if (t % deltaT != 0) {
161
WRITE_WARNING("The given time value " + time2string(t) + " is not a multiple of the step length " + time2string(deltaT) + error + ".")
162
}
163
} else {
164
if ((t - begin) % deltaT != 0) {
165
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
return false;
171
}
172
173
void checkTimeBounds(const double time) {
174
if (time > STEPS2TIME(SUMOTime_MAX)) {
175
throw TimeFormatException("Input time " + toString(time) + "s exceeds the time value range.");
176
}
177
}
178
179
180
/****************************************************************************/
181
182