gitee.com/quant1x/pkg@v0.2.8/goja/builtin_date.go (about)

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