dateparser.h revision 6ded16be15dd865a9b21ea304d5273c8be299c87
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_DATEPARSER_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_DATEPARSER_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scanner.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass DateParser : public AllStatic {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Parse the string as a date. If parsing succeeds, return true after
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // filling out the output array as follows (all integers are Smis):
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [0]: year
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [1]: month (0 = Jan, 1 = Feb, ...)
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [2]: day
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [3]: hour
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [4]: minute
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // [5]: second
476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [6]: millisecond
486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // [7]: UTC offset in seconds, or null value if no timezone specified
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If parsing fails, return false (content of output array is not defined).
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <typename Char>
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static bool Parse(Vector<Char> str, FixedArray* output);
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum {
546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Range testing
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static inline bool Between(int x, int lo, int hi) {
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return static_cast<unsigned>(x - lo) <= static_cast<unsigned>(hi - lo);
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Indicates a missing value.
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  static const int kNone = kMaxInt;
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // InputReader provides basic string parsing and character classification.
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  template <typename Char>
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class InputReader BASE_EMBEDDED {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    explicit InputReader(Vector<Char> s)
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        : index_(0),
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          buffer_(s),
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          has_read_number_(false) {
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Next();
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Advance to the next character of the string.
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void Next() { ch_ = (index_ < buffer_.length()) ? buffer_[index_++] : 0; }
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Read a string of digits as an unsigned number (cap just below kMaxInt).
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int ReadUnsignedNumber() {
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      has_read_number_ = true;
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int n;
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (n = 0; IsAsciiDigit() && n < kMaxInt / 10 - 1; Next()) {
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        n = n * 10 + ch_ - '0';
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return n;
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Read a word (sequence of chars. >= 'A'), fill the given buffer with a
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // lower-case prefix, and pad any remainder of the buffer with zeroes.
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Return word length.
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int ReadWord(uint32_t* prefix, int prefix_size) {
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int len;
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) {
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (len < prefix_size) prefix[len] = GetAsciiAlphaLower();
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      for (int i = len; i < prefix_size; i++) prefix[i] = 0;
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return len;
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The skip methods return whether they actually skipped something.
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Skip(uint32_t c) { return ch_ == c ?  (Next(), true) : false; }
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool SkipWhiteSpace() {
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Scanner::kIsWhiteSpace.get(ch_) ? (Next(), true) : false;
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool SkipParentheses() {
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (ch_ != '(') return false;
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int balance = 0;
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      do {
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        if (ch_ == ')') --balance;
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        else if (ch_ == '(') ++balance;
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Next();
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } while (balance > 0 && ch_);
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return true;
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Character testing/classification. Non-ASCII digits are not supported.
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Is(uint32_t c) const { return ch_ == c; }
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsEnd() const { return ch_ == 0; }
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsAsciiDigit() const { return IsDecimalDigit(ch_); }
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; }
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; }
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Return 1 for '+' and -1 for '-'.
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int GetAsciiSignValue() const { return 44 - static_cast<int>(ch_); }
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Indicates whether any (possibly empty!) numbers have been read.
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool HasReadNumber() const { return has_read_number_; }
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If current character is in 'A'-'Z' or 'a'-'z', return its lower-case.
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Else, return something outside of 'A'-'Z' and 'a'-'z'.
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t GetAsciiAlphaLower() const { return ch_ | 32; }
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int index_;
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Vector<Char> buffer_;
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool has_read_number_;
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t ch_;
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // KeywordTable maps names of months, time zones, am/pm to numbers.
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class KeywordTable : public AllStatic {
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Look up a word in the keyword table and return an index.
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // 'pre' contains a prefix of the word, zero-padded to size kPrefixLength
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // and 'len' is the word length.
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static int Lookup(const uint32_t* pre, int len);
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Get the type of the keyword at index i.
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static KeywordType GetType(int i) {
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return static_cast<KeywordType>(array[i][kTypeOffset]);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Get the value of the keyword at index i.
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static int GetValue(int i) { return array[i][kValueOffset]; }
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kPrefixLength = 3;
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kTypeOffset = kPrefixLength;
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kValueOffset = kTypeOffset + 1;
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kEntrySize = kValueOffset + 1;
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int8_t array[][kEntrySize];
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class TimeZoneComposer BASE_EMBEDDED {
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TimeZoneComposer() : sign_(kNone), hour_(kNone), minute_(kNone) {}
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void Set(int offset_in_hours) {
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      sign_ = offset_in_hours < 0 ? -1 : 1;
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      hour_ = offset_in_hours * sign_;
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      minute_ = 0;
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void SetSign(int sign) { sign_ = sign < 0 ? -1 : 1; }
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void SetAbsoluteHour(int hour) { hour_ = hour; }
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void SetAbsoluteMinute(int minute) { minute_ = minute; }
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsExpecting(int n) const {
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return hour_ != kNone && minute_ == kNone && TimeComposer::IsMinute(n);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsUTC() const { return hour_ == 0 && minute_ == 0; }
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Write(FixedArray* output);
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int sign_;
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int hour_;
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int minute_;
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class TimeComposer BASE_EMBEDDED {
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TimeComposer() : index_(0), hour_offset_(kNone) {}
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsEmpty() const { return index_ == 0; }
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsExpecting(int n) const {
1936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      return (index_ == 1 && IsMinute(n)) ||
1946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block             (index_ == 2 && IsSecond(n)) ||
1956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block             (index_ == 3 && IsMillisecond(n));
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Add(int n) {
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return index_ < kSize ? (comp_[index_++] = n, true) : false;
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool AddFinal(int n) {
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!Add(n)) return false;
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      while (index_ < kSize) comp_[index_++] = 0;
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return true;
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void SetHourOffset(int n) { hour_offset_ = n; }
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Write(FixedArray* output);
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsMinute(int x) { return Between(x, 0, 59); }
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsHour(int x) { return Between(x, 0, 23); }
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsHour12(int x) { return Between(x, 0, 12); }
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsSecond(int x) { return Between(x, 0, 59); }
2136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    static bool IsMillisecond(int x) { return Between(x, 0, 999); }
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    static const int kSize = 4;
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int comp_[kSize];
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int index_;
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int hour_offset_;
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  class DayComposer BASE_EMBEDDED {
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   public:
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DayComposer() : index_(0), named_month_(kNone) {}
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool IsEmpty() const { return index_ == 0; }
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Add(int n) {
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return index_ < kSize ? (comp_[index_++] = n, true) : false;
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    void SetNamedMonth(int n) { named_month_ = n; }
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool Write(FixedArray* output);
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block   private:
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsMonth(int x) { return Between(x, 1, 12); }
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static bool IsDay(int x) { return Between(x, 1, 31); }
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    static const int kSize = 3;
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int comp_[kSize];
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int index_;
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int named_month_;
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_DATEPARSER_H_
245