mirror of
https://github.com/robertkrimen/otto
synced 2025-09-28 18:45:22 +08:00
Use new date adjustment technique
This commit is contained in:
parent
e35b7985f6
commit
fa0f2abc44
20
builtin.go
20
builtin.go
|
@ -1222,6 +1222,26 @@ func builtinDate_setTime(call FunctionCall) Value {
|
|||
return date.Value()
|
||||
}
|
||||
|
||||
func _builtinDate_set(call FunctionCall, argumentCap int, dateLocal bool) (*_dateObject, *_ecmaTime) {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
return nil, nil
|
||||
}
|
||||
for index := 0; index < len(call.ArgumentList) && index < argumentCap; index++ {
|
||||
value := call.Argument(index)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return date, nil
|
||||
}
|
||||
}
|
||||
baseTime := date.Time()
|
||||
if dateLocal {
|
||||
baseTime = baseTime.Local()
|
||||
}
|
||||
ecmaTime := ecmaTime(baseTime)
|
||||
return date, &ecmaTime
|
||||
}
|
||||
|
||||
// Error
|
||||
|
||||
func builtinError(call FunctionCall) Value {
|
||||
|
|
138
global.go
138
global.go
|
@ -444,51 +444,21 @@ func newContext() *_runtime {
|
|||
// setTime, ...
|
||||
"setTime", 1, builtinDate_setTime,
|
||||
"setMilliseconds", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, true)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().Local()
|
||||
setTime := time_.Date(
|
||||
baseTime.Year(),
|
||||
baseTime.Month(),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
int(toInteger(value)) * 100 * 100 * 100,
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.millisecond = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
"setUTCMilliseconds", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, false)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().UTC()
|
||||
setTime := time_.Date(
|
||||
baseTime.Year(),
|
||||
baseTime.Month(),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
int(toInteger(value)) * 100 * 100 * 100,
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.millisecond = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
// setSeconds
|
||||
|
@ -500,99 +470,39 @@ func newContext() *_runtime {
|
|||
// setDate
|
||||
// setUTCDate
|
||||
"setMonth", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, true)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().Local()
|
||||
setTime := time_.Date(
|
||||
baseTime.Year(),
|
||||
dateToGoMonth(int(toInteger(value))),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
baseTime.Nanosecond(),
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.month = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
"setUTCMonth", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, false)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().UTC()
|
||||
setTime := time_.Date(
|
||||
baseTime.Year(),
|
||||
dateToGoMonth(int(toInteger(value))),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
baseTime.Nanosecond(),
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.month = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
"setFullYear", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, true)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().Local()
|
||||
setTime := time_.Date(
|
||||
int(toInteger(value)),
|
||||
baseTime.Month(),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
baseTime.Nanosecond(),
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.year = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
"setUTCFullYear", 1, func(call FunctionCall) Value {
|
||||
date := dateObjectOf(call.thisObject())
|
||||
if date.isNaN {
|
||||
date, ecmaTime := _builtinDate_set(call, 1, false)
|
||||
if ecmaTime == nil {
|
||||
return NaNValue()
|
||||
}
|
||||
value := call.Argument(0)
|
||||
if value.IsNaN() {
|
||||
date.SetNaN()
|
||||
return NaNValue()
|
||||
}
|
||||
baseTime := date.Time().UTC()
|
||||
setTime := time_.Date(
|
||||
int(toInteger(value)),
|
||||
baseTime.Month(),
|
||||
baseTime.Day(),
|
||||
baseTime.Hour(),
|
||||
baseTime.Minute(),
|
||||
baseTime.Second(),
|
||||
baseTime.Nanosecond(),
|
||||
baseTime.Location(),
|
||||
)
|
||||
date.SetTime(setTime)
|
||||
ecmaTime.year = int(toInteger(call.Argument(0)))
|
||||
date.SetTime(ecmaTime.goTime())
|
||||
return date.Value()
|
||||
},
|
||||
// toUTCString
|
||||
|
|
|
@ -579,6 +579,7 @@ func TestDate(t *testing.T) {
|
|||
test(`new Date(2009, 9, 25).toString()`, "Sun, 25 Oct 2009 00:00:00 UTC")
|
||||
test(`+(new Date(2009, 9, 25))`, "1.2564288e+12")
|
||||
|
||||
test(`abc = new Date(12564504e5); abc.setMilliseconds(2001); abc.toString()`, "Sun, 25 Oct 2009 06:00:02 UTC")
|
||||
test(`abc = new Date(12564504e5); abc.setMonth(9); abc.toString()`, "Sun, 25 Oct 2009 06:00:00 UTC")
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("09"); abc.toString()`, "Sun, 25 Oct 2009 06:00:00 UTC")
|
||||
test(`abc = new Date(12564504e5); abc.setMonth("10"); abc.toString()`, "Wed, 25 Nov 2009 07:00:00 UTC")
|
||||
|
|
37
type_date.go
37
type_date.go
|
@ -13,6 +13,43 @@ type _dateObject struct {
|
|||
isNaN bool
|
||||
}
|
||||
|
||||
type _ecmaTime struct {
|
||||
year int
|
||||
month int
|
||||
day int
|
||||
hour int
|
||||
minute int
|
||||
second int
|
||||
millisecond int
|
||||
location *tme.Location // Basically, either local or UTC
|
||||
}
|
||||
|
||||
func ecmaTime(goTime tme.Time) _ecmaTime {
|
||||
return _ecmaTime{
|
||||
goTime.Year(),
|
||||
dateFromGoMonth(goTime.Month()),
|
||||
goTime.Day(),
|
||||
goTime.Hour(),
|
||||
goTime.Minute(),
|
||||
goTime.Second(),
|
||||
goTime.Nanosecond() / (100 * 100 * 100),
|
||||
goTime.Location(),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *_ecmaTime) goTime() tme.Time {
|
||||
return tme.Date(
|
||||
self.year,
|
||||
dateToGoMonth(self.month),
|
||||
self.day,
|
||||
self.hour,
|
||||
self.minute,
|
||||
self.second,
|
||||
self.millisecond * (100 * 100 * 100),
|
||||
self.location,
|
||||
)
|
||||
}
|
||||
|
||||
func (self *_dateObject) Time() tme.Time {
|
||||
return self.time
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user