parseDttmToDate.test.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import { parseDttmToDate } from '@superset-ui/core';
  20. import timezoneMock from 'timezone-mock';
  21. // NOW will be set at midnight 2024-06-03 and transforme dfrom local timezone to UTC
  22. const NOW_IN_UTC = '2024-06-03T00:00:00Z';
  23. const NOW_UTC_IN_EUROPE = '2024-06-02T22:00:00Z'; // Same as 2024-06-03T00:00:00+02:00
  24. const NOW_UTC_IN_PACIFIC = '2024-06-03T08:00:00Z'; // Same as 2024-06-03T00:00:00-08:00
  25. afterEach(() => {
  26. timezoneMock.unregister();
  27. jest.useRealTimers();
  28. });
  29. const runTimezoneTest = (
  30. eval_time: string,
  31. now_time: string,
  32. timezone: any,
  33. expected_result: Date | null,
  34. endDate = false,
  35. computingShift = false,
  36. ) => {
  37. jest.setSystemTime(new Date(now_time));
  38. timezoneMock.register(timezone);
  39. expect(parseDttmToDate(eval_time, endDate, computingShift)).toEqual(
  40. expected_result,
  41. );
  42. timezoneMock.unregister();
  43. };
  44. test('should return the current date for "now"', () => {
  45. jest.useFakeTimers();
  46. runTimezoneTest(
  47. 'now',
  48. NOW_UTC_IN_EUROPE,
  49. 'Etc/GMT-2',
  50. new Date('2024-06-03T00:00:00+02:00'),
  51. );
  52. runTimezoneTest('now', NOW_IN_UTC, 'UTC', new Date('2024-06-03T00:00:00Z'));
  53. runTimezoneTest(
  54. 'now',
  55. NOW_UTC_IN_PACIFIC,
  56. 'Etc/GMT+8',
  57. new Date('2024-06-03T00:00:00-08:00'),
  58. );
  59. });
  60. test('should return the current date for "today"', () => {
  61. jest.useFakeTimers();
  62. runTimezoneTest(
  63. 'today',
  64. NOW_UTC_IN_EUROPE,
  65. 'Etc/GMT-2',
  66. new Date('2024-06-03T00:00:00+02:00'),
  67. );
  68. runTimezoneTest('today', NOW_IN_UTC, 'UTC', new Date('2024-06-03T00:00:00Z'));
  69. runTimezoneTest(
  70. 'today',
  71. NOW_UTC_IN_PACIFIC,
  72. 'Etc/GMT+8',
  73. new Date('2024-06-03T00:00:00-08:00'),
  74. );
  75. });
  76. test('should return the current date for "No filter"', () => {
  77. jest.useFakeTimers();
  78. runTimezoneTest(
  79. 'No filter',
  80. NOW_UTC_IN_EUROPE,
  81. 'Etc/GMT-2',
  82. new Date('2024-06-03T00:00:00+02:00'),
  83. );
  84. runTimezoneTest(
  85. 'No filter',
  86. NOW_IN_UTC,
  87. 'UTC',
  88. new Date('2024-06-03T00:00:00Z'),
  89. );
  90. runTimezoneTest(
  91. 'No filter',
  92. NOW_UTC_IN_PACIFIC,
  93. 'Etc/GMT+8',
  94. new Date('2024-06-03T00:00:00-08:00'),
  95. );
  96. });
  97. test('should return the current date for an empty string', () => {
  98. jest.useFakeTimers();
  99. runTimezoneTest(
  100. '',
  101. NOW_UTC_IN_EUROPE,
  102. 'Etc/GMT-2',
  103. new Date('2024-06-03T00:00:00+02:00'),
  104. );
  105. runTimezoneTest('', NOW_IN_UTC, 'UTC', new Date('2024-06-03T00:00:00Z'));
  106. runTimezoneTest(
  107. '',
  108. NOW_UTC_IN_PACIFIC,
  109. 'Etc/GMT+8',
  110. new Date('2024-06-03T00:00:00-08:00'),
  111. );
  112. });
  113. test('should return yesterday date for "Last day"', () => {
  114. jest.useFakeTimers();
  115. runTimezoneTest(
  116. 'Last day',
  117. NOW_UTC_IN_EUROPE,
  118. 'Etc/GMT-2',
  119. new Date('2024-06-01T22:00:00Z'),
  120. );
  121. runTimezoneTest(
  122. 'Last day',
  123. NOW_IN_UTC,
  124. 'UTC',
  125. new Date('2024-06-02T00:00:00Z'),
  126. );
  127. runTimezoneTest(
  128. 'Last day',
  129. NOW_UTC_IN_PACIFIC,
  130. 'Etc/GMT+8',
  131. new Date('2024-06-02T08:00:00Z'),
  132. );
  133. });
  134. test('should return the date one week ago for "Last week"', () => {
  135. jest.useFakeTimers();
  136. runTimezoneTest(
  137. 'Last week',
  138. NOW_UTC_IN_EUROPE,
  139. 'Etc/GMT-2',
  140. new Date('2024-05-26T22:00:00Z'),
  141. );
  142. runTimezoneTest(
  143. 'Last week',
  144. NOW_IN_UTC,
  145. 'UTC',
  146. new Date('2024-05-27T00:00:00Z'),
  147. );
  148. runTimezoneTest(
  149. 'Last week',
  150. NOW_UTC_IN_PACIFIC,
  151. 'Etc/GMT+8',
  152. new Date('2024-05-27T08:00:00Z'),
  153. );
  154. });
  155. test('should return the date one month ago for "Last month"', () => {
  156. jest.useFakeTimers();
  157. runTimezoneTest(
  158. 'Last month',
  159. NOW_UTC_IN_EUROPE,
  160. 'Etc/GMT-2',
  161. new Date('2024-05-02T22:00:00Z'),
  162. );
  163. runTimezoneTest(
  164. 'Last month',
  165. NOW_IN_UTC,
  166. 'UTC',
  167. new Date('2024-05-03T00:00:00Z'),
  168. );
  169. runTimezoneTest(
  170. 'Last month',
  171. NOW_UTC_IN_PACIFIC,
  172. 'Etc/GMT+8',
  173. new Date('2024-05-03T08:00:00Z'),
  174. );
  175. });
  176. test('should return the date three months ago for "Last quarter"', () => {
  177. jest.useFakeTimers();
  178. runTimezoneTest(
  179. 'Last quarter',
  180. NOW_UTC_IN_EUROPE,
  181. 'Etc/GMT-2',
  182. new Date('2024-03-02T22:00:00Z'),
  183. );
  184. runTimezoneTest(
  185. 'Last quarter',
  186. NOW_IN_UTC,
  187. 'UTC',
  188. new Date('2024-03-03T00:00:00Z'),
  189. );
  190. runTimezoneTest(
  191. 'Last quarter',
  192. NOW_UTC_IN_PACIFIC,
  193. 'Etc/GMT+8',
  194. new Date('2024-03-03T08:00:00Z'),
  195. );
  196. });
  197. test('should return the date one year ago for "Last year"', () => {
  198. jest.useFakeTimers();
  199. runTimezoneTest(
  200. 'Last year',
  201. NOW_UTC_IN_EUROPE,
  202. 'Etc/GMT-2',
  203. new Date('2023-06-02T22:00:00Z'),
  204. );
  205. runTimezoneTest(
  206. 'Last year',
  207. NOW_IN_UTC,
  208. 'UTC',
  209. new Date('2023-06-03T00:00:00Z'),
  210. );
  211. runTimezoneTest(
  212. 'Last year',
  213. NOW_UTC_IN_PACIFIC,
  214. 'Etc/GMT+8',
  215. new Date('2023-06-03T08:00:00Z'),
  216. );
  217. });
  218. test('should return the date for "previous calendar week"', () => {
  219. jest.useFakeTimers();
  220. runTimezoneTest(
  221. 'previous calendar week',
  222. '2024-06-04T22:00:00Z',
  223. 'Etc/GMT-2',
  224. new Date('2024-05-26T22:00:00Z'),
  225. );
  226. runTimezoneTest(
  227. 'previous calendar week',
  228. '2024-06-05T00:00:00Z',
  229. 'UTC',
  230. new Date('2024-05-27T00:00:00Z'),
  231. );
  232. runTimezoneTest(
  233. 'previous calendar week',
  234. '2024-06-05T08:00:00Z',
  235. 'Etc/GMT+8',
  236. new Date('2024-05-27T08:00:00Z'),
  237. );
  238. });
  239. test('should return the date for "previous calendar month"', () => {
  240. jest.useFakeTimers();
  241. runTimezoneTest(
  242. 'previous calendar month',
  243. NOW_UTC_IN_EUROPE,
  244. 'Etc/GMT-2',
  245. new Date('2024-04-30T22:00:00Z'),
  246. );
  247. runTimezoneTest(
  248. 'previous calendar month',
  249. NOW_IN_UTC,
  250. 'UTC',
  251. new Date('2024-05-01T00:00:00Z'),
  252. );
  253. runTimezoneTest(
  254. 'previous calendar month',
  255. NOW_UTC_IN_PACIFIC,
  256. 'Etc/GMT+8',
  257. new Date('2024-05-01T08:00:00Z'),
  258. );
  259. });
  260. test('should return the date for "previous calendar year"', () => {
  261. jest.useFakeTimers();
  262. runTimezoneTest(
  263. 'previous calendar year',
  264. NOW_UTC_IN_EUROPE,
  265. 'Etc/GMT-2',
  266. new Date('2022-12-31T22:00:00Z'),
  267. );
  268. runTimezoneTest(
  269. 'previous calendar year',
  270. NOW_IN_UTC,
  271. 'UTC',
  272. new Date('2023-01-01T00:00:00Z'),
  273. );
  274. runTimezoneTest(
  275. 'previous calendar year',
  276. NOW_UTC_IN_PACIFIC,
  277. 'Etc/GMT+8',
  278. new Date('2023-01-01T08:00:00Z'),
  279. );
  280. });
  281. test('should return the date for "1 day ago"', () => {
  282. jest.useFakeTimers();
  283. runTimezoneTest(
  284. '1 day ago',
  285. NOW_UTC_IN_EUROPE,
  286. 'Etc/GMT-2',
  287. new Date('2024-06-01T22:00:00Z'),
  288. );
  289. runTimezoneTest(
  290. '1 day ago',
  291. NOW_IN_UTC,
  292. 'UTC',
  293. new Date('2024-06-02T00:00:00Z'),
  294. );
  295. runTimezoneTest(
  296. '1 day ago',
  297. NOW_UTC_IN_PACIFIC,
  298. 'Etc/GMT+8',
  299. new Date('2024-06-02T08:00:00Z'),
  300. );
  301. });
  302. test('should return the date for "1 week ago"', () => {
  303. jest.useFakeTimers();
  304. runTimezoneTest(
  305. '1 week ago',
  306. NOW_UTC_IN_EUROPE,
  307. 'Etc/GMT-2',
  308. new Date('2024-05-26T22:00:00Z'),
  309. );
  310. runTimezoneTest(
  311. '1 week ago',
  312. NOW_IN_UTC,
  313. 'UTC',
  314. new Date('2024-05-27T00:00:00Z'),
  315. );
  316. runTimezoneTest(
  317. '1 week ago',
  318. NOW_UTC_IN_PACIFIC,
  319. 'Etc/GMT+8',
  320. new Date('2024-05-27T08:00:00Z'),
  321. );
  322. });
  323. test('should return the date for "1 month ago"', () => {
  324. jest.useFakeTimers();
  325. runTimezoneTest(
  326. '1 month ago',
  327. NOW_UTC_IN_EUROPE,
  328. 'Etc/GMT-2',
  329. new Date('2024-05-02T22:00:00Z'),
  330. );
  331. runTimezoneTest(
  332. '1 month ago',
  333. NOW_IN_UTC,
  334. 'UTC',
  335. new Date('2024-05-03T00:00:00Z'),
  336. );
  337. runTimezoneTest(
  338. '1 month ago',
  339. NOW_UTC_IN_PACIFIC,
  340. 'Etc/GMT+8',
  341. new Date('2024-05-03T08:00:00Z'),
  342. );
  343. });
  344. test('should return the date for "1 year ago"', () => {
  345. jest.useFakeTimers();
  346. runTimezoneTest(
  347. '1 year ago',
  348. NOW_UTC_IN_EUROPE,
  349. 'Etc/GMT-2',
  350. new Date('2023-06-02T22:00:00Z'),
  351. );
  352. runTimezoneTest(
  353. '1 year ago',
  354. NOW_IN_UTC,
  355. 'UTC',
  356. new Date('2023-06-03T00:00:00Z'),
  357. );
  358. runTimezoneTest(
  359. '1 year ago',
  360. NOW_UTC_IN_PACIFIC,
  361. 'Etc/GMT+8',
  362. new Date('2023-06-03T08:00:00Z'),
  363. );
  364. });
  365. test('should return the date for "2024-03-09"', () => {
  366. jest.useFakeTimers();
  367. runTimezoneTest(
  368. '2024-03-09',
  369. NOW_UTC_IN_EUROPE,
  370. 'Etc/GMT-2',
  371. new Date('2024-03-08T22:00:00.000Z'),
  372. );
  373. runTimezoneTest(
  374. '2024-03-09',
  375. NOW_IN_UTC,
  376. 'UTC',
  377. new Date('2024-03-09T00:00:00.000Z'),
  378. );
  379. runTimezoneTest(
  380. '2024-03-09',
  381. NOW_UTC_IN_PACIFIC,
  382. 'Etc/GMT+8',
  383. new Date('2024-03-09T08:00:00.000Z'),
  384. );
  385. });
  386. test('should return the current date for "Last day" with isEndDate true', () => {
  387. jest.useFakeTimers();
  388. runTimezoneTest(
  389. 'Last day',
  390. NOW_UTC_IN_EUROPE,
  391. 'Etc/GMT-2',
  392. new Date('2024-06-02T22:00:00Z'),
  393. true,
  394. );
  395. runTimezoneTest(
  396. 'Last day',
  397. NOW_IN_UTC,
  398. 'UTC',
  399. new Date('2024-06-03T00:00:00Z'),
  400. true,
  401. );
  402. runTimezoneTest(
  403. 'Last day',
  404. NOW_UTC_IN_PACIFIC,
  405. 'Etc/GMT+8',
  406. new Date('2024-06-03T08:00:00Z'),
  407. true,
  408. );
  409. });
  410. test('should return the current date for "Last week" with isEndDate true', () => {
  411. jest.useFakeTimers();
  412. runTimezoneTest(
  413. 'Last week',
  414. NOW_UTC_IN_EUROPE,
  415. 'Etc/GMT-2',
  416. new Date('2024-06-02T22:00:00Z'),
  417. true,
  418. );
  419. runTimezoneTest(
  420. 'Last week',
  421. NOW_IN_UTC,
  422. 'UTC',
  423. new Date('2024-06-03T00:00:00Z'),
  424. true,
  425. );
  426. runTimezoneTest(
  427. 'Last week',
  428. NOW_UTC_IN_PACIFIC,
  429. 'Etc/GMT+8',
  430. new Date('2024-06-03T08:00:00Z'),
  431. true,
  432. );
  433. });
  434. test('should return the current date for "Last quarter" with isEndDate true', () => {
  435. jest.useFakeTimers();
  436. runTimezoneTest(
  437. 'Last quarter',
  438. NOW_UTC_IN_EUROPE,
  439. 'Etc/GMT-2',
  440. new Date('2024-06-02T22:00:00Z'),
  441. true,
  442. );
  443. runTimezoneTest(
  444. 'Last quarter',
  445. NOW_IN_UTC,
  446. 'UTC',
  447. new Date('2024-06-03T00:00:00Z'),
  448. true,
  449. );
  450. runTimezoneTest(
  451. 'Last quarter',
  452. NOW_UTC_IN_PACIFIC,
  453. 'Etc/GMT+8',
  454. new Date('2024-06-03T08:00:00Z'),
  455. true,
  456. );
  457. });
  458. test('should return the current date for "Last year" with isEndDate true', () => {
  459. jest.useFakeTimers();
  460. runTimezoneTest(
  461. 'Last year',
  462. NOW_UTC_IN_EUROPE,
  463. 'Etc/GMT-2',
  464. new Date('2024-06-02T22:00:00Z'),
  465. true,
  466. );
  467. runTimezoneTest(
  468. 'Last year',
  469. NOW_IN_UTC,
  470. 'UTC',
  471. new Date('2024-06-03T00:00:00Z'),
  472. true,
  473. );
  474. runTimezoneTest(
  475. 'Last year',
  476. NOW_UTC_IN_PACIFIC,
  477. 'Etc/GMT+8',
  478. new Date('2024-06-03T08:00:00Z'),
  479. true,
  480. );
  481. });
  482. test('should return the date for "previous calendar week" with isEndDate true', () => {
  483. jest.useFakeTimers();
  484. runTimezoneTest(
  485. 'previous calendar week',
  486. NOW_UTC_IN_EUROPE,
  487. 'Etc/GMT-2',
  488. new Date('2024-06-02T22:00:00Z'),
  489. true,
  490. );
  491. runTimezoneTest(
  492. 'previous calendar week',
  493. NOW_IN_UTC,
  494. 'UTC',
  495. new Date('2024-06-03T00:00:00Z'),
  496. true,
  497. );
  498. runTimezoneTest(
  499. 'previous calendar week',
  500. NOW_UTC_IN_PACIFIC,
  501. 'Etc/GMT+8',
  502. new Date('2024-06-03T08:00:00Z'),
  503. true,
  504. );
  505. });
  506. test('should return the date for "previous calendar month" with isEndDate true', () => {
  507. jest.useFakeTimers();
  508. runTimezoneTest(
  509. 'previous calendar month',
  510. NOW_UTC_IN_EUROPE,
  511. 'Etc/GMT-2',
  512. new Date('2024-05-31T22:00:00Z'),
  513. true,
  514. );
  515. runTimezoneTest(
  516. 'previous calendar month',
  517. NOW_IN_UTC,
  518. 'UTC',
  519. new Date('2024-06-01T00:00:00Z'),
  520. true,
  521. );
  522. runTimezoneTest(
  523. 'previous calendar month',
  524. NOW_UTC_IN_PACIFIC,
  525. 'Etc/GMT+8',
  526. new Date('2024-06-01T08:00:00Z'),
  527. true,
  528. );
  529. });
  530. test('should return the date for "previous calendar year" with isEndDate true', () => {
  531. jest.useFakeTimers();
  532. runTimezoneTest(
  533. 'previous calendar year',
  534. NOW_UTC_IN_EUROPE,
  535. 'Etc/GMT-2',
  536. new Date('2023-12-31T22:00:00Z'),
  537. true,
  538. );
  539. runTimezoneTest(
  540. 'previous calendar year',
  541. NOW_IN_UTC,
  542. 'UTC',
  543. new Date('2024-01-01T00:00:00Z'),
  544. true,
  545. );
  546. runTimezoneTest(
  547. 'previous calendar year',
  548. NOW_UTC_IN_PACIFIC,
  549. 'Etc/GMT+8',
  550. new Date('2024-01-01T08:00:00Z'),
  551. true,
  552. );
  553. });
  554. test('should return the date for "2024" with parts.length === 1', () => {
  555. jest.useFakeTimers();
  556. runTimezoneTest(
  557. '2024',
  558. NOW_UTC_IN_EUROPE,
  559. 'Etc/GMT-2',
  560. new Date('2023-12-31T22:00:00.000Z'),
  561. );
  562. runTimezoneTest('2024', NOW_IN_UTC, 'UTC', new Date('2024-01-01T00:00:00Z'));
  563. runTimezoneTest(
  564. '2024',
  565. NOW_UTC_IN_PACIFIC,
  566. 'Etc/GMT+8',
  567. new Date('2023-12-31T08:00:00.000Z'),
  568. );
  569. });
  570. test('should return the date for "2024-03" with parts.length === 2', () => {
  571. jest.useFakeTimers();
  572. runTimezoneTest(
  573. '2024-03',
  574. NOW_UTC_IN_EUROPE,
  575. 'Etc/GMT-2',
  576. new Date('2024-02-29T22:00:00.000Z'),
  577. );
  578. runTimezoneTest(
  579. '2024-03',
  580. NOW_IN_UTC,
  581. 'UTC',
  582. new Date('2024-03-01T00:00:00Z'),
  583. );
  584. runTimezoneTest(
  585. '2024-03',
  586. NOW_UTC_IN_PACIFIC,
  587. 'Etc/GMT+8',
  588. new Date('2024-02-29T08:00:00.000Z'),
  589. );
  590. });
  591. test('should return the date for "2024-03-06" with parts.length === 3', () => {
  592. jest.useFakeTimers();
  593. runTimezoneTest(
  594. '2024-03-06',
  595. NOW_UTC_IN_EUROPE,
  596. 'Etc/GMT-2',
  597. new Date('2024-03-05T22:00:00.000Z'),
  598. );
  599. runTimezoneTest(
  600. '2024-03-06',
  601. NOW_IN_UTC,
  602. 'UTC',
  603. new Date('2024-03-06T00:00:00.000Z'),
  604. );
  605. runTimezoneTest(
  606. '2024-03-06',
  607. NOW_UTC_IN_PACIFIC,
  608. 'Etc/GMT+8',
  609. new Date('2024-03-06T08:00:00.000Z'),
  610. );
  611. });
  612. test('should return the date for "2024-03-06" with computingShifts true', () => {
  613. jest.useFakeTimers();
  614. const expectedDate = new Date('2024-03-06T22:00:00Z');
  615. expectedDate.setHours(-expectedDate.getTimezoneOffset() / 60, 0, 0, 0);
  616. runTimezoneTest(
  617. '2024-03-06',
  618. NOW_UTC_IN_EUROPE,
  619. 'Etc/GMT-2',
  620. expectedDate,
  621. false,
  622. true,
  623. );
  624. });
  625. test('should return the date for "2024-03-06" with computingShifts true and isEndDate true', () => {
  626. jest.useFakeTimers();
  627. const expectedDate = new Date('2024-03-06T22:00:00Z');
  628. expectedDate.setHours(-expectedDate.getTimezoneOffset() / 60, 0, 0, 0);
  629. runTimezoneTest(
  630. '2024-03-06',
  631. NOW_UTC_IN_EUROPE,
  632. 'Etc/GMT-2',
  633. expectedDate,
  634. true,
  635. true,
  636. );
  637. });