github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/builtin_date.go (about)

     1  package goja
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"time"
     7  )
     8  
     9  func (r *Runtime) makeDate(args []Value, utc bool) (t time.Time, valid bool) {
    10  	switch {
    11  	case len(args) >= 2:
    12  		t = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.Local)
    13  		t, valid = _dateSetYear(t, FunctionCall{Arguments: args}, 0, utc)
    14  	case len(args) == 0:
    15  		t = r.now()
    16  		valid = true
    17  	default: // one argument
    18  		if o, ok := args[0].(*Object); ok {
    19  			if d, ok := o.self.(*dateObject); ok {
    20  				t = d.time()
    21  				valid = true
    22  			}
    23  		}
    24  		if !valid {
    25  			pv := toPrimitive(args[0])
    26  			if val, ok := pv.(String); ok {
    27  				return dateParse(val.String())
    28  			}
    29  			pv = pv.ToNumber()
    30  			var n int64
    31  			if i, ok := pv.(valueInt); ok {
    32  				n = int64(i)
    33  			} else if f, ok := pv.(valueFloat); ok {
    34  				f := float64(f)
    35  				if math.IsNaN(f) || math.IsInf(f, 0) {
    36  					return
    37  				}
    38  				if math.Abs(f) > maxTime {
    39  					return
    40  				}
    41  				n = int64(f)
    42  			} else {
    43  				n = pv.ToInteger()
    44  			}
    45  			t = timeFromMsec(n)
    46  			valid = true
    47  		}
    48  	}
    49  	if valid {
    50  		msec := t.Unix()*1000 + int64(t.Nanosecond()/1e6)
    51  		if msec < 0 {
    52  			msec = -msec
    53  		}
    54  		if msec > maxTime {
    55  			valid = false
    56  		}
    57  	}
    58  	return
    59  }
    60  
    61  func (r *Runtime) newDateTime(args []Value, proto *Object) *Object {
    62  	t, isSet := r.makeDate(args, false)
    63  	return r.newDateObject(t, isSet, proto)
    64  }
    65  
    66  func (r *Runtime) builtin_newDate(args []Value, proto *Object) *Object {
    67  	return r.newDateTime(args, proto)
    68  }
    69  
    70  func (r *Runtime) builtin_date(FunctionCall) Value {
    71  	return asciiString(dateFormat(r.now()))
    72  }
    73  
    74  func (r *Runtime) date_parse(call FunctionCall) Value {
    75  	t, set := dateParse(call.Argument(0).toString().String())
    76  	if set {
    77  		return intToValue(timeToMsec(t))
    78  	}
    79  	return _NaN
    80  }
    81  
    82  func (r *Runtime) date_UTC(call FunctionCall) Value {
    83  	var args []Value
    84  	if len(call.Arguments) < 2 {
    85  		args = []Value{call.Argument(0), _positiveZero}
    86  	} else {
    87  		args = call.Arguments
    88  	}
    89  	t, valid := r.makeDate(args, true)
    90  	if !valid {
    91  		return _NaN
    92  	}
    93  	return intToValue(timeToMsec(t))
    94  }
    95  
    96  func (r *Runtime) date_now(FunctionCall) Value {
    97  	return intToValue(timeToMsec(r.now()))
    98  }
    99  
   100  func (r *Runtime) dateproto_toString(call FunctionCall) Value {
   101  	obj := r.toObject(call.This)
   102  	if d, ok := obj.self.(*dateObject); ok {
   103  		if d.isSet() {
   104  			return asciiString(d.time().Format(dateTimeLayout))
   105  		} else {
   106  			return stringInvalidDate
   107  		}
   108  	}
   109  	panic(r.NewTypeError("Method Date.prototype.toString is called on incompatible receiver"))
   110  }
   111  
   112  func (r *Runtime) dateproto_toUTCString(call FunctionCall) Value {
   113  	obj := r.toObject(call.This)
   114  	if d, ok := obj.self.(*dateObject); ok {
   115  		if d.isSet() {
   116  			return asciiString(d.timeUTC().Format(utcDateTimeLayout))
   117  		} else {
   118  			return stringInvalidDate
   119  		}
   120  	}
   121  	panic(r.NewTypeError("Method Date.prototype.toUTCString is called on incompatible receiver"))
   122  }
   123  
   124  func (r *Runtime) dateproto_toISOString(call FunctionCall) Value {
   125  	obj := r.toObject(call.This)
   126  	if d, ok := obj.self.(*dateObject); ok {
   127  		if d.isSet() {
   128  			utc := d.timeUTC()
   129  			year := utc.Year()
   130  			if year >= -9999 && year <= 9999 {
   131  				return asciiString(utc.Format(isoDateTimeLayout))
   132  			}
   133  			// extended year
   134  			return asciiString(fmt.Sprintf("%+06d-", year) + utc.Format(isoDateTimeLayout[5:]))
   135  		} else {
   136  			panic(r.newError(r.global.RangeError, "Invalid time value"))
   137  		}
   138  	}
   139  	panic(r.NewTypeError("Method Date.prototype.toISOString is called on incompatible receiver"))
   140  }
   141  
   142  func (r *Runtime) dateproto_toJSON(call FunctionCall) Value {
   143  	obj := call.This.ToObject(r)
   144  	tv := obj.toPrimitiveNumber()
   145  	if f, ok := tv.(valueFloat); ok {
   146  		f := float64(f)
   147  		if math.IsNaN(f) || math.IsInf(f, 0) {
   148  			return _null
   149  		}
   150  	}
   151  
   152  	if toISO, ok := obj.self.getStr("toISOString", nil).(*Object); ok {
   153  		if toISO, ok := toISO.self.assertCallable(); ok {
   154  			return toISO(FunctionCall{
   155  				This: obj,
   156  			})
   157  		}
   158  	}
   159  
   160  	panic(r.NewTypeError("toISOString is not a function"))
   161  }
   162  
   163  func (r *Runtime) dateproto_toPrimitive(call FunctionCall) Value {
   164  	o := r.toObject(call.This)
   165  	arg := call.Argument(0)
   166  
   167  	if asciiString("string").StrictEquals(arg) || asciiString("default").StrictEquals(arg) {
   168  		return o.ordinaryToPrimitiveString()
   169  	}
   170  	if asciiString("number").StrictEquals(arg) {
   171  		return o.ordinaryToPrimitiveNumber()
   172  	}
   173  	panic(r.NewTypeError("Invalid hint: %s", arg))
   174  }
   175  
   176  func (r *Runtime) dateproto_toDateString(call FunctionCall) Value {
   177  	obj := r.toObject(call.This)
   178  	if d, ok := obj.self.(*dateObject); ok {
   179  		if d.isSet() {
   180  			return asciiString(d.time().Format(dateLayout))
   181  		} else {
   182  			return stringInvalidDate
   183  		}
   184  	}
   185  	panic(r.NewTypeError("Method Date.prototype.toDateString is called on incompatible receiver"))
   186  }
   187  
   188  func (r *Runtime) dateproto_toTimeString(call FunctionCall) Value {
   189  	obj := r.toObject(call.This)
   190  	if d, ok := obj.self.(*dateObject); ok {
   191  		if d.isSet() {
   192  			return asciiString(d.time().Format(timeLayout))
   193  		} else {
   194  			return stringInvalidDate
   195  		}
   196  	}
   197  	panic(r.NewTypeError("Method Date.prototype.toTimeString is called on incompatible receiver"))
   198  }
   199  
   200  func (r *Runtime) dateproto_toLocaleString(call FunctionCall) Value {
   201  	obj := r.toObject(call.This)
   202  	if d, ok := obj.self.(*dateObject); ok {
   203  		if d.isSet() {
   204  			return asciiString(d.time().Format(datetimeLayout_en_GB))
   205  		} else {
   206  			return stringInvalidDate
   207  		}
   208  	}
   209  	panic(r.NewTypeError("Method Date.prototype.toLocaleString is called on incompatible receiver"))
   210  }
   211  
   212  func (r *Runtime) dateproto_toLocaleDateString(call FunctionCall) Value {
   213  	obj := r.toObject(call.This)
   214  	if d, ok := obj.self.(*dateObject); ok {
   215  		if d.isSet() {
   216  			return asciiString(d.time().Format(dateLayout_en_GB))
   217  		} else {
   218  			return stringInvalidDate
   219  		}
   220  	}
   221  	panic(r.NewTypeError("Method Date.prototype.toLocaleDateString is called on incompatible receiver"))
   222  }
   223  
   224  func (r *Runtime) dateproto_toLocaleTimeString(call FunctionCall) Value {
   225  	obj := r.toObject(call.This)
   226  	if d, ok := obj.self.(*dateObject); ok {
   227  		if d.isSet() {
   228  			return asciiString(d.time().Format(timeLayout_en_GB))
   229  		} else {
   230  			return stringInvalidDate
   231  		}
   232  	}
   233  	panic(r.NewTypeError("Method Date.prototype.toLocaleTimeString is called on incompatible receiver"))
   234  }
   235  
   236  func (r *Runtime) dateproto_valueOf(call FunctionCall) Value {
   237  	obj := r.toObject(call.This)
   238  	if d, ok := obj.self.(*dateObject); ok {
   239  		if d.isSet() {
   240  			return intToValue(d.msec)
   241  		} else {
   242  			return _NaN
   243  		}
   244  	}
   245  	panic(r.NewTypeError("Method Date.prototype.valueOf is called on incompatible receiver"))
   246  }
   247  
   248  func (r *Runtime) dateproto_getTime(call FunctionCall) Value {
   249  	obj := r.toObject(call.This)
   250  	if d, ok := obj.self.(*dateObject); ok {
   251  		if d.isSet() {
   252  			return intToValue(d.msec)
   253  		} else {
   254  			return _NaN
   255  		}
   256  	}
   257  	panic(r.NewTypeError("Method Date.prototype.getTime is called on incompatible receiver"))
   258  }
   259  
   260  func (r *Runtime) dateproto_getFullYear(call FunctionCall) Value {
   261  	obj := r.toObject(call.This)
   262  	if d, ok := obj.self.(*dateObject); ok {
   263  		if d.isSet() {
   264  			return intToValue(int64(d.time().Year()))
   265  		} else {
   266  			return _NaN
   267  		}
   268  	}
   269  	panic(r.NewTypeError("Method Date.prototype.getFullYear is called on incompatible receiver"))
   270  }
   271  
   272  func (r *Runtime) dateproto_getUTCFullYear(call FunctionCall) Value {
   273  	obj := r.toObject(call.This)
   274  	if d, ok := obj.self.(*dateObject); ok {
   275  		if d.isSet() {
   276  			return intToValue(int64(d.timeUTC().Year()))
   277  		} else {
   278  			return _NaN
   279  		}
   280  	}
   281  	panic(r.NewTypeError("Method Date.prototype.getUTCFullYear is called on incompatible receiver"))
   282  }
   283  
   284  func (r *Runtime) dateproto_getMonth(call FunctionCall) Value {
   285  	obj := r.toObject(call.This)
   286  	if d, ok := obj.self.(*dateObject); ok {
   287  		if d.isSet() {
   288  			return intToValue(int64(d.time().Month()) - 1)
   289  		} else {
   290  			return _NaN
   291  		}
   292  	}
   293  	panic(r.NewTypeError("Method Date.prototype.getMonth is called on incompatible receiver"))
   294  }
   295  
   296  func (r *Runtime) dateproto_getUTCMonth(call FunctionCall) Value {
   297  	obj := r.toObject(call.This)
   298  	if d, ok := obj.self.(*dateObject); ok {
   299  		if d.isSet() {
   300  			return intToValue(int64(d.timeUTC().Month()) - 1)
   301  		} else {
   302  			return _NaN
   303  		}
   304  	}
   305  	panic(r.NewTypeError("Method Date.prototype.getUTCMonth is called on incompatible receiver"))
   306  }
   307  
   308  func (r *Runtime) dateproto_getHours(call FunctionCall) Value {
   309  	obj := r.toObject(call.This)
   310  	if d, ok := obj.self.(*dateObject); ok {
   311  		if d.isSet() {
   312  			return intToValue(int64(d.time().Hour()))
   313  		} else {
   314  			return _NaN
   315  		}
   316  	}
   317  	panic(r.NewTypeError("Method Date.prototype.getHours is called on incompatible receiver"))
   318  }
   319  
   320  func (r *Runtime) dateproto_getUTCHours(call FunctionCall) Value {
   321  	obj := r.toObject(call.This)
   322  	if d, ok := obj.self.(*dateObject); ok {
   323  		if d.isSet() {
   324  			return intToValue(int64(d.timeUTC().Hour()))
   325  		} else {
   326  			return _NaN
   327  		}
   328  	}
   329  	panic(r.NewTypeError("Method Date.prototype.getUTCHours is called on incompatible receiver"))
   330  }
   331  
   332  func (r *Runtime) dateproto_getDate(call FunctionCall) Value {
   333  	obj := r.toObject(call.This)
   334  	if d, ok := obj.self.(*dateObject); ok {
   335  		if d.isSet() {
   336  			return intToValue(int64(d.time().Day()))
   337  		} else {
   338  			return _NaN
   339  		}
   340  	}
   341  	panic(r.NewTypeError("Method Date.prototype.getDate is called on incompatible receiver"))
   342  }
   343  
   344  func (r *Runtime) dateproto_getUTCDate(call FunctionCall) Value {
   345  	obj := r.toObject(call.This)
   346  	if d, ok := obj.self.(*dateObject); ok {
   347  		if d.isSet() {
   348  			return intToValue(int64(d.timeUTC().Day()))
   349  		} else {
   350  			return _NaN
   351  		}
   352  	}
   353  	panic(r.NewTypeError("Method Date.prototype.getUTCDate is called on incompatible receiver"))
   354  }
   355  
   356  func (r *Runtime) dateproto_getDay(call FunctionCall) Value {
   357  	obj := r.toObject(call.This)
   358  	if d, ok := obj.self.(*dateObject); ok {
   359  		if d.isSet() {
   360  			return intToValue(int64(d.time().Weekday()))
   361  		} else {
   362  			return _NaN
   363  		}
   364  	}
   365  	panic(r.NewTypeError("Method Date.prototype.getDay is called on incompatible receiver"))
   366  }
   367  
   368  func (r *Runtime) dateproto_getUTCDay(call FunctionCall) Value {
   369  	obj := r.toObject(call.This)
   370  	if d, ok := obj.self.(*dateObject); ok {
   371  		if d.isSet() {
   372  			return intToValue(int64(d.timeUTC().Weekday()))
   373  		} else {
   374  			return _NaN
   375  		}
   376  	}
   377  	panic(r.NewTypeError("Method Date.prototype.getUTCDay is called on incompatible receiver"))
   378  }
   379  
   380  func (r *Runtime) dateproto_getMinutes(call FunctionCall) Value {
   381  	obj := r.toObject(call.This)
   382  	if d, ok := obj.self.(*dateObject); ok {
   383  		if d.isSet() {
   384  			return intToValue(int64(d.time().Minute()))
   385  		} else {
   386  			return _NaN
   387  		}
   388  	}
   389  	panic(r.NewTypeError("Method Date.prototype.getMinutes is called on incompatible receiver"))
   390  }
   391  
   392  func (r *Runtime) dateproto_getUTCMinutes(call FunctionCall) Value {
   393  	obj := r.toObject(call.This)
   394  	if d, ok := obj.self.(*dateObject); ok {
   395  		if d.isSet() {
   396  			return intToValue(int64(d.timeUTC().Minute()))
   397  		} else {
   398  			return _NaN
   399  		}
   400  	}
   401  	panic(r.NewTypeError("Method Date.prototype.getUTCMinutes is called on incompatible receiver"))
   402  }
   403  
   404  func (r *Runtime) dateproto_getSeconds(call FunctionCall) Value {
   405  	obj := r.toObject(call.This)
   406  	if d, ok := obj.self.(*dateObject); ok {
   407  		if d.isSet() {
   408  			return intToValue(int64(d.time().Second()))
   409  		} else {
   410  			return _NaN
   411  		}
   412  	}
   413  	panic(r.NewTypeError("Method Date.prototype.getSeconds is called on incompatible receiver"))
   414  }
   415  
   416  func (r *Runtime) dateproto_getUTCSeconds(call FunctionCall) Value {
   417  	obj := r.toObject(call.This)
   418  	if d, ok := obj.self.(*dateObject); ok {
   419  		if d.isSet() {
   420  			return intToValue(int64(d.timeUTC().Second()))
   421  		} else {
   422  			return _NaN
   423  		}
   424  	}
   425  	panic(r.NewTypeError("Method Date.prototype.getUTCSeconds is called on incompatible receiver"))
   426  }
   427  
   428  func (r *Runtime) dateproto_getMilliseconds(call FunctionCall) Value {
   429  	obj := r.toObject(call.This)
   430  	if d, ok := obj.self.(*dateObject); ok {
   431  		if d.isSet() {
   432  			return intToValue(int64(d.time().Nanosecond() / 1e6))
   433  		} else {
   434  			return _NaN
   435  		}
   436  	}
   437  	panic(r.NewTypeError("Method Date.prototype.getMilliseconds is called on incompatible receiver"))
   438  }
   439  
   440  func (r *Runtime) dateproto_getUTCMilliseconds(call FunctionCall) Value {
   441  	obj := r.toObject(call.This)
   442  	if d, ok := obj.self.(*dateObject); ok {
   443  		if d.isSet() {
   444  			return intToValue(int64(d.timeUTC().Nanosecond() / 1e6))
   445  		} else {
   446  			return _NaN
   447  		}
   448  	}
   449  	panic(r.NewTypeError("Method Date.prototype.getUTCMilliseconds is called on incompatible receiver"))
   450  }
   451  
   452  func (r *Runtime) dateproto_getTimezoneOffset(call FunctionCall) Value {
   453  	obj := r.toObject(call.This)
   454  	if d, ok := obj.self.(*dateObject); ok {
   455  		if d.isSet() {
   456  			_, offset := d.time().Zone()
   457  			return floatToValue(float64(-offset) / 60)
   458  		} else {
   459  			return _NaN
   460  		}
   461  	}
   462  	panic(r.NewTypeError("Method Date.prototype.getTimezoneOffset is called on incompatible receiver"))
   463  }
   464  
   465  func (r *Runtime) dateproto_setTime(call FunctionCall) Value {
   466  	obj := r.toObject(call.This)
   467  	if d, ok := obj.self.(*dateObject); ok {
   468  		n := call.Argument(0).ToNumber()
   469  		if IsNaN(n) {
   470  			d.unset()
   471  			return _NaN
   472  		}
   473  		return d.setTimeMs(n.ToInteger())
   474  	}
   475  	panic(r.NewTypeError("Method Date.prototype.setTime is called on incompatible receiver"))
   476  }
   477  
   478  // _norm returns nhi, nlo such that
   479  //
   480  //	hi * base + lo == nhi * base + nlo
   481  //	0 <= nlo < base
   482  func _norm(hi, lo, base int64) (nhi, nlo int64, ok bool) {
   483  	if lo < 0 {
   484  		if hi == math.MinInt64 && lo <= -base {
   485  			// underflow
   486  			ok = false
   487  			return
   488  		}
   489  		n := (-lo-1)/base + 1
   490  		hi -= n
   491  		lo += n * base
   492  	}
   493  	if lo >= base {
   494  		if hi == math.MaxInt64 {
   495  			// overflow
   496  			ok = false
   497  			return
   498  		}
   499  		n := lo / base
   500  		hi += n
   501  		lo -= n * base
   502  	}
   503  	return hi, lo, true
   504  }
   505  
   506  func mkTime(year, m, day, hour, min, sec, nsec int64, loc *time.Location) (t time.Time, ok bool) {
   507  	year, m, ok = _norm(year, m, 12)
   508  	if !ok {
   509  		return
   510  	}
   511  
   512  	// Normalise nsec, sec, min, hour, overflowing into day.
   513  	sec, nsec, ok = _norm(sec, nsec, 1e9)
   514  	if !ok {
   515  		return
   516  	}
   517  	min, sec, ok = _norm(min, sec, 60)
   518  	if !ok {
   519  		return
   520  	}
   521  	hour, min, ok = _norm(hour, min, 60)
   522  	if !ok {
   523  		return
   524  	}
   525  	day, hour, ok = _norm(day, hour, 24)
   526  	if !ok {
   527  		return
   528  	}
   529  	if year > math.MaxInt32 || year < math.MinInt32 ||
   530  		day > math.MaxInt32 || day < math.MinInt32 ||
   531  		m >= math.MaxInt32 || m < math.MinInt32-1 {
   532  		return time.Time{}, false
   533  	}
   534  	month := time.Month(m) + 1
   535  	return time.Date(int(year), month, int(day), int(hour), int(min), int(sec), int(nsec), loc), true
   536  }
   537  
   538  func _intArg(call FunctionCall, argNum int) (int64, bool) {
   539  	n := call.Argument(argNum).ToNumber()
   540  	if IsNaN(n) {
   541  		return 0, false
   542  	}
   543  	return n.ToInteger(), true
   544  }
   545  
   546  func _dateSetYear(t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   547  	var year int64
   548  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   549  		var ok bool
   550  		year, ok = _intArg(call, argNum)
   551  		if !ok {
   552  			return time.Time{}, false
   553  		}
   554  		if year >= 0 && year <= 99 {
   555  			year += 1900
   556  		}
   557  	} else {
   558  		year = int64(t.Year())
   559  	}
   560  
   561  	return _dateSetMonth(year, t, call, argNum+1, utc)
   562  }
   563  
   564  func _dateSetFullYear(t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   565  	var year int64
   566  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   567  		var ok bool
   568  		year, ok = _intArg(call, argNum)
   569  		if !ok {
   570  			return time.Time{}, false
   571  		}
   572  	} else {
   573  		year = int64(t.Year())
   574  	}
   575  	return _dateSetMonth(year, t, call, argNum+1, utc)
   576  }
   577  
   578  func _dateSetMonth(year int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   579  	var mon int64
   580  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   581  		var ok bool
   582  		mon, ok = _intArg(call, argNum)
   583  		if !ok {
   584  			return time.Time{}, false
   585  		}
   586  	} else {
   587  		mon = int64(t.Month()) - 1
   588  	}
   589  
   590  	return _dateSetDay(year, mon, t, call, argNum+1, utc)
   591  }
   592  
   593  func _dateSetDay(year, mon int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   594  	var day int64
   595  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   596  		var ok bool
   597  		day, ok = _intArg(call, argNum)
   598  		if !ok {
   599  			return time.Time{}, false
   600  		}
   601  	} else {
   602  		day = int64(t.Day())
   603  	}
   604  
   605  	return _dateSetHours(year, mon, day, t, call, argNum+1, utc)
   606  }
   607  
   608  func _dateSetHours(year, mon, day int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   609  	var hours int64
   610  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   611  		var ok bool
   612  		hours, ok = _intArg(call, argNum)
   613  		if !ok {
   614  			return time.Time{}, false
   615  		}
   616  	} else {
   617  		hours = int64(t.Hour())
   618  	}
   619  	return _dateSetMinutes(year, mon, day, hours, t, call, argNum+1, utc)
   620  }
   621  
   622  func _dateSetMinutes(year, mon, day, hours int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   623  	var min int64
   624  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   625  		var ok bool
   626  		min, ok = _intArg(call, argNum)
   627  		if !ok {
   628  			return time.Time{}, false
   629  		}
   630  	} else {
   631  		min = int64(t.Minute())
   632  	}
   633  	return _dateSetSeconds(year, mon, day, hours, min, t, call, argNum+1, utc)
   634  }
   635  
   636  func _dateSetSeconds(year, mon, day, hours, min int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   637  	var sec int64
   638  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   639  		var ok bool
   640  		sec, ok = _intArg(call, argNum)
   641  		if !ok {
   642  			return time.Time{}, false
   643  		}
   644  	} else {
   645  		sec = int64(t.Second())
   646  	}
   647  	return _dateSetMilliseconds(year, mon, day, hours, min, sec, t, call, argNum+1, utc)
   648  }
   649  
   650  func _dateSetMilliseconds(year, mon, day, hours, min, sec int64, t time.Time, call FunctionCall, argNum int, utc bool) (time.Time, bool) {
   651  	var msec int64
   652  	if argNum == 0 || argNum > 0 && argNum < len(call.Arguments) {
   653  		var ok bool
   654  		msec, ok = _intArg(call, argNum)
   655  		if !ok {
   656  			return time.Time{}, false
   657  		}
   658  	} else {
   659  		msec = int64(t.Nanosecond() / 1e6)
   660  	}
   661  	var ok bool
   662  	sec, msec, ok = _norm(sec, msec, 1e3)
   663  	if !ok {
   664  		return time.Time{}, false
   665  	}
   666  
   667  	var loc *time.Location
   668  	if utc {
   669  		loc = time.UTC
   670  	} else {
   671  		loc = time.Local
   672  	}
   673  	r, ok := mkTime(year, mon, day, hours, min, sec, msec*1e6, loc)
   674  	if !ok {
   675  		return time.Time{}, false
   676  	}
   677  	if utc {
   678  		return r.In(time.Local), true
   679  	}
   680  	return r, true
   681  }
   682  
   683  func (r *Runtime) dateproto_setMilliseconds(call FunctionCall) Value {
   684  	obj := r.toObject(call.This)
   685  	if d, ok := obj.self.(*dateObject); ok {
   686  		n := call.Argument(0).ToNumber()
   687  		if IsNaN(n) {
   688  			d.unset()
   689  			return _NaN
   690  		}
   691  		msec := n.ToInteger()
   692  		sec := d.msec / 1e3
   693  		var ok bool
   694  		sec, msec, ok = _norm(sec, msec, 1e3)
   695  		if !ok {
   696  			d.unset()
   697  			return _NaN
   698  		}
   699  		if d.isSet() {
   700  			return d.setTimeMs(sec*1e3 + msec)
   701  		} else {
   702  			return _NaN
   703  		}
   704  	}
   705  	panic(r.NewTypeError("Method Date.prototype.setMilliseconds is called on incompatible receiver"))
   706  }
   707  
   708  func (r *Runtime) dateproto_setUTCMilliseconds(call FunctionCall) Value {
   709  	obj := r.toObject(call.This)
   710  	if d, ok := obj.self.(*dateObject); ok {
   711  		n := call.Argument(0).ToNumber()
   712  		if IsNaN(n) {
   713  			d.unset()
   714  			return _NaN
   715  		}
   716  		msec := n.ToInteger()
   717  		sec := d.msec / 1e3
   718  		var ok bool
   719  		sec, msec, ok = _norm(sec, msec, 1e3)
   720  		if !ok {
   721  			d.unset()
   722  			return _NaN
   723  		}
   724  		if d.isSet() {
   725  			return d.setTimeMs(sec*1e3 + msec)
   726  		} else {
   727  			return _NaN
   728  		}
   729  	}
   730  	panic(r.NewTypeError("Method Date.prototype.setUTCMilliseconds is called on incompatible receiver"))
   731  }
   732  
   733  func (r *Runtime) dateproto_setSeconds(call FunctionCall) Value {
   734  	obj := r.toObject(call.This)
   735  	if d, ok := obj.self.(*dateObject); ok {
   736  		t, ok := _dateSetFullYear(d.time(), call, -5, false)
   737  		if !ok {
   738  			d.unset()
   739  			return _NaN
   740  		}
   741  		if d.isSet() {
   742  			return d.setTimeMs(timeToMsec(t))
   743  		} else {
   744  			return _NaN
   745  		}
   746  	}
   747  	panic(r.NewTypeError("Method Date.prototype.setSeconds is called on incompatible receiver"))
   748  }
   749  
   750  func (r *Runtime) dateproto_setUTCSeconds(call FunctionCall) Value {
   751  	obj := r.toObject(call.This)
   752  	if d, ok := obj.self.(*dateObject); ok {
   753  		t, ok := _dateSetFullYear(d.timeUTC(), call, -5, true)
   754  		if !ok {
   755  			d.unset()
   756  			return _NaN
   757  		}
   758  		if d.isSet() {
   759  			return d.setTimeMs(timeToMsec(t))
   760  		} else {
   761  			return _NaN
   762  		}
   763  	}
   764  	panic(r.NewTypeError("Method Date.prototype.setUTCSeconds is called on incompatible receiver"))
   765  }
   766  
   767  func (r *Runtime) dateproto_setMinutes(call FunctionCall) Value {
   768  	obj := r.toObject(call.This)
   769  	if d, ok := obj.self.(*dateObject); ok {
   770  		t, ok := _dateSetFullYear(d.time(), call, -4, false)
   771  		if !ok {
   772  			d.unset()
   773  			return _NaN
   774  		}
   775  		if d.isSet() {
   776  			return d.setTimeMs(timeToMsec(t))
   777  		} else {
   778  			return _NaN
   779  		}
   780  	}
   781  	panic(r.NewTypeError("Method Date.prototype.setMinutes is called on incompatible receiver"))
   782  }
   783  
   784  func (r *Runtime) dateproto_setUTCMinutes(call FunctionCall) Value {
   785  	obj := r.toObject(call.This)
   786  	if d, ok := obj.self.(*dateObject); ok {
   787  		t, ok := _dateSetFullYear(d.timeUTC(), call, -4, true)
   788  		if !ok {
   789  			d.unset()
   790  			return _NaN
   791  		}
   792  		if d.isSet() {
   793  			return d.setTimeMs(timeToMsec(t))
   794  		} else {
   795  			return _NaN
   796  		}
   797  	}
   798  	panic(r.NewTypeError("Method Date.prototype.setUTCMinutes is called on incompatible receiver"))
   799  }
   800  
   801  func (r *Runtime) dateproto_setHours(call FunctionCall) Value {
   802  	obj := r.toObject(call.This)
   803  	if d, ok := obj.self.(*dateObject); ok {
   804  		t, ok := _dateSetFullYear(d.time(), call, -3, false)
   805  		if !ok {
   806  			d.unset()
   807  			return _NaN
   808  		}
   809  		if d.isSet() {
   810  			return d.setTimeMs(timeToMsec(t))
   811  		} else {
   812  			return _NaN
   813  		}
   814  	}
   815  	panic(r.NewTypeError("Method Date.prototype.setHours is called on incompatible receiver"))
   816  }
   817  
   818  func (r *Runtime) dateproto_setUTCHours(call FunctionCall) Value {
   819  	obj := r.toObject(call.This)
   820  	if d, ok := obj.self.(*dateObject); ok {
   821  		t, ok := _dateSetFullYear(d.timeUTC(), call, -3, true)
   822  		if !ok {
   823  			d.unset()
   824  			return _NaN
   825  		}
   826  		if d.isSet() {
   827  			return d.setTimeMs(timeToMsec(t))
   828  		} else {
   829  			return _NaN
   830  		}
   831  	}
   832  	panic(r.NewTypeError("Method Date.prototype.setUTCHours is called on incompatible receiver"))
   833  }
   834  
   835  func (r *Runtime) dateproto_setDate(call FunctionCall) Value {
   836  	obj := r.toObject(call.This)
   837  	if d, ok := obj.self.(*dateObject); ok {
   838  		t, ok := _dateSetFullYear(d.time(), limitCallArgs(call, 1), -2, false)
   839  		if !ok {
   840  			d.unset()
   841  			return _NaN
   842  		}
   843  		if d.isSet() {
   844  			return d.setTimeMs(timeToMsec(t))
   845  		} else {
   846  			return _NaN
   847  		}
   848  	}
   849  	panic(r.NewTypeError("Method Date.prototype.setDate is called on incompatible receiver"))
   850  }
   851  
   852  func (r *Runtime) dateproto_setUTCDate(call FunctionCall) Value {
   853  	obj := r.toObject(call.This)
   854  	if d, ok := obj.self.(*dateObject); ok {
   855  		t, ok := _dateSetFullYear(d.timeUTC(), limitCallArgs(call, 1), -2, true)
   856  		if !ok {
   857  			d.unset()
   858  			return _NaN
   859  		}
   860  		if d.isSet() {
   861  			return d.setTimeMs(timeToMsec(t))
   862  		} else {
   863  			return _NaN
   864  		}
   865  	}
   866  	panic(r.NewTypeError("Method Date.prototype.setUTCDate is called on incompatible receiver"))
   867  }
   868  
   869  func (r *Runtime) dateproto_setMonth(call FunctionCall) Value {
   870  	obj := r.toObject(call.This)
   871  	if d, ok := obj.self.(*dateObject); ok {
   872  		t, ok := _dateSetFullYear(d.time(), limitCallArgs(call, 2), -1, false)
   873  		if !ok {
   874  			d.unset()
   875  			return _NaN
   876  		}
   877  		if d.isSet() {
   878  			return d.setTimeMs(timeToMsec(t))
   879  		} else {
   880  			return _NaN
   881  		}
   882  	}
   883  	panic(r.NewTypeError("Method Date.prototype.setMonth is called on incompatible receiver"))
   884  }
   885  
   886  func (r *Runtime) dateproto_setUTCMonth(call FunctionCall) Value {
   887  	obj := r.toObject(call.This)
   888  	if d, ok := obj.self.(*dateObject); ok {
   889  		t, ok := _dateSetFullYear(d.timeUTC(), limitCallArgs(call, 2), -1, true)
   890  		if !ok {
   891  			d.unset()
   892  			return _NaN
   893  		}
   894  		if d.isSet() {
   895  			return d.setTimeMs(timeToMsec(t))
   896  		} else {
   897  			return _NaN
   898  		}
   899  	}
   900  	panic(r.NewTypeError("Method Date.prototype.setUTCMonth is called on incompatible receiver"))
   901  }
   902  
   903  func (r *Runtime) dateproto_setFullYear(call FunctionCall) Value {
   904  	obj := r.toObject(call.This)
   905  	if d, ok := obj.self.(*dateObject); ok {
   906  		var t time.Time
   907  		if d.isSet() {
   908  			t = d.time()
   909  		} else {
   910  			t = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.Local)
   911  		}
   912  		t, ok := _dateSetFullYear(t, limitCallArgs(call, 3), 0, false)
   913  		if !ok {
   914  			d.unset()
   915  			return _NaN
   916  		}
   917  		return d.setTimeMs(timeToMsec(t))
   918  	}
   919  	panic(r.NewTypeError("Method Date.prototype.setFullYear is called on incompatible receiver"))
   920  }
   921  
   922  func (r *Runtime) dateproto_setUTCFullYear(call FunctionCall) Value {
   923  	obj := r.toObject(call.This)
   924  	if d, ok := obj.self.(*dateObject); ok {
   925  		var t time.Time
   926  		if d.isSet() {
   927  			t = d.timeUTC()
   928  		} else {
   929  			t = time.Date(1970, time.January, 1, 0, 0, 0, 0, time.UTC)
   930  		}
   931  		t, ok := _dateSetFullYear(t, limitCallArgs(call, 3), 0, true)
   932  		if !ok {
   933  			d.unset()
   934  			return _NaN
   935  		}
   936  		return d.setTimeMs(timeToMsec(t))
   937  	}
   938  	panic(r.NewTypeError("Method Date.prototype.setUTCFullYear is called on incompatible receiver"))
   939  }
   940  
   941  func (r *Runtime) createDateProto(val *Object) objectImpl {
   942  	o := &baseObject{
   943  		class:      classObject,
   944  		val:        val,
   945  		extensible: true,
   946  		prototype:  r.global.ObjectPrototype,
   947  	}
   948  	o.init()
   949  
   950  	o._putProp("constructor", r.global.Date, true, false, true)
   951  	o._putProp("toString", r.newNativeFunc(r.dateproto_toString, nil, "toString", nil, 0), true, false, true)
   952  	o._putProp("toDateString", r.newNativeFunc(r.dateproto_toDateString, nil, "toDateString", nil, 0), true, false, true)
   953  	o._putProp("toTimeString", r.newNativeFunc(r.dateproto_toTimeString, nil, "toTimeString", nil, 0), true, false, true)
   954  	o._putProp("toLocaleString", r.newNativeFunc(r.dateproto_toLocaleString, nil, "toLocaleString", nil, 0), true, false, true)
   955  	o._putProp("toLocaleDateString", r.newNativeFunc(r.dateproto_toLocaleDateString, nil, "toLocaleDateString", nil, 0), true, false, true)
   956  	o._putProp("toLocaleTimeString", r.newNativeFunc(r.dateproto_toLocaleTimeString, nil, "toLocaleTimeString", nil, 0), true, false, true)
   957  	o._putProp("valueOf", r.newNativeFunc(r.dateproto_valueOf, nil, "valueOf", nil, 0), true, false, true)
   958  	o._putProp("getTime", r.newNativeFunc(r.dateproto_getTime, nil, "getTime", nil, 0), true, false, true)
   959  	o._putProp("getFullYear", r.newNativeFunc(r.dateproto_getFullYear, nil, "getFullYear", nil, 0), true, false, true)
   960  	o._putProp("getUTCFullYear", r.newNativeFunc(r.dateproto_getUTCFullYear, nil, "getUTCFullYear", nil, 0), true, false, true)
   961  	o._putProp("getMonth", r.newNativeFunc(r.dateproto_getMonth, nil, "getMonth", nil, 0), true, false, true)
   962  	o._putProp("getUTCMonth", r.newNativeFunc(r.dateproto_getUTCMonth, nil, "getUTCMonth", nil, 0), true, false, true)
   963  	o._putProp("getDate", r.newNativeFunc(r.dateproto_getDate, nil, "getDate", nil, 0), true, false, true)
   964  	o._putProp("getUTCDate", r.newNativeFunc(r.dateproto_getUTCDate, nil, "getUTCDate", nil, 0), true, false, true)
   965  	o._putProp("getDay", r.newNativeFunc(r.dateproto_getDay, nil, "getDay", nil, 0), true, false, true)
   966  	o._putProp("getUTCDay", r.newNativeFunc(r.dateproto_getUTCDay, nil, "getUTCDay", nil, 0), true, false, true)
   967  	o._putProp("getHours", r.newNativeFunc(r.dateproto_getHours, nil, "getHours", nil, 0), true, false, true)
   968  	o._putProp("getUTCHours", r.newNativeFunc(r.dateproto_getUTCHours, nil, "getUTCHours", nil, 0), true, false, true)
   969  	o._putProp("getMinutes", r.newNativeFunc(r.dateproto_getMinutes, nil, "getMinutes", nil, 0), true, false, true)
   970  	o._putProp("getUTCMinutes", r.newNativeFunc(r.dateproto_getUTCMinutes, nil, "getUTCMinutes", nil, 0), true, false, true)
   971  	o._putProp("getSeconds", r.newNativeFunc(r.dateproto_getSeconds, nil, "getSeconds", nil, 0), true, false, true)
   972  	o._putProp("getUTCSeconds", r.newNativeFunc(r.dateproto_getUTCSeconds, nil, "getUTCSeconds", nil, 0), true, false, true)
   973  	o._putProp("getMilliseconds", r.newNativeFunc(r.dateproto_getMilliseconds, nil, "getMilliseconds", nil, 0), true, false, true)
   974  	o._putProp("getUTCMilliseconds", r.newNativeFunc(r.dateproto_getUTCMilliseconds, nil, "getUTCMilliseconds", nil, 0), true, false, true)
   975  	o._putProp("getTimezoneOffset", r.newNativeFunc(r.dateproto_getTimezoneOffset, nil, "getTimezoneOffset", nil, 0), true, false, true)
   976  	o._putProp("setTime", r.newNativeFunc(r.dateproto_setTime, nil, "setTime", nil, 1), true, false, true)
   977  	o._putProp("setMilliseconds", r.newNativeFunc(r.dateproto_setMilliseconds, nil, "setMilliseconds", nil, 1), true, false, true)
   978  	o._putProp("setUTCMilliseconds", r.newNativeFunc(r.dateproto_setUTCMilliseconds, nil, "setUTCMilliseconds", nil, 1), true, false, true)
   979  	o._putProp("setSeconds", r.newNativeFunc(r.dateproto_setSeconds, nil, "setSeconds", nil, 2), true, false, true)
   980  	o._putProp("setUTCSeconds", r.newNativeFunc(r.dateproto_setUTCSeconds, nil, "setUTCSeconds", nil, 2), true, false, true)
   981  	o._putProp("setMinutes", r.newNativeFunc(r.dateproto_setMinutes, nil, "setMinutes", nil, 3), true, false, true)
   982  	o._putProp("setUTCMinutes", r.newNativeFunc(r.dateproto_setUTCMinutes, nil, "setUTCMinutes", nil, 3), true, false, true)
   983  	o._putProp("setHours", r.newNativeFunc(r.dateproto_setHours, nil, "setHours", nil, 4), true, false, true)
   984  	o._putProp("setUTCHours", r.newNativeFunc(r.dateproto_setUTCHours, nil, "setUTCHours", nil, 4), true, false, true)
   985  	o._putProp("setDate", r.newNativeFunc(r.dateproto_setDate, nil, "setDate", nil, 1), true, false, true)
   986  	o._putProp("setUTCDate", r.newNativeFunc(r.dateproto_setUTCDate, nil, "setUTCDate", nil, 1), true, false, true)
   987  	o._putProp("setMonth", r.newNativeFunc(r.dateproto_setMonth, nil, "setMonth", nil, 2), true, false, true)
   988  	o._putProp("setUTCMonth", r.newNativeFunc(r.dateproto_setUTCMonth, nil, "setUTCMonth", nil, 2), true, false, true)
   989  	o._putProp("setFullYear", r.newNativeFunc(r.dateproto_setFullYear, nil, "setFullYear", nil, 3), true, false, true)
   990  	o._putProp("setUTCFullYear", r.newNativeFunc(r.dateproto_setUTCFullYear, nil, "setUTCFullYear", nil, 3), true, false, true)
   991  	o._putProp("toUTCString", r.newNativeFunc(r.dateproto_toUTCString, nil, "toUTCString", nil, 0), true, false, true)
   992  	o._putProp("toISOString", r.newNativeFunc(r.dateproto_toISOString, nil, "toISOString", nil, 0), true, false, true)
   993  	o._putProp("toJSON", r.newNativeFunc(r.dateproto_toJSON, nil, "toJSON", nil, 1), true, false, true)
   994  
   995  	o._putSym(SymToPrimitive, valueProp(r.newNativeFunc(r.dateproto_toPrimitive, nil, "[Symbol.toPrimitive]", nil, 1), false, false, true))
   996  
   997  	return o
   998  }
   999  
  1000  func (r *Runtime) createDate(val *Object) objectImpl {
  1001  	o := r.newNativeFuncObj(val, r.builtin_date, r.builtin_newDate, "Date", r.global.DatePrototype, intToValue(7))
  1002  
  1003  	o._putProp("parse", r.newNativeFunc(r.date_parse, nil, "parse", nil, 1), true, false, true)
  1004  	o._putProp("UTC", r.newNativeFunc(r.date_UTC, nil, "UTC", nil, 7), true, false, true)
  1005  	o._putProp("now", r.newNativeFunc(r.date_now, nil, "now", nil, 0), true, false, true)
  1006  
  1007  	return o
  1008  }
  1009  
  1010  func (r *Runtime) initDate() {
  1011  	r.global.DatePrototype = r.newLazyObject(r.createDateProto)
  1012  
  1013  	r.global.Date = r.newLazyObject(r.createDate)
  1014  	r.addToGlobal("Date", r.global.Date)
  1015  }