• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stdint.h>
6 #include <time.h>
7 
8 #include "base/compiler_specific.h"
9 #include "base/macros.h"
10 #include "base/third_party/nspr/prtime.h"
11 #include "base/time/time.h"
12 #include "build/build_config.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 using base::Time;
16 
17 namespace {
18 
19 // time_t representation of 15th Oct 2007 12:45:00 PDT
20 PRTime comparison_time_pdt = 1192477500 * Time::kMicrosecondsPerSecond;
21 
22 // Time with positive tz offset and fractional seconds:
23 // 2013-07-08T11:28:12.441381+02:00
24 PRTime comparison_time_2 = INT64_C(1373275692441381);   // represented as GMT
25 
26 // Specialized test fixture allowing time strings without timezones to be
27 // tested by comparing them to a known time in the local zone.
28 class PRTimeTest : public testing::Test {
29  protected:
SetUp()30   void SetUp() override {
31     // Use mktime to get a time_t, and turn it into a PRTime by converting
32     // seconds to microseconds.  Use 15th Oct 2007 12:45:00 local.  This
33     // must be a time guaranteed to be outside of a DST fallback hour in
34     // any timezone.
35     struct tm local_comparison_tm = {
36       0,            // second
37       45,           // minute
38       12,           // hour
39       15,           // day of month
40       10 - 1,       // month
41       2007 - 1900,  // year
42       0,            // day of week (ignored, output only)
43       0,            // day of year (ignored, output only)
44       -1            // DST in effect, -1 tells mktime to figure it out
45     };
46     comparison_time_local_ =
47         mktime(&local_comparison_tm) * Time::kMicrosecondsPerSecond;
48     ASSERT_GT(comparison_time_local_, 0);
49 
50     const int microseconds = 441381;
51     struct tm local_comparison_tm_2 = {
52       12,           // second
53       28,           // minute
54       11,           // hour
55       8,            // day of month
56       7 - 1,        // month
57       2013 - 1900,  // year
58       0,            // day of week (ignored, output only)
59       0,            // day of year (ignored, output only)
60       -1            // DST in effect, -1 tells mktime to figure it out
61     };
62     comparison_time_local_2_ =
63         mktime(&local_comparison_tm_2) * Time::kMicrosecondsPerSecond;
64     ASSERT_GT(comparison_time_local_2_, 0);
65     comparison_time_local_2_ += microseconds;
66   }
67 
68   PRTime comparison_time_local_;
69   PRTime comparison_time_local_2_;
70 };
71 
72 // Tests the PR_ParseTimeString nspr helper function for
73 // a variety of time strings.
TEST_F(PRTimeTest,ParseTimeTest1)74 TEST_F(PRTimeTest, ParseTimeTest1) {
75   time_t current_time = 0;
76   time(&current_time);
77 
78   struct tm local_time = {};
79   char time_buf[64] = {};
80 #if defined(OS_WIN)
81   localtime_s(&local_time, &current_time);
82   asctime_s(time_buf, arraysize(time_buf), &local_time);
83 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
84   localtime_r(&current_time, &local_time);
85   asctime_r(&local_time, time_buf);
86 #endif
87 
88   PRTime current_time64 = static_cast<PRTime>(current_time) * PR_USEC_PER_SEC;
89 
90   PRTime parsed_time = 0;
91   PRStatus result = PR_ParseTimeString(time_buf, PR_FALSE, &parsed_time);
92   EXPECT_EQ(PR_SUCCESS, result);
93   EXPECT_EQ(current_time64, parsed_time);
94 }
95 
TEST_F(PRTimeTest,ParseTimeTest2)96 TEST_F(PRTimeTest, ParseTimeTest2) {
97   PRTime parsed_time = 0;
98   PRStatus result = PR_ParseTimeString("Mon, 15 Oct 2007 19:45:00 GMT",
99                                        PR_FALSE, &parsed_time);
100   EXPECT_EQ(PR_SUCCESS, result);
101   EXPECT_EQ(comparison_time_pdt, parsed_time);
102 }
103 
TEST_F(PRTimeTest,ParseTimeTest3)104 TEST_F(PRTimeTest, ParseTimeTest3) {
105   PRTime parsed_time = 0;
106   PRStatus result = PR_ParseTimeString("15 Oct 07 12:45:00", PR_FALSE,
107                                        &parsed_time);
108   EXPECT_EQ(PR_SUCCESS, result);
109   EXPECT_EQ(comparison_time_local_, parsed_time);
110 }
111 
TEST_F(PRTimeTest,ParseTimeTest4)112 TEST_F(PRTimeTest, ParseTimeTest4) {
113   PRTime parsed_time = 0;
114   PRStatus result = PR_ParseTimeString("15 Oct 07 19:45 GMT", PR_FALSE,
115                                        &parsed_time);
116   EXPECT_EQ(PR_SUCCESS, result);
117   EXPECT_EQ(comparison_time_pdt, parsed_time);
118 }
119 
TEST_F(PRTimeTest,ParseTimeTest5)120 TEST_F(PRTimeTest, ParseTimeTest5) {
121   PRTime parsed_time = 0;
122   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:45 PDT 2007",
123                                        PR_FALSE, &parsed_time);
124   EXPECT_EQ(PR_SUCCESS, result);
125   EXPECT_EQ(comparison_time_pdt, parsed_time);
126 }
127 
TEST_F(PRTimeTest,ParseTimeTest6)128 TEST_F(PRTimeTest, ParseTimeTest6) {
129   PRTime parsed_time = 0;
130   PRStatus result = PR_ParseTimeString("Monday, Oct 15, 2007 12:45 PM",
131                                        PR_FALSE, &parsed_time);
132   EXPECT_EQ(PR_SUCCESS, result);
133   EXPECT_EQ(comparison_time_local_, parsed_time);
134 }
135 
TEST_F(PRTimeTest,ParseTimeTest7)136 TEST_F(PRTimeTest, ParseTimeTest7) {
137   PRTime parsed_time = 0;
138   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00 PM", PR_FALSE,
139                                        &parsed_time);
140   EXPECT_EQ(PR_SUCCESS, result);
141   EXPECT_EQ(comparison_time_local_, parsed_time);
142 }
143 
TEST_F(PRTimeTest,ParseTimeTest8)144 TEST_F(PRTimeTest, ParseTimeTest8) {
145   PRTime parsed_time = 0;
146   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00. PM", PR_FALSE,
147                                        &parsed_time);
148   EXPECT_EQ(PR_SUCCESS, result);
149   EXPECT_EQ(comparison_time_local_, parsed_time);
150 }
151 
TEST_F(PRTimeTest,ParseTimeTest9)152 TEST_F(PRTimeTest, ParseTimeTest9) {
153   PRTime parsed_time = 0;
154   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00.0 PM", PR_FALSE,
155                                        &parsed_time);
156   EXPECT_EQ(PR_SUCCESS, result);
157   EXPECT_EQ(comparison_time_local_, parsed_time);
158 }
159 
TEST_F(PRTimeTest,ParseTimeTest10)160 TEST_F(PRTimeTest, ParseTimeTest10) {
161   PRTime parsed_time = 0;
162   PRStatus result = PR_ParseTimeString("15-OCT-2007 12:45pm", PR_FALSE,
163                                        &parsed_time);
164   EXPECT_EQ(PR_SUCCESS, result);
165   EXPECT_EQ(comparison_time_local_, parsed_time);
166 }
167 
TEST_F(PRTimeTest,ParseTimeTest11)168 TEST_F(PRTimeTest, ParseTimeTest11) {
169   PRTime parsed_time = 0;
170   PRStatus result = PR_ParseTimeString("16 Oct 2007 4:45-JST (Tuesday)",
171                                        PR_FALSE, &parsed_time);
172   EXPECT_EQ(PR_SUCCESS, result);
173   EXPECT_EQ(comparison_time_pdt, parsed_time);
174 }
175 
176 // hh:mm timezone offset.
TEST_F(PRTimeTest,ParseTimeTest12)177 TEST_F(PRTimeTest, ParseTimeTest12) {
178   PRTime parsed_time = 0;
179   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381+02:00",
180                                        PR_FALSE, &parsed_time);
181   EXPECT_EQ(PR_SUCCESS, result);
182   EXPECT_EQ(comparison_time_2, parsed_time);
183 }
184 
185 // hhmm timezone offset.
TEST_F(PRTimeTest,ParseTimeTest13)186 TEST_F(PRTimeTest, ParseTimeTest13) {
187   PRTime parsed_time = 0;
188   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381+0200",
189                                        PR_FALSE, &parsed_time);
190   EXPECT_EQ(PR_SUCCESS, result);
191   EXPECT_EQ(comparison_time_2, parsed_time);
192 }
193 
194 // hh timezone offset.
TEST_F(PRTimeTest,ParseTimeTest14)195 TEST_F(PRTimeTest, ParseTimeTest14) {
196   PRTime parsed_time = 0;
197   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.4413819+02",
198                                        PR_FALSE, &parsed_time);
199   EXPECT_EQ(PR_SUCCESS, result);
200   EXPECT_EQ(comparison_time_2, parsed_time);
201 }
202 
203 // 5 digits fractional second.
TEST_F(PRTimeTest,ParseTimeTest15)204 TEST_F(PRTimeTest, ParseTimeTest15) {
205   PRTime parsed_time = 0;
206   PRStatus result = PR_ParseTimeString("2013-07-08T09:28:12.44138Z",
207                                        PR_FALSE, &parsed_time);
208   EXPECT_EQ(PR_SUCCESS, result);
209   EXPECT_EQ(comparison_time_2-1, parsed_time);
210 }
211 
212 // Fractional seconds, local timezone.
TEST_F(PRTimeTest,ParseTimeTest16)213 TEST_F(PRTimeTest, ParseTimeTest16) {
214   PRTime parsed_time = 0;
215   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381",
216                                        PR_FALSE, &parsed_time);
217   EXPECT_EQ(PR_SUCCESS, result);
218   EXPECT_EQ(comparison_time_local_2_, parsed_time);
219 }
220 
221 // "Z" (=GMT) timezone.
TEST_F(PRTimeTest,ParseTimeTest17)222 TEST_F(PRTimeTest, ParseTimeTest17) {
223   PRTime parsed_time = 0;
224   PRStatus result = PR_ParseTimeString("2013-07-08T09:28:12.441381Z",
225                                        PR_FALSE, &parsed_time);
226   EXPECT_EQ(PR_SUCCESS, result);
227   EXPECT_EQ(comparison_time_2, parsed_time);
228 }
229 
230 // "T" delimiter replaced by space.
TEST_F(PRTimeTest,ParseTimeTest18)231 TEST_F(PRTimeTest, ParseTimeTest18) {
232   PRTime parsed_time = 0;
233   PRStatus result = PR_ParseTimeString("2013-07-08 09:28:12.441381Z",
234                                        PR_FALSE, &parsed_time);
235   EXPECT_EQ(PR_SUCCESS, result);
236   EXPECT_EQ(comparison_time_2, parsed_time);
237 }
238 
TEST_F(PRTimeTest,ParseTimeTestInvalid1)239 TEST_F(PRTimeTest, ParseTimeTestInvalid1) {
240   PRTime parsed_time = 0;
241   PRStatus result = PR_ParseTimeString("201-07-08T09:28:12.441381Z",
242                                        PR_FALSE, &parsed_time);
243   EXPECT_EQ(PR_FAILURE, result);
244 }
245 
TEST_F(PRTimeTest,ParseTimeTestInvalid2)246 TEST_F(PRTimeTest, ParseTimeTestInvalid2) {
247   PRTime parsed_time = 0;
248   PRStatus result = PR_ParseTimeString("2013-007-08T09:28:12.441381Z",
249                                        PR_FALSE, &parsed_time);
250   EXPECT_EQ(PR_FAILURE, result);
251 }
252 
TEST_F(PRTimeTest,ParseTimeTestInvalid3)253 TEST_F(PRTimeTest, ParseTimeTestInvalid3) {
254   PRTime parsed_time = 0;
255   PRStatus result = PR_ParseTimeString("2013-07-008T09:28:12.441381Z",
256                                        PR_FALSE, &parsed_time);
257   EXPECT_EQ(PR_FAILURE, result);
258 }
259 
260 // This test should not crash when compiled with Visual C++ 2005 (see
261 // http://crbug.com/4387).
TEST_F(PRTimeTest,ParseTimeTestOutOfRange)262 TEST_F(PRTimeTest, ParseTimeTestOutOfRange) {
263   PRTime parsed_time = 0;
264   // Note the lack of timezone in the time string.  The year has to be 3001.
265   // The date has to be after 23:59:59, December 31, 3000, US Pacific Time, so
266   // we use January 2, 3001 to make sure it's after the magic maximum in any
267   // timezone.
268   PRStatus result = PR_ParseTimeString("Sun Jan  2 00:00:00 3001",
269                                        PR_FALSE, &parsed_time);
270   EXPECT_EQ(PR_SUCCESS, result);
271 }
272 
TEST_F(PRTimeTest,ParseTimeTestNotNormalized1)273 TEST_F(PRTimeTest, ParseTimeTestNotNormalized1) {
274   PRTime parsed_time = 0;
275   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:44:60 PDT 2007",
276                                        PR_FALSE, &parsed_time);
277   EXPECT_EQ(PR_SUCCESS, result);
278   EXPECT_EQ(comparison_time_pdt, parsed_time);
279 }
280 
TEST_F(PRTimeTest,ParseTimeTestNotNormalized2)281 TEST_F(PRTimeTest, ParseTimeTestNotNormalized2) {
282   PRTime parsed_time = 0;
283   PRStatus result = PR_ParseTimeString("Sun Oct 14 36:45 PDT 2007",
284                                        PR_FALSE, &parsed_time);
285   EXPECT_EQ(PR_SUCCESS, result);
286   EXPECT_EQ(comparison_time_pdt, parsed_time);
287 }
288 
289 }  // namespace
290