builtin_date.go 29 KB

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