1
0
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:
Robert Krimen 2012-10-07 22:54:39 -07:00
parent e35b7985f6
commit fa0f2abc44
4 changed files with 82 additions and 114 deletions

View File

@ -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
View File

@ -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

View File

@ -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")

View File

@ -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
}