if isNaN Date.parse "2011-01-01T12:00:00-05:00"
  Date.parse = ((parse) ->
    # The date time string format as specified by ES 5.1 section 15.9.1.15.
    pattern = ///^
      (\d{4}) # Year
      (?:-(\d{2}) # Optional month
      (?:-(\d{2}) # Optional date
      (?: # Optional time component
        T(\d{2}) # Hours
        :(\d{2}) # Minutes
        (?:
          :(\d{2}) # Optional seconds
          (?:\.(\d{3}))? # Optional milliseconds
        )?
      (?: # Optional time zone offset component
        Z| # UTC specifier
        (?: # Offset specifier
          ([-+]) # Direction of offset
          (\d{2}) # Hour offset
          :(\d{2}) # Minute offset
        )
      )?
      )?)?)?
    $///
    (value) ->
      if match = pattern.exec value
        [_, year, month, date, hours, minutes, seconds, milliseconds, direction, hourOffset, minuteOffset] = value
        # Parse the specified UTC offset.
        if direction
          # Detect invalid hour and minute offset values.
          return 0 / 0 if hourOffset > 23 or minuteOffset > 59
          # Express the specified time zone offset in minutes. The offset is negative for time
          # zones west of UTC, and positive for those east of UTC.
          offset = (hourOffset * 60 + (+minuteOffset)) * 6e4 * (if direction is "+" then -1 else 1)
        # Compute a new UTC date value.
        result = Date.UTC year, (month or 1) - 1, date or 1, hours or 0, minutes or 0, seconds or 0, milliseconds or 0
        # Apply the offset to the computed date.
        result + offset
      parse value
  )(Date.parse)

if typeof Date::toISOString isnt "function"
  Date::toISOString = ->
    throw new RangeError if not isFinite @
    result = [@getUTCFullYear(), @getUTCMonth() + 1, @getUTCDate(), @getUTCHours(), @getUTCMinutes(), @getUTCSeconds()]
    # Months, dates, hours, minutes, and seconds should have two digits.
    (result[index] = "0" + element) for element, index in result when element < 10
    # Milliseconds should have three digits.
    "#{result.slice(0, 3).join("-")}T#{result.slice(3).join(":")}.#{("000" + @getUTCMilliseconds()).slice(-3)}Z"

  Date::toJSON = ->
    if isFinite @ then @toISOString() else null