builtin_date.go 29 KB

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