13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
23ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Redistribution and use in source and binary forms, with or without
33ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// modification, are permitted provided that the following conditions are
43ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// met:
53ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
63ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions of source code must retain the above copyright
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       notice, this list of conditions and the following disclaimer.
83ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Redistributions in binary form must reproduce the above
93ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       copyright notice, this list of conditions and the following
103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       disclaimer in the documentation and/or other materials provided
113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       with the distribution.
123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//     * Neither the name of Google Inc. nor the names of its
133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       contributors may be used to endorse or promote products derived
143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//       from this software without specific prior written permission.
153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//
163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h"
293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochusing namespace v8::internal;
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass DateCacheMock: public DateCache {
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  struct Rule {
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int year, start_month, start_day, end_month, end_day, offset_sec;
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DateCacheMock(int local_offset, Rule* rules, int rules_count)
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      : local_offset_(local_offset), rules_(rules), rules_count_(rules_count) {}
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual int GetDaylightSavingsOffsetFromOS(int64_t time_sec) {
463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int days = DaysFromTime(time_sec * 1000);
473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int time_in_day_sec = TimeInDay(time_sec * 1000, days) / 1000;
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int year, month, day;
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    YearMonthDayFromDays(days, &year, &month, &day);
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Rule* rule = FindRuleFor(year, month, day, time_in_day_sec);
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return rule == NULL ? 0 : rule->offset_sec * 1000;
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  virtual int GetLocalOffsetFromOS() {
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return local_offset_;
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Rule* FindRuleFor(int year, int month, int day, int time_in_day_sec) {
613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Rule* result = NULL;
623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < rules_count_; i++)
633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (Match(&rules_[i], year, month, day, time_in_day_sec)) {
643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        result = &rules_[i];
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return result;
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool Match(Rule* rule, int year, int month, int day, int time_in_day_sec) {
713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->year != 0 && rule->year != year) return false;
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->start_month > month) return false;
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->end_month < month) return false;
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int start_day = ComputeRuleDay(year, rule->start_month, rule->start_day);
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->start_month == month && start_day > day) return false;
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->start_month == month && start_day == day &&
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        2 * 3600 > time_in_day_sec)
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return false;
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int end_day = ComputeRuleDay(year, rule->end_month, rule->end_day);
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->end_month == month && end_day < day) return false;
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (rule->end_month == month && end_day == day &&
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        2 * 3600 <= time_in_day_sec)
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return false;
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ComputeRuleDay(int year, int month, int day) {
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (day != 0) return day;
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int days = DaysFromYearMonth(year, month);
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Find the first Sunday of the month.
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    while (Weekday(days + day) != 6) day++;
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return day + 1;
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int local_offset_;
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Rule* rules_;
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int rules_count_;
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic int64_t TimeFromYearMonthDay(DateCache* date_cache,
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    int year,
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    int month,
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    int day) {
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t result = date_cache->DaysFromYearMonth(year, month);
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return (result + day - 1) * DateCache::kMsPerDay;
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void CheckDST(int64_t time) {
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = CcTest::i_isolate();
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DateCache* date_cache = isolate->date_cache();
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t actual = date_cache->ToLocal(time);
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t expected = time + date_cache->GetLocalOffsetFromOS() +
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     date_cache->GetDaylightSavingsOffsetFromOS(time / 1000);
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CHECK_EQ(actual, expected);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(DaylightSavingsTime) {
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LocalContext context;
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Isolate* isolate = context->GetIsolate();
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::HandleScope scope(isolate);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DateCacheMock::Rule rules[] = {
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {0, 2, 0, 10, 0, 3600},  // DST from March to November in any year.
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {2010, 2, 0, 7, 20, 3600},  // DST from March to August 20 in 2010.
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {2010, 7, 20, 8, 10, 0},  // No DST from August 20 to September 10 in 2010.
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    {2010, 8, 10, 10, 0, 3600},  // DST from September 10 to November in 2010.
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int local_offset_ms = -36000000;  // -10 hours.
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DateCacheMock* date_cache =
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    new DateCacheMock(local_offset_ms, rules, arraysize(rules));
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<Isolate*>(isolate)->set_date_cache(date_cache);
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t start_of_2010 = TimeFromYearMonthDay(date_cache, 2010, 0, 1);
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t start_of_2011 = TimeFromYearMonthDay(date_cache, 2011, 0, 1);
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t august_20 = TimeFromYearMonthDay(date_cache, 2010, 7, 20);
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int64_t september_10 = TimeFromYearMonthDay(date_cache, 2010, 8, 10);
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST((august_20 + september_10) / 2);
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10);
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10 + 2 * 3600);
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10 + 2 * 3600 - 1000);
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20 + 2 * 3600);
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20 + 2 * 3600 - 1000);
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20);
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check each day of 2010.
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int64_t time = start_of_2011 + 2 * 3600;
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       time >= start_of_2010;
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       time -= DateCache::kMsPerDay) {
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CheckDST(time);
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CheckDST(time - 1000);
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CheckDST(time + 1000);
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check one day from 2010 to 2100.
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int year = 2100; year >= 2010; year--) {
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CheckDST(TimeFromYearMonthDay(date_cache, year, 5, 5));
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST((august_20 + september_10) / 2);
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10);
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10 + 2 * 3600);
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(september_10 + 2 * 3600 - 1000);
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20 + 2 * 3600);
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20 + 2 * 3600 - 1000);
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckDST(august_20);
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
169