builtin_date.go 29 KB

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