Home | History | Annotate | Download | only in time
      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:
     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.
     74 TEST_F(PRTimeTest, ParseTimeTest1) {
     75   time_t current_time = 0;
     76   time(&current_time);
     77 
     78   const int BUFFER_SIZE = 64;
     79   struct tm local_time = {0};
     80   char time_buf[BUFFER_SIZE] = {0};
     81 #if defined(OS_WIN)
     82   localtime_s(&local_time, &current_time);
     83   asctime_s(time_buf, arraysize(time_buf), &local_time);
     84 #elif defined(OS_POSIX)
     85   localtime_r(&current_time, &local_time);
     86   asctime_r(&local_time, time_buf);
     87 #endif
     88 
     89   PRTime current_time64 = static_cast<PRTime>(current_time) * PR_USEC_PER_SEC;
     90 
     91   PRTime parsed_time = 0;
     92   PRStatus result = PR_ParseTimeString(time_buf, PR_FALSE, &parsed_time);
     93   EXPECT_EQ(PR_SUCCESS, result);
     94   EXPECT_EQ(current_time64, parsed_time);
     95 }
     96 
     97 TEST_F(PRTimeTest, ParseTimeTest2) {
     98   PRTime parsed_time = 0;
     99   PRStatus result = PR_ParseTimeString("Mon, 15 Oct 2007 19:45:00 GMT",
    100                                        PR_FALSE, &parsed_time);
    101   EXPECT_EQ(PR_SUCCESS, result);
    102   EXPECT_EQ(comparison_time_pdt, parsed_time);
    103 }
    104 
    105 TEST_F(PRTimeTest, ParseTimeTest3) {
    106   PRTime parsed_time = 0;
    107   PRStatus result = PR_ParseTimeString("15 Oct 07 12:45:00", PR_FALSE,
    108                                        &parsed_time);
    109   EXPECT_EQ(PR_SUCCESS, result);
    110   EXPECT_EQ(comparison_time_local_, parsed_time);
    111 }
    112 
    113 TEST_F(PRTimeTest, ParseTimeTest4) {
    114   PRTime parsed_time = 0;
    115   PRStatus result = PR_ParseTimeString("15 Oct 07 19:45 GMT", PR_FALSE,
    116                                        &parsed_time);
    117   EXPECT_EQ(PR_SUCCESS, result);
    118   EXPECT_EQ(comparison_time_pdt, parsed_time);
    119 }
    120 
    121 TEST_F(PRTimeTest, ParseTimeTest5) {
    122   PRTime parsed_time = 0;
    123   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:45 PDT 2007",
    124                                        PR_FALSE, &parsed_time);
    125   EXPECT_EQ(PR_SUCCESS, result);
    126   EXPECT_EQ(comparison_time_pdt, parsed_time);
    127 }
    128 
    129 TEST_F(PRTimeTest, ParseTimeTest6) {
    130   PRTime parsed_time = 0;
    131   PRStatus result = PR_ParseTimeString("Monday, Oct 15, 2007 12:45 PM",
    132                                        PR_FALSE, &parsed_time);
    133   EXPECT_EQ(PR_SUCCESS, result);
    134   EXPECT_EQ(comparison_time_local_, parsed_time);
    135 }
    136 
    137 TEST_F(PRTimeTest, ParseTimeTest7) {
    138   PRTime parsed_time = 0;
    139   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00 PM", PR_FALSE,
    140                                        &parsed_time);
    141   EXPECT_EQ(PR_SUCCESS, result);
    142   EXPECT_EQ(comparison_time_local_, parsed_time);
    143 }
    144 
    145 TEST_F(PRTimeTest, ParseTimeTest8) {
    146   PRTime parsed_time = 0;
    147   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00. PM", PR_FALSE,
    148                                        &parsed_time);
    149   EXPECT_EQ(PR_SUCCESS, result);
    150   EXPECT_EQ(comparison_time_local_, parsed_time);
    151 }
    152 
    153 TEST_F(PRTimeTest, ParseTimeTest9) {
    154   PRTime parsed_time = 0;
    155   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00.0 PM", PR_FALSE,
    156                                        &parsed_time);
    157   EXPECT_EQ(PR_SUCCESS, result);
    158   EXPECT_EQ(comparison_time_local_, parsed_time);
    159 }
    160 
    161 TEST_F(PRTimeTest, ParseTimeTest10) {
    162   PRTime parsed_time = 0;
    163   PRStatus result = PR_ParseTimeString("15-OCT-2007 12:45pm", PR_FALSE,
    164                                        &parsed_time);
    165   EXPECT_EQ(PR_SUCCESS, result);
    166   EXPECT_EQ(comparison_time_local_, parsed_time);
    167 }
    168 
    169 TEST_F(PRTimeTest, ParseTimeTest11) {
    170   PRTime parsed_time = 0;
    171   PRStatus result = PR_ParseTimeString("16 Oct 2007 4:45-JST (Tuesday)",
    172                                        PR_FALSE, &parsed_time);
    173   EXPECT_EQ(PR_SUCCESS, result);
    174   EXPECT_EQ(comparison_time_pdt, parsed_time);
    175 }
    176 
    177 // hh:mm timezone offset.
    178 TEST_F(PRTimeTest, ParseTimeTest12) {
    179   PRTime parsed_time = 0;
    180   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381+02:00",
    181                                        PR_FALSE, &parsed_time);
    182   EXPECT_EQ(PR_SUCCESS, result);
    183   EXPECT_EQ(comparison_time_2, parsed_time);
    184 }
    185 
    186 // hhmm timezone offset.
    187 TEST_F(PRTimeTest, ParseTimeTest13) {
    188   PRTime parsed_time = 0;
    189   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381+0200",
    190                                        PR_FALSE, &parsed_time);
    191   EXPECT_EQ(PR_SUCCESS, result);
    192   EXPECT_EQ(comparison_time_2, parsed_time);
    193 }
    194 
    195 // hh timezone offset.
    196 TEST_F(PRTimeTest, ParseTimeTest14) {
    197   PRTime parsed_time = 0;
    198   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.4413819+02",
    199                                        PR_FALSE, &parsed_time);
    200   EXPECT_EQ(PR_SUCCESS, result);
    201   EXPECT_EQ(comparison_time_2, parsed_time);
    202 }
    203 
    204 // 5 digits fractional second.
    205 TEST_F(PRTimeTest, ParseTimeTest15) {
    206   PRTime parsed_time = 0;
    207   PRStatus result = PR_ParseTimeString("2013-07-08T09:28:12.44138Z",
    208                                        PR_FALSE, &parsed_time);
    209   EXPECT_EQ(PR_SUCCESS, result);
    210   EXPECT_EQ(comparison_time_2-1, parsed_time);
    211 }
    212 
    213 // Fractional seconds, local timezone.
    214 TEST_F(PRTimeTest, ParseTimeTest16) {
    215   PRTime parsed_time = 0;
    216   PRStatus result = PR_ParseTimeString("2013-07-08T11:28:12.441381",
    217                                        PR_FALSE, &parsed_time);
    218   EXPECT_EQ(PR_SUCCESS, result);
    219   EXPECT_EQ(comparison_time_local_2_, parsed_time);
    220 }
    221 
    222 // "Z" (=GMT) timezone.
    223 TEST_F(PRTimeTest, ParseTimeTest17) {
    224   PRTime parsed_time = 0;
    225   PRStatus result = PR_ParseTimeString("2013-07-08T09:28:12.441381Z",
    226                                        PR_FALSE, &parsed_time);
    227   EXPECT_EQ(PR_SUCCESS, result);
    228   EXPECT_EQ(comparison_time_2, parsed_time);
    229 }
    230 
    231 // "T" delimiter replaced by space.
    232 TEST_F(PRTimeTest, ParseTimeTest18) {
    233   PRTime parsed_time = 0;
    234   PRStatus result = PR_ParseTimeString("2013-07-08 09:28:12.441381Z",
    235                                        PR_FALSE, &parsed_time);
    236   EXPECT_EQ(PR_SUCCESS, result);
    237   EXPECT_EQ(comparison_time_2, parsed_time);
    238 }
    239 
    240 TEST_F(PRTimeTest, ParseTimeTestInvalid1) {
    241   PRTime parsed_time = 0;
    242   PRStatus result = PR_ParseTimeString("201-07-08T09:28:12.441381Z",
    243                                        PR_FALSE, &parsed_time);
    244   EXPECT_EQ(PR_FAILURE, result);
    245 }
    246 
    247 TEST_F(PRTimeTest, ParseTimeTestInvalid2) {
    248   PRTime parsed_time = 0;
    249   PRStatus result = PR_ParseTimeString("2013-007-08T09:28:12.441381Z",
    250                                        PR_FALSE, &parsed_time);
    251   EXPECT_EQ(PR_FAILURE, result);
    252 }
    253 
    254 TEST_F(PRTimeTest, ParseTimeTestInvalid3) {
    255   PRTime parsed_time = 0;
    256   PRStatus result = PR_ParseTimeString("2013-07-008T09:28:12.441381Z",
    257                                        PR_FALSE, &parsed_time);
    258   EXPECT_EQ(PR_FAILURE, result);
    259 }
    260 
    261 // This test should not crash when compiled with Visual C++ 2005 (see
    262 // http://crbug.com/4387).
    263 TEST_F(PRTimeTest, ParseTimeTestOutOfRange) {
    264   PRTime parsed_time = 0;
    265   // Note the lack of timezone in the time string.  The year has to be 3001.
    266   // The date has to be after 23:59:59, December 31, 3000, US Pacific Time, so
    267   // we use January 2, 3001 to make sure it's after the magic maximum in any
    268   // timezone.
    269   PRStatus result = PR_ParseTimeString("Sun Jan  2 00:00:00 3001",
    270                                        PR_FALSE, &parsed_time);
    271   EXPECT_EQ(PR_SUCCESS, result);
    272 }
    273 
    274 TEST_F(PRTimeTest, ParseTimeTestNotNormalized1) {
    275   PRTime parsed_time = 0;
    276   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:44:60 PDT 2007",
    277                                        PR_FALSE, &parsed_time);
    278   EXPECT_EQ(PR_SUCCESS, result);
    279   EXPECT_EQ(comparison_time_pdt, parsed_time);
    280 }
    281 
    282 TEST_F(PRTimeTest, ParseTimeTestNotNormalized2) {
    283   PRTime parsed_time = 0;
    284   PRStatus result = PR_ParseTimeString("Sun Oct 14 36:45 PDT 2007",
    285                                        PR_FALSE, &parsed_time);
    286   EXPECT_EQ(PR_SUCCESS, result);
    287   EXPECT_EQ(comparison_time_pdt, parsed_time);
    288 }
    289 
    290 }  // namespace
    291