builtin_date.go 29 KB

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