builtin_date.go 29 KB

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