• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <google/protobuf/util/time_util.h>
32 
33 #include <ctime>
34 
35 #include <google/protobuf/timestamp.pb.h>
36 #include <google/protobuf/duration.pb.h>
37 #include <google/protobuf/testing/googletest.h>
38 #include <gtest/gtest.h>
39 
40 namespace google {
41 namespace protobuf {
42 namespace util {
43 
44 using google::protobuf::Timestamp;
45 using google::protobuf::Duration;
46 
47 namespace {
48 
TEST(TimeUtilTest,TimestampStringFormat)49 TEST(TimeUtilTest, TimestampStringFormat) {
50   Timestamp begin, end;
51   EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
52   EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds());
53   EXPECT_EQ(0, begin.nanos());
54   EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
55   EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds());
56   EXPECT_EQ(999999999, end.nanos());
57   EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin));
58   EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end));
59 
60   // Test negative timestamps.
61   Timestamp time = TimeUtil::NanosecondsToTimestamp(-1);
62   EXPECT_EQ(-1, time.seconds());
63   // Timestamp's nano part is always non-negative.
64   EXPECT_EQ(999999999, time.nanos());
65   EXPECT_EQ("1969-12-31T23:59:59.999999999Z", TimeUtil::ToString(time));
66 
67   // Generated output should contain 3, 6, or 9 fractional digits.
68   EXPECT_EQ("1970-01-01T00:00:00Z",
69             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(0)));
70   EXPECT_EQ("1970-01-01T00:00:00.010Z",
71             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000000)));
72   EXPECT_EQ("1970-01-01T00:00:00.000010Z",
73             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000)));
74   EXPECT_EQ("1970-01-01T00:00:00.000000010Z",
75             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10)));
76 
77   // Parsing accepts an fractional digits as long as they fit into nano
78   // precision.
79   EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.1Z", &time));
80   EXPECT_EQ(100000000, TimeUtil::TimestampToNanoseconds(time));
81   EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0001Z", &time));
82   EXPECT_EQ(100000, TimeUtil::TimestampToNanoseconds(time));
83   EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0000001Z", &time));
84   EXPECT_EQ(100, TimeUtil::TimestampToNanoseconds(time));
85 
86   // Also accpets offsets.
87   EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00-08:00", &time));
88   EXPECT_EQ(8 * 3600, TimeUtil::TimestampToSeconds(time));
89 }
90 
TEST(TimeUtilTest,DurationStringFormat)91 TEST(TimeUtilTest, DurationStringFormat) {
92   Timestamp begin, end;
93   EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
94   EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
95 
96   EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin));
97   EXPECT_EQ(999999999, (end - begin).nanos());
98   EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end));
99   EXPECT_EQ(-999999999, (begin - end).nanos());
100 
101   // Generated output should contain 3, 6, or 9 fractional digits.
102   EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
103   EXPECT_EQ("0.010s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(10)));
104   EXPECT_EQ("0.000010s",
105             TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(10)));
106   EXPECT_EQ("0.000000010s",
107             TimeUtil::ToString(TimeUtil::NanosecondsToDuration(10)));
108 
109   // Parsing accepts an fractional digits as long as they fit into nano
110   // precision.
111   Duration d;
112   EXPECT_TRUE(TimeUtil::FromString("0.1s", &d));
113   EXPECT_EQ(100, TimeUtil::DurationToMilliseconds(d));
114   EXPECT_TRUE(TimeUtil::FromString("0.0001s", &d));
115   EXPECT_EQ(100, TimeUtil::DurationToMicroseconds(d));
116   EXPECT_TRUE(TimeUtil::FromString("0.0000001s", &d));
117   EXPECT_EQ(100, TimeUtil::DurationToNanoseconds(d));
118 
119   // Duration must support range from -315,576,000,000s to +315576000000s
120   // which includes negative values.
121   EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d));
122   EXPECT_EQ(315576000000LL, d.seconds());
123   EXPECT_EQ(999999999, d.nanos());
124   EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d));
125   EXPECT_EQ(-315576000000LL, d.seconds());
126   EXPECT_EQ(-999999999, d.nanos());
127 }
128 
TEST(TimeUtilTest,GetEpoch)129 TEST(TimeUtilTest, GetEpoch) {
130   EXPECT_EQ(0, TimeUtil::TimestampToNanoseconds(TimeUtil::GetEpoch()));
131 }
132 
TEST(TimeUtilTest,DurationIntegerConversion)133 TEST(TimeUtilTest, DurationIntegerConversion) {
134   EXPECT_EQ("0.000000001s",
135             TimeUtil::ToString(TimeUtil::NanosecondsToDuration(1)));
136   EXPECT_EQ("-0.000000001s",
137             TimeUtil::ToString(TimeUtil::NanosecondsToDuration(-1)));
138   EXPECT_EQ("0.000001s",
139             TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(1)));
140   EXPECT_EQ("-0.000001s",
141             TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(-1)));
142   EXPECT_EQ("0.001s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(1)));
143   EXPECT_EQ("-0.001s",
144             TimeUtil::ToString(TimeUtil::MillisecondsToDuration(-1)));
145   EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
146   EXPECT_EQ("-1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(-1)));
147   EXPECT_EQ("60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(1)));
148   EXPECT_EQ("-60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(-1)));
149   EXPECT_EQ("3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(1)));
150   EXPECT_EQ("-3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(-1)));
151 
152   EXPECT_EQ(
153       1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(1)));
154   EXPECT_EQ(
155       -1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(-1)));
156   EXPECT_EQ(
157       1, TimeUtil::DurationToMicroseconds(TimeUtil::MicrosecondsToDuration(1)));
158   EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
159                     TimeUtil::MicrosecondsToDuration(-1)));
160   EXPECT_EQ(
161       1, TimeUtil::DurationToMilliseconds(TimeUtil::MillisecondsToDuration(1)));
162   EXPECT_EQ(-1, TimeUtil::DurationToMilliseconds(
163                     TimeUtil::MillisecondsToDuration(-1)));
164   EXPECT_EQ(1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(1)));
165   EXPECT_EQ(-1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(-1)));
166   EXPECT_EQ(1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(1)));
167   EXPECT_EQ(-1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(-1)));
168   EXPECT_EQ(1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(1)));
169   EXPECT_EQ(-1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(-1)));
170 
171   // Test truncation behavior.
172   EXPECT_EQ(1, TimeUtil::DurationToMicroseconds(
173                    TimeUtil::NanosecondsToDuration(1999)));
174   // For negative values, Duration will be rounded towards 0.
175   EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
176                     TimeUtil::NanosecondsToDuration(-1999)));
177 }
178 
TEST(TestUtilTest,TimestampIntegerConversion)179 TEST(TestUtilTest, TimestampIntegerConversion) {
180   EXPECT_EQ("1970-01-01T00:00:00.000000001Z",
181             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(1)));
182   EXPECT_EQ("1969-12-31T23:59:59.999999999Z",
183             TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(-1)));
184   EXPECT_EQ("1970-01-01T00:00:00.000001Z",
185             TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(1)));
186   EXPECT_EQ("1969-12-31T23:59:59.999999Z",
187             TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(-1)));
188   EXPECT_EQ("1970-01-01T00:00:00.001Z",
189             TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(1)));
190   EXPECT_EQ("1969-12-31T23:59:59.999Z",
191             TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(-1)));
192   EXPECT_EQ("1970-01-01T00:00:01Z",
193             TimeUtil::ToString(TimeUtil::SecondsToTimestamp(1)));
194   EXPECT_EQ("1969-12-31T23:59:59Z",
195             TimeUtil::ToString(TimeUtil::SecondsToTimestamp(-1)));
196 
197   EXPECT_EQ(
198       1, TimeUtil::TimestampToNanoseconds(TimeUtil::NanosecondsToTimestamp(1)));
199   EXPECT_EQ(-1, TimeUtil::TimestampToNanoseconds(
200                     TimeUtil::NanosecondsToTimestamp(-1)));
201   EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
202                    TimeUtil::MicrosecondsToTimestamp(1)));
203   EXPECT_EQ(-1, TimeUtil::TimestampToMicroseconds(
204                     TimeUtil::MicrosecondsToTimestamp(-1)));
205   EXPECT_EQ(1, TimeUtil::TimestampToMilliseconds(
206                    TimeUtil::MillisecondsToTimestamp(1)));
207   EXPECT_EQ(-1, TimeUtil::TimestampToMilliseconds(
208                     TimeUtil::MillisecondsToTimestamp(-1)));
209   EXPECT_EQ(1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(1)));
210   EXPECT_EQ(-1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(-1)));
211 
212   // Test truncation behavior.
213   EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
214                    TimeUtil::NanosecondsToTimestamp(1999)));
215   // For negative values, Timestamp will be rounded down.
216   // For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
217   // will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
218   // "1970-01-01T00:00:00Z" (i.e., 0s).
219   EXPECT_EQ(-2, TimeUtil::TimestampToMicroseconds(
220                     TimeUtil::NanosecondsToTimestamp(-1999)));
221 }
222 
TEST(TimeUtilTest,TimeTConversion)223 TEST(TimeUtilTest, TimeTConversion) {
224   time_t value = time(NULL);
225   EXPECT_EQ(value,
226             TimeUtil::TimestampToTimeT(TimeUtil::TimeTToTimestamp(value)));
227   EXPECT_EQ(
228       1, TimeUtil::TimestampToTimeT(TimeUtil::MillisecondsToTimestamp(1999)));
229 }
230 
TEST(TimeUtilTest,TimevalConversion)231 TEST(TimeUtilTest, TimevalConversion) {
232   timeval value = TimeUtil::TimestampToTimeval(
233       TimeUtil::NanosecondsToTimestamp(1999999999));
234   EXPECT_EQ(1, value.tv_sec);
235   EXPECT_EQ(999999, value.tv_usec);
236   value = TimeUtil::TimestampToTimeval(
237       TimeUtil::NanosecondsToTimestamp(-1999999999));
238   EXPECT_EQ(-2, value.tv_sec);
239   EXPECT_EQ(0, value.tv_usec);
240 
241   value =
242       TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(1999999999));
243   EXPECT_EQ(1, value.tv_sec);
244   EXPECT_EQ(999999, value.tv_usec);
245   value =
246       TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(-1999999999));
247   EXPECT_EQ(-2, value.tv_sec);
248   EXPECT_EQ(1, value.tv_usec);
249 }
250 
TEST(TimeUtilTest,DurationOperators)251 TEST(TimeUtilTest, DurationOperators) {
252   Duration one_second = TimeUtil::SecondsToDuration(1);
253   Duration one_nano = TimeUtil::NanosecondsToDuration(1);
254 
255   // Test +/-
256   Duration a = one_second;
257   a += one_second;
258   a -= one_nano;
259   EXPECT_EQ("1.999999999s", TimeUtil::ToString(a));
260   Duration b = -a;
261   EXPECT_EQ("-1.999999999s", TimeUtil::ToString(b));
262   EXPECT_EQ("3.999999998s", TimeUtil::ToString(a + a));
263   EXPECT_EQ("0s", TimeUtil::ToString(a + b));
264   EXPECT_EQ("0s", TimeUtil::ToString(b + a));
265   EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b + b));
266   EXPECT_EQ("3.999999998s", TimeUtil::ToString(a - b));
267   EXPECT_EQ("0s", TimeUtil::ToString(a - a));
268   EXPECT_EQ("0s", TimeUtil::ToString(b - b));
269   EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b - a));
270 
271   // Test *
272   EXPECT_EQ(a + a, a * 2);
273   EXPECT_EQ(b + b, a * (-2));
274   EXPECT_EQ(b + b, b * 2);
275   EXPECT_EQ(a + a, b * (-2));
276   EXPECT_EQ("0.999999999s", TimeUtil::ToString(a * 0.5));
277   EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b * 0.5));
278   // Multiplication should not overflow if the result fits into the supported
279   // range of Duration (intermediate result may be larger than int64).
280   EXPECT_EQ("315575999684.424s",
281             TimeUtil::ToString((one_second - one_nano) * 315576000000LL));
282   EXPECT_EQ("-315575999684.424s",
283             TimeUtil::ToString((one_nano - one_second) * 315576000000LL));
284   EXPECT_EQ("-315575999684.424s",
285             TimeUtil::ToString((one_second - one_nano) * (-315576000000LL)));
286 
287   // Test / and %
288   EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2));
289   EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2));
290   Duration large = TimeUtil::SecondsToDuration(315576000000LL) - one_nano;
291   // We have to handle division with values beyond 64 bits.
292   EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / 315576000000LL));
293   EXPECT_EQ("-0.999999999s", TimeUtil::ToString((-large) / 315576000000LL));
294   EXPECT_EQ("-0.999999999s", TimeUtil::ToString(large / (-315576000000LL)));
295   Duration large2 = large + one_nano;
296   EXPECT_EQ(large, large % large2);
297   EXPECT_EQ(-large, (-large) % large2);
298   EXPECT_EQ(large, large % (-large2));
299   EXPECT_EQ(one_nano, large2 % large);
300   EXPECT_EQ(-one_nano, (-large2) % large);
301   EXPECT_EQ(one_nano, large2 % (-large));
302   // Some corner cases about negative values.
303   //
304   // (-5) / 2 = -2, remainder = -1
305   // (-5) / (-2) = 2, remainder = -1
306   a = TimeUtil::NanosecondsToDuration(-5);
307   EXPECT_EQ(TimeUtil::NanosecondsToDuration(-2), a / 2);
308   EXPECT_EQ(TimeUtil::NanosecondsToDuration(2), a / (-2));
309   b = TimeUtil::NanosecondsToDuration(2);
310   EXPECT_EQ(-2, a / b);
311   EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % b);
312   EXPECT_EQ(2, a / (-b));
313   EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % (-b));
314 
315   // Test relational operators.
316   EXPECT_TRUE(one_nano < one_second);
317   EXPECT_FALSE(one_second < one_second);
318   EXPECT_FALSE(one_second < one_nano);
319   EXPECT_FALSE(-one_nano < -one_second);
320   EXPECT_FALSE(-one_second < -one_second);
321   EXPECT_TRUE(-one_second < -one_nano);
322   EXPECT_TRUE(-one_nano < one_nano);
323   EXPECT_FALSE(one_nano < -one_nano);
324 
325   EXPECT_FALSE(one_nano > one_second);
326   EXPECT_FALSE(one_nano > one_nano);
327   EXPECT_TRUE(one_second > one_nano);
328 
329   EXPECT_FALSE(one_nano >= one_second);
330   EXPECT_TRUE(one_nano >= one_nano);
331   EXPECT_TRUE(one_second >= one_nano);
332 
333   EXPECT_TRUE(one_nano <= one_second);
334   EXPECT_TRUE(one_nano <= one_nano);
335   EXPECT_FALSE(one_second <= one_nano);
336 
337   EXPECT_TRUE(one_nano == one_nano);
338   EXPECT_FALSE(one_nano == one_second);
339 
340   EXPECT_FALSE(one_nano != one_nano);
341   EXPECT_TRUE(one_nano != one_second);
342 }
343 
TEST(TimeUtilTest,TimestampOperators)344 TEST(TimeUtilTest, TimestampOperators) {
345   Timestamp begin, end;
346   EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
347   EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
348   Duration d = end - begin;
349   EXPECT_TRUE(end == begin + d);
350   EXPECT_TRUE(end == d + begin);
351   EXPECT_TRUE(begin == end - d);
352 
353   // Test relational operators
354   Timestamp t1 = begin + d / 4;
355   Timestamp t2 = end - d / 4;
356   EXPECT_TRUE(t1 < t2);
357   EXPECT_FALSE(t1 < t1);
358   EXPECT_FALSE(t2 < t1);
359   EXPECT_FALSE(t1 > t2);
360   EXPECT_FALSE(t1 > t1);
361   EXPECT_TRUE(t2 > t1);
362   EXPECT_FALSE(t1 >= t2);
363   EXPECT_TRUE(t1 >= t1);
364   EXPECT_TRUE(t2 >= t1);
365   EXPECT_TRUE(t1 <= t2);
366   EXPECT_TRUE(t1 <= t1);
367   EXPECT_FALSE(t2 <= t1);
368 
369   EXPECT_FALSE(t1 == t2);
370   EXPECT_TRUE(t1 == t1);
371   EXPECT_FALSE(t2 == t1);
372   EXPECT_TRUE(t1 != t2);
373   EXPECT_FALSE(t1 != t1);
374   EXPECT_TRUE(t2 != t1);
375 }
376 
377 }  // namespace
378 }  // namespace util
379 }  // namespace protobuf
380 }  // namespace google
381