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