Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 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 <time.h>
      6 
      7 #include "base/third_party/nspr/prtime.h"
      8 #include "base/time.h"
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 using base::Time;
     12 
     13 namespace {
     14 
     15 // time_t representation of 15th Oct 2007 12:45:00 PDT
     16 PRTime comparison_time_pdt = 1192477500 * Time::kMicrosecondsPerSecond;
     17 
     18 // Specialized test fixture allowing time strings without timezones to be
     19 // tested by comparing them to a known time in the local zone.
     20 class PRTimeTest : public testing::Test {
     21  protected:
     22   virtual void SetUp() {
     23     // Use mktime to get a time_t, and turn it into a PRTime by converting
     24     // seconds to microseconds.  Use 15th Oct 2007 12:45:00 local.  This
     25     // must be a time guaranteed to be outside of a DST fallback hour in
     26     // any timezone.
     27     struct tm local_comparison_tm = {
     28       0,            // second
     29       45,           // minute
     30       12,           // hour
     31       15,           // day of month
     32       10 - 1,       // month
     33       2007 - 1900,  // year
     34       0,            // day of week (ignored, output only)
     35       0,            // day of year (ignored, output only)
     36       -1            // DST in effect, -1 tells mktime to figure it out
     37     };
     38     comparison_time_local_ = mktime(&local_comparison_tm) *
     39                              Time::kMicrosecondsPerSecond;
     40     ASSERT_GT(comparison_time_local_, 0);
     41   }
     42 
     43   PRTime comparison_time_local_;
     44 };
     45 
     46 // Tests the PR_ParseTimeString nspr helper function for
     47 // a variety of time strings.
     48 TEST_F(PRTimeTest, ParseTimeTest1) {
     49   time_t current_time = 0;
     50   time(&current_time);
     51 
     52   const int BUFFER_SIZE = 64;
     53   struct tm local_time = {0};
     54   char time_buf[BUFFER_SIZE] = {0};
     55 #if defined(OS_WIN)
     56   localtime_s(&local_time, &current_time);
     57   asctime_s(time_buf, arraysize(time_buf), &local_time);
     58 #elif defined(OS_POSIX)
     59   localtime_r(&current_time, &local_time);
     60   asctime_r(&local_time, time_buf);
     61 #endif
     62 
     63   PRTime current_time64 = static_cast<PRTime>(current_time) * PR_USEC_PER_SEC;
     64 
     65   PRTime parsed_time = 0;
     66   PRStatus result = PR_ParseTimeString(time_buf, PR_FALSE, &parsed_time);
     67   EXPECT_EQ(PR_SUCCESS, result);
     68   EXPECT_EQ(current_time64, parsed_time);
     69 }
     70 
     71 TEST_F(PRTimeTest, ParseTimeTest2) {
     72   PRTime parsed_time = 0;
     73   PRStatus result = PR_ParseTimeString("Mon, 15 Oct 2007 19:45:00 GMT",
     74                                        PR_FALSE, &parsed_time);
     75   EXPECT_EQ(PR_SUCCESS, result);
     76   EXPECT_EQ(parsed_time, comparison_time_pdt);
     77 }
     78 
     79 TEST_F(PRTimeTest, ParseTimeTest3) {
     80   PRTime parsed_time = 0;
     81   PRStatus result = PR_ParseTimeString("15 Oct 07 12:45:00", PR_FALSE,
     82                                        &parsed_time);
     83   EXPECT_EQ(PR_SUCCESS, result);
     84   EXPECT_EQ(parsed_time, comparison_time_local_);
     85 }
     86 
     87 TEST_F(PRTimeTest, ParseTimeTest4) {
     88   PRTime parsed_time = 0;
     89   PRStatus result = PR_ParseTimeString("15 Oct 07 19:45 GMT", PR_FALSE,
     90                                        &parsed_time);
     91   EXPECT_EQ(PR_SUCCESS, result);
     92   EXPECT_EQ(parsed_time, comparison_time_pdt);
     93 }
     94 
     95 TEST_F(PRTimeTest, ParseTimeTest5) {
     96   PRTime parsed_time = 0;
     97   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:45 PDT 2007",
     98                                        PR_FALSE, &parsed_time);
     99   EXPECT_EQ(PR_SUCCESS, result);
    100   EXPECT_EQ(parsed_time, comparison_time_pdt);
    101 }
    102 
    103 TEST_F(PRTimeTest, ParseTimeTest6) {
    104   PRTime parsed_time = 0;
    105   PRStatus result = PR_ParseTimeString("Monday, Oct 15, 2007 12:45 PM",
    106                                        PR_FALSE, &parsed_time);
    107   EXPECT_EQ(PR_SUCCESS, result);
    108   EXPECT_EQ(parsed_time, comparison_time_local_);
    109 }
    110 
    111 TEST_F(PRTimeTest, ParseTimeTest7) {
    112   PRTime parsed_time = 0;
    113   PRStatus result = PR_ParseTimeString("10/15/07 12:45:00 PM", PR_FALSE,
    114                                        &parsed_time);
    115   EXPECT_EQ(PR_SUCCESS, result);
    116   EXPECT_EQ(parsed_time, comparison_time_local_);
    117 }
    118 
    119 TEST_F(PRTimeTest, ParseTimeTest8) {
    120   PRTime parsed_time = 0;
    121   PRStatus result = PR_ParseTimeString("15-OCT-2007 12:45pm", PR_FALSE,
    122                                        &parsed_time);
    123   EXPECT_EQ(PR_SUCCESS, result);
    124   EXPECT_EQ(parsed_time, comparison_time_local_);
    125 }
    126 
    127 TEST_F(PRTimeTest, ParseTimeTest9) {
    128   PRTime parsed_time = 0;
    129   PRStatus result = PR_ParseTimeString("16 Oct 2007 4:45-JST (Tuesday)",
    130                                        PR_FALSE, &parsed_time);
    131   EXPECT_EQ(PR_SUCCESS, result);
    132   EXPECT_EQ(parsed_time, comparison_time_pdt);
    133 }
    134 
    135 // This tests the Time::FromString wrapper over PR_ParseTimeString
    136 TEST_F(PRTimeTest, ParseTimeTest10) {
    137   Time parsed_time;
    138   bool result = Time::FromString(L"15/10/07 12:45", &parsed_time);
    139   EXPECT_TRUE(result);
    140 
    141   time_t computed_time = parsed_time.ToTimeT();
    142   time_t time_to_compare = comparison_time_local_ /
    143                            Time::kMicrosecondsPerSecond;
    144   EXPECT_EQ(computed_time, time_to_compare);
    145 }
    146 
    147 // This tests the Time::FromString wrapper over PR_ParseTimeString
    148 TEST_F(PRTimeTest, ParseTimeTest11) {
    149   Time parsed_time;
    150   bool result = Time::FromString(L"Mon, 15 Oct 2007 19:45:00 GMT",
    151                                  &parsed_time);
    152   EXPECT_TRUE(result);
    153 
    154   time_t computed_time = parsed_time.ToTimeT();
    155   time_t time_to_compare = comparison_time_pdt / Time::kMicrosecondsPerSecond;
    156   EXPECT_EQ(computed_time, time_to_compare);
    157 }
    158 
    159 // Test some of edge cases around epoch, etc.
    160 TEST_F(PRTimeTest, ParseTimeTestEpoch0) {
    161   Time parsed_time;
    162 
    163   // time_t == epoch == 0
    164   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 01:00:00 +0100 1970",
    165                                &parsed_time));
    166   EXPECT_EQ(0, parsed_time.ToTimeT());
    167   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 00:00:00 GMT 1970",
    168                                &parsed_time));
    169   EXPECT_EQ(0, parsed_time.ToTimeT());
    170 }
    171 
    172 TEST_F(PRTimeTest, ParseTimeTestEpoch1) {
    173   Time parsed_time;
    174 
    175   // time_t == 1 second after epoch == 1
    176   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 01:00:01 +0100 1970",
    177                                &parsed_time));
    178   EXPECT_EQ(1, parsed_time.ToTimeT());
    179   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 00:00:01 GMT 1970",
    180                                &parsed_time));
    181   EXPECT_EQ(1, parsed_time.ToTimeT());
    182 }
    183 
    184 TEST_F(PRTimeTest, ParseTimeTestEpoch2) {
    185   Time parsed_time;
    186 
    187   // time_t == 2 seconds after epoch == 2
    188   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 01:00:02 +0100 1970",
    189                                &parsed_time));
    190   EXPECT_EQ(2, parsed_time.ToTimeT());
    191   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 00:00:02 GMT 1970",
    192                                &parsed_time));
    193   EXPECT_EQ(2, parsed_time.ToTimeT());
    194 }
    195 
    196 TEST_F(PRTimeTest, ParseTimeTestEpochNeg1) {
    197   Time parsed_time;
    198 
    199   // time_t == 1 second before epoch == -1
    200   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 00:59:59 +0100 1970",
    201                                &parsed_time));
    202   EXPECT_EQ(-1, parsed_time.ToTimeT());
    203   EXPECT_TRUE(Time::FromString(L"Wed Dec 31 23:59:59 GMT 1969",
    204                                &parsed_time));
    205   EXPECT_EQ(-1, parsed_time.ToTimeT());
    206 }
    207 
    208 // If time_t is 32 bits, a date after year 2038 will overflow time_t and
    209 // cause timegm() to return -1.  The parsed time should not be 1 second
    210 // before epoch.
    211 TEST_F(PRTimeTest, ParseTimeTestEpochNotNeg1) {
    212   Time parsed_time;
    213 
    214   EXPECT_TRUE(Time::FromString(L"Wed Dec 31 23:59:59 GMT 2100",
    215                                &parsed_time));
    216   EXPECT_NE(-1, parsed_time.ToTimeT());
    217 }
    218 
    219 TEST_F(PRTimeTest, ParseTimeTestEpochNeg2) {
    220   Time parsed_time;
    221 
    222   // time_t == 2 seconds before epoch == -2
    223   EXPECT_TRUE(Time::FromString(L"Thu Jan 01 00:59:58 +0100 1970",
    224                                &parsed_time));
    225   EXPECT_EQ(-2, parsed_time.ToTimeT());
    226   EXPECT_TRUE(Time::FromString(L"Wed Dec 31 23:59:58 GMT 1969",
    227                                &parsed_time));
    228   EXPECT_EQ(-2, parsed_time.ToTimeT());
    229 }
    230 
    231 TEST_F(PRTimeTest, ParseTimeTestEpoch1960) {
    232   Time parsed_time;
    233 
    234   // time_t before Epoch, in 1960
    235   EXPECT_TRUE(Time::FromString(L"Wed Jun 29 19:40:01 +0100 1960",
    236                                &parsed_time));
    237   EXPECT_EQ(-299999999, parsed_time.ToTimeT());
    238   EXPECT_TRUE(Time::FromString(L"Wed Jun 29 18:40:01 GMT 1960",
    239                                &parsed_time));
    240   EXPECT_EQ(-299999999, parsed_time.ToTimeT());
    241   EXPECT_TRUE(Time::FromString(L"Wed Jun 29 17:40:01 GMT 1960",
    242                                &parsed_time));
    243   EXPECT_EQ(-300003599, parsed_time.ToTimeT());
    244 }
    245 
    246 TEST_F(PRTimeTest, ParseTimeTestEmpty) {
    247   Time parsed_time;
    248   EXPECT_FALSE(Time::FromString(L"", &parsed_time));
    249 }
    250 
    251 // This test should not crash when compiled with Visual C++ 2005 (see
    252 // http://crbug.com/4387).
    253 TEST_F(PRTimeTest, ParseTimeTestOutOfRange) {
    254   PRTime parsed_time = 0;
    255   // Note the lack of timezone in the time string.  The year has to be 3001.
    256   // The date has to be after 23:59:59, December 31, 3000, US Pacific Time, so
    257   // we use January 2, 3001 to make sure it's after the magic maximum in any
    258   // timezone.
    259   PRStatus result = PR_ParseTimeString("Sun Jan  2 00:00:00 3001",
    260                                        PR_FALSE, &parsed_time);
    261   EXPECT_EQ(PR_SUCCESS, result);
    262 }
    263 
    264 TEST_F(PRTimeTest, ParseTimeTestNotNormalized1) {
    265   PRTime parsed_time = 0;
    266   PRStatus result = PR_ParseTimeString("Mon Oct 15 12:44:60 PDT 2007",
    267                                        PR_FALSE, &parsed_time);
    268   EXPECT_EQ(PR_SUCCESS, result);
    269   EXPECT_EQ(comparison_time_pdt, parsed_time);
    270 }
    271 
    272 TEST_F(PRTimeTest, ParseTimeTestNotNormalized2) {
    273   PRTime parsed_time = 0;
    274   PRStatus result = PR_ParseTimeString("Sun Oct 14 36:45 PDT 2007",
    275                                        PR_FALSE, &parsed_time);
    276   EXPECT_EQ(PR_SUCCESS, result);
    277   EXPECT_EQ(comparison_time_pdt, parsed_time);
    278 }
    279 
    280 }  // namespace
    281