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 35namespace google { 36namespace protobuf { 37namespace internal { 38namespace { 39static const int64 kSecondsPerDay = 3600 * 24; 40 41// For DateTime, tests will mostly focuse on the date part because that's 42// the tricky one. 43int64 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 59TEST(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 107TEST(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 137TEST(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 152TEST(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 179TEST(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