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 #include <google/protobuf/stubs/time.h>
31 
32 #include <google/protobuf/testing/googletest.h>
33 #include <gtest/gtest.h>
34 
35 namespace google {
36 namespace protobuf {
37 namespace internal {
38 namespace {
39 static const int64 kSecondsPerDay = 3600 * 24;
40 
41 // For DateTime, tests will mostly focuse on the date part because that's
42 // the tricky one.
CreateTimestamp(int year,int month,int day)43 int64 CreateTimestamp(int year, int month, int day) {
44   DateTime time;
45   time.year = year;
46   time.month = month;
47   time.day = day;
48   time.hour = time.minute = time.second = 0;
49   int64 result;
50   GOOGLE_CHECK(DateTimeToSeconds(time, &result));
51   // Check that a roundtrip produces the same result.
52   GOOGLE_CHECK(SecondsToDateTime(result, &time));
53   GOOGLE_CHECK(time.year == year);
54   GOOGLE_CHECK(time.month == month);
55   GOOGLE_CHECK(time.day == day);
56   return result;
57 }
58 
TEST(DateTimeTest,SimpleTime)59 TEST(DateTimeTest, SimpleTime) {
60   DateTime time;
61   ASSERT_TRUE(SecondsToDateTime(1, &time));
62   EXPECT_EQ(1970, time.year);
63   EXPECT_EQ(1, time.month);
64   EXPECT_EQ(1, time.day);
65   EXPECT_EQ(0, time.hour);
66   EXPECT_EQ(0, time.minute);
67   EXPECT_EQ(1, time.second);
68   int64 seconds;
69   ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
70   EXPECT_EQ(1, seconds);
71 
72   ASSERT_TRUE(SecondsToDateTime(-1, &time));
73   EXPECT_EQ(1969, time.year);
74   EXPECT_EQ(12, time.month);
75   EXPECT_EQ(31, time.day);
76   EXPECT_EQ(23, time.hour);
77   EXPECT_EQ(59, time.minute);
78   EXPECT_EQ(59, time.second);
79   ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
80   EXPECT_EQ(-1, seconds);
81 
82   DateTime start, end;
83   start.year = 1;
84   start.month = 1;
85   start.day = 1;
86   start.hour = 0;
87   start.minute = 0;
88   start.second = 0;
89   end.year = 9999;
90   end.month = 12;
91   end.day = 31;
92   end.hour = 23;
93   end.minute = 59;
94   end.second = 59;
95   int64 start_time, end_time;
96   ASSERT_TRUE(DateTimeToSeconds(start, &start_time));
97   ASSERT_TRUE(DateTimeToSeconds(end, &end_time));
98   EXPECT_EQ(315537897599LL, end_time - start_time);
99   ASSERT_TRUE(SecondsToDateTime(start_time, &time));
100   ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
101   EXPECT_EQ(start_time, seconds);
102   ASSERT_TRUE(SecondsToDateTime(end_time, &time));
103   ASSERT_TRUE(DateTimeToSeconds(time, &seconds));
104   EXPECT_EQ(end_time, seconds);
105 }
106 
TEST(DateTimeTest,DayInMonths)107 TEST(DateTimeTest, DayInMonths) {
108   // Check that month boundaries are handled correctly.
109   EXPECT_EQ(kSecondsPerDay,
110             CreateTimestamp(2015, 1, 1) - CreateTimestamp(2014, 12, 31));
111   EXPECT_EQ(kSecondsPerDay,
112             CreateTimestamp(2015, 2, 1) - CreateTimestamp(2015, 1, 31));
113   EXPECT_EQ(kSecondsPerDay,
114             CreateTimestamp(2015, 3, 1) - CreateTimestamp(2015, 2, 28));
115   EXPECT_EQ(kSecondsPerDay,
116             CreateTimestamp(2015, 4, 1) - CreateTimestamp(2015, 3, 31));
117   EXPECT_EQ(kSecondsPerDay,
118             CreateTimestamp(2015, 5, 1) - CreateTimestamp(2015, 4, 30));
119   EXPECT_EQ(kSecondsPerDay,
120             CreateTimestamp(2015, 6, 1) - CreateTimestamp(2015, 5, 31));
121   EXPECT_EQ(kSecondsPerDay,
122             CreateTimestamp(2015, 7, 1) - CreateTimestamp(2015, 6, 30));
123   EXPECT_EQ(kSecondsPerDay,
124             CreateTimestamp(2015, 8, 1) - CreateTimestamp(2015, 7, 31));
125   EXPECT_EQ(kSecondsPerDay,
126             CreateTimestamp(2015, 9, 1) - CreateTimestamp(2015, 8, 31));
127   EXPECT_EQ(kSecondsPerDay,
128             CreateTimestamp(2015, 10, 1) - CreateTimestamp(2015, 9, 30));
129   EXPECT_EQ(kSecondsPerDay,
130             CreateTimestamp(2015, 11, 1) - CreateTimestamp(2015, 10, 31));
131   EXPECT_EQ(kSecondsPerDay,
132             CreateTimestamp(2015, 12, 1) - CreateTimestamp(2015, 11, 30));
133   EXPECT_EQ(kSecondsPerDay,
134             CreateTimestamp(2016, 1, 1) - CreateTimestamp(2015, 12, 31));
135 }
136 
TEST(DateTimeTest,LeapYear)137 TEST(DateTimeTest, LeapYear) {
138   // Non-leap year.
139   EXPECT_EQ(kSecondsPerDay,
140             CreateTimestamp(2015, 3, 1) - CreateTimestamp(2015, 2, 28));
141   // Leap year.
142   EXPECT_EQ(kSecondsPerDay,
143             CreateTimestamp(2016, 3, 1) - CreateTimestamp(2016, 2, 29));
144   // Non-leap year.
145   EXPECT_EQ(kSecondsPerDay,
146             CreateTimestamp(2100, 3, 1) - CreateTimestamp(2100, 2, 28));
147   // Leap year.
148   EXPECT_EQ(kSecondsPerDay,
149             CreateTimestamp(2400, 3, 1) - CreateTimestamp(2400, 2, 29));
150 }
151 
TEST(DateTimeTest,StringFormat)152 TEST(DateTimeTest, StringFormat) {
153   DateTime start, end;
154   start.year = 1;
155   start.month = 1;
156   start.day = 1;
157   start.hour = 0;
158   start.minute = 0;
159   start.second = 0;
160   end.year = 9999;
161   end.month = 12;
162   end.day = 31;
163   end.hour = 23;
164   end.minute = 59;
165   end.second = 59;
166   int64 start_time, end_time;
167   ASSERT_TRUE(DateTimeToSeconds(start, &start_time));
168   ASSERT_TRUE(DateTimeToSeconds(end, &end_time));
169 
170   EXPECT_EQ("0001-01-01T00:00:00Z", FormatTime(start_time, 0));
171   EXPECT_EQ("9999-12-31T23:59:59Z", FormatTime(end_time, 0));
172 
173   // Make sure the nanoseconds part is formated correctly.
174   EXPECT_EQ("1970-01-01T00:00:00.010Z", FormatTime(0, 10000000));
175   EXPECT_EQ("1970-01-01T00:00:00.000010Z", FormatTime(0, 10000));
176   EXPECT_EQ("1970-01-01T00:00:00.000000010Z", FormatTime(0, 10));
177 }
178 
TEST(DateTimeTest,ParseString)179 TEST(DateTimeTest, ParseString) {
180   int64 seconds;
181   int32 nanos;
182   ASSERT_TRUE(ParseTime("0001-01-01T00:00:00Z", &seconds, &nanos));
183   EXPECT_EQ("0001-01-01T00:00:00Z", FormatTime(seconds, nanos));
184   ASSERT_TRUE(ParseTime("9999-12-31T23:59:59.999999999Z", &seconds, &nanos));
185   EXPECT_EQ("9999-12-31T23:59:59.999999999Z", FormatTime(seconds, nanos));
186 
187   // Test time zone offsets.
188   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00-08:00", &seconds, &nanos));
189   EXPECT_EQ("1970-01-01T08:00:00Z", FormatTime(seconds, nanos));
190   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00+08:00", &seconds, &nanos));
191   EXPECT_EQ("1969-12-31T16:00:00Z", FormatTime(seconds, nanos));
192 
193   // Test nanoseconds.
194   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.01Z", &seconds, &nanos));
195   EXPECT_EQ("1970-01-01T00:00:00.010Z", FormatTime(seconds, nanos));
196   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.00001-08:00", &seconds, &nanos));
197   EXPECT_EQ("1970-01-01T08:00:00.000010Z", FormatTime(seconds, nanos));
198   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.00000001+08:00", &seconds, &nanos));
199   EXPECT_EQ("1969-12-31T16:00:00.000000010Z", FormatTime(seconds, nanos));
200   // Fractional parts less than 1 nanosecond will be ignored.
201   ASSERT_TRUE(ParseTime("1970-01-01T00:00:00.0123456789Z", &seconds, &nanos));
202   EXPECT_EQ("1970-01-01T00:00:00.012345678Z", FormatTime(seconds, nanos));
203 }
204 
205 }  // namespace
206 }  // namespace internal
207 }  // namespace protobuf
208 }  // namespace google
209