Repository: knowledgecode/date-and-time
Branch: master
Commit: b505b94b0590
Files: 618
Total size: 833.5 KB
Directory structure:
gitextract_4dtccixv/
├── .editorconfig
├── .github/
│ └── workflows/
│ ├── deploy-docs.yml
│ └── test.yml
├── .gitignore
├── LICENSE
├── README.md
├── astro.config.mjs
├── docs/
│ ├── api/
│ │ ├── addDays.md
│ │ ├── addHours.md
│ │ ├── addMilliseconds.md
│ │ ├── addMinutes.md
│ │ ├── addMonths.md
│ │ ├── addSeconds.md
│ │ ├── addYears.md
│ │ ├── compile.md
│ │ ├── format.md
│ │ ├── index.md
│ │ ├── isValid.md
│ │ ├── parse.md
│ │ ├── preparse.md
│ │ ├── subtract.md
│ │ ├── transform.md
│ │ └── utils/
│ │ ├── getDaysInMonth.md
│ │ ├── getISOWeek.md
│ │ ├── getISOWeekYear.md
│ │ ├── isLeapYear.md
│ │ └── isSameDay.md
│ ├── content.config.ts
│ ├── env.d.ts
│ ├── guide/
│ │ ├── index.md
│ │ ├── installation.mdx
│ │ └── quick-start.md
│ ├── index.mdx
│ ├── locales.md
│ ├── migration.md
│ ├── plugins.md
│ ├── styles/
│ │ └── custom.css
│ ├── timezones.md
│ └── tsconfig.json
├── eslint.config.js
├── package.json
├── rollup.config.ts
├── src/
│ ├── addDays.ts
│ ├── addHours.ts
│ ├── addMilliseconds.ts
│ ├── addMinutes.ts
│ ├── addMonths.ts
│ ├── addSeconds.ts
│ ├── addYears.ts
│ ├── compile.ts
│ ├── datetime.ts
│ ├── dtf.ts
│ ├── duration.ts
│ ├── format.ts
│ ├── formatter.ts
│ ├── index.ts
│ ├── isValid.ts
│ ├── locale.ts
│ ├── locales/
│ │ ├── ar.ts
│ │ ├── az.ts
│ │ ├── bn.ts
│ │ ├── cs.ts
│ │ ├── da.ts
│ │ ├── de.ts
│ │ ├── el.ts
│ │ ├── en.ts
│ │ ├── es.ts
│ │ ├── fa.ts
│ │ ├── fi.ts
│ │ ├── fr.ts
│ │ ├── he.ts
│ │ ├── hi.ts
│ │ ├── hu.ts
│ │ ├── id.ts
│ │ ├── it.ts
│ │ ├── ja.ts
│ │ ├── ko.ts
│ │ ├── ms.ts
│ │ ├── my.ts
│ │ ├── nl.ts
│ │ ├── no.ts
│ │ ├── pl.ts
│ │ ├── pt-BR.ts
│ │ ├── pt-PT.ts
│ │ ├── ro.ts
│ │ ├── ru.ts
│ │ ├── rw.ts
│ │ ├── sr-Cyrl.ts
│ │ ├── sr-Latn.ts
│ │ ├── sv.ts
│ │ ├── ta.ts
│ │ ├── th.ts
│ │ ├── tr.ts
│ │ ├── uk.ts
│ │ ├── uz-Cyrl.ts
│ │ ├── uz-Latn.ts
│ │ ├── vi.ts
│ │ ├── zh-Hans.ts
│ │ └── zh-Hant.ts
│ ├── numeral.ts
│ ├── numerals/
│ │ ├── arab.ts
│ │ ├── arabext.ts
│ │ ├── beng.ts
│ │ ├── latn.ts
│ │ └── mymr.ts
│ ├── parse.ts
│ ├── parser.ts
│ ├── plugin.ts
│ ├── plugins/
│ │ ├── day-of-week.ts
│ │ ├── microsecond.ts
│ │ ├── nanosecond.ts
│ │ ├── ordinal.ts
│ │ ├── quarter.ts
│ │ ├── timestamp.ts
│ │ ├── two-digit-year.ts
│ │ ├── week.ts
│ │ └── zonename.ts
│ ├── preparse.ts
│ ├── subtract.ts
│ ├── timezone.ts
│ ├── timezones/
│ │ ├── Africa/
│ │ │ ├── Abidjan.ts
│ │ │ ├── Accra.ts
│ │ │ ├── Addis_Ababa.ts
│ │ │ ├── Algiers.ts
│ │ │ ├── Asmara.ts
│ │ │ ├── Bamako.ts
│ │ │ ├── Bangui.ts
│ │ │ ├── Banjul.ts
│ │ │ ├── Bissau.ts
│ │ │ ├── Blantyre.ts
│ │ │ ├── Brazzaville.ts
│ │ │ ├── Bujumbura.ts
│ │ │ ├── Cairo.ts
│ │ │ ├── Casablanca.ts
│ │ │ ├── Ceuta.ts
│ │ │ ├── Conakry.ts
│ │ │ ├── Dakar.ts
│ │ │ ├── Dar_es_Salaam.ts
│ │ │ ├── Djibouti.ts
│ │ │ ├── Douala.ts
│ │ │ ├── El_Aaiun.ts
│ │ │ ├── Freetown.ts
│ │ │ ├── Gaborone.ts
│ │ │ ├── Harare.ts
│ │ │ ├── Johannesburg.ts
│ │ │ ├── Juba.ts
│ │ │ ├── Kampala.ts
│ │ │ ├── Khartoum.ts
│ │ │ ├── Kigali.ts
│ │ │ ├── Kinshasa.ts
│ │ │ ├── Lagos.ts
│ │ │ ├── Libreville.ts
│ │ │ ├── Lome.ts
│ │ │ ├── Luanda.ts
│ │ │ ├── Lubumbashi.ts
│ │ │ ├── Lusaka.ts
│ │ │ ├── Malabo.ts
│ │ │ ├── Maputo.ts
│ │ │ ├── Maseru.ts
│ │ │ ├── Mbabane.ts
│ │ │ ├── Mogadishu.ts
│ │ │ ├── Monrovia.ts
│ │ │ ├── Nairobi.ts
│ │ │ ├── Ndjamena.ts
│ │ │ ├── Niamey.ts
│ │ │ ├── Nouakchott.ts
│ │ │ ├── Ouagadougou.ts
│ │ │ ├── Porto-Novo.ts
│ │ │ ├── Sao_Tome.ts
│ │ │ ├── Tripoli.ts
│ │ │ ├── Tunis.ts
│ │ │ └── Windhoek.ts
│ │ ├── America/
│ │ │ ├── Adak.ts
│ │ │ ├── Anchorage.ts
│ │ │ ├── Anguilla.ts
│ │ │ ├── Antigua.ts
│ │ │ ├── Araguaina.ts
│ │ │ ├── Argentina/
│ │ │ │ ├── Buenos_Aires.ts
│ │ │ │ ├── Catamarca.ts
│ │ │ │ ├── Cordoba.ts
│ │ │ │ ├── Jujuy.ts
│ │ │ │ ├── La_Rioja.ts
│ │ │ │ ├── Mendoza.ts
│ │ │ │ ├── Rio_Gallegos.ts
│ │ │ │ ├── Salta.ts
│ │ │ │ ├── San_Juan.ts
│ │ │ │ ├── San_Luis.ts
│ │ │ │ ├── Tucuman.ts
│ │ │ │ └── Ushuaia.ts
│ │ │ ├── Aruba.ts
│ │ │ ├── Asuncion.ts
│ │ │ ├── Atikokan.ts
│ │ │ ├── Bahia.ts
│ │ │ ├── Bahia_Banderas.ts
│ │ │ ├── Barbados.ts
│ │ │ ├── Belem.ts
│ │ │ ├── Belize.ts
│ │ │ ├── Blanc-Sablon.ts
│ │ │ ├── Boa_Vista.ts
│ │ │ ├── Bogota.ts
│ │ │ ├── Boise.ts
│ │ │ ├── Cambridge_Bay.ts
│ │ │ ├── Campo_Grande.ts
│ │ │ ├── Cancun.ts
│ │ │ ├── Caracas.ts
│ │ │ ├── Cayenne.ts
│ │ │ ├── Cayman.ts
│ │ │ ├── Chicago.ts
│ │ │ ├── Chihuahua.ts
│ │ │ ├── Ciudad_Juarez.ts
│ │ │ ├── Costa_Rica.ts
│ │ │ ├── Coyhaique.ts
│ │ │ ├── Creston.ts
│ │ │ ├── Cuiaba.ts
│ │ │ ├── Curacao.ts
│ │ │ ├── Danmarkshavn.ts
│ │ │ ├── Dawson.ts
│ │ │ ├── Dawson_Creek.ts
│ │ │ ├── Denver.ts
│ │ │ ├── Detroit.ts
│ │ │ ├── Dominica.ts
│ │ │ ├── Edmonton.ts
│ │ │ ├── Eirunepe.ts
│ │ │ ├── El_Salvador.ts
│ │ │ ├── Fort_Nelson.ts
│ │ │ ├── Fortaleza.ts
│ │ │ ├── Glace_Bay.ts
│ │ │ ├── Goose_Bay.ts
│ │ │ ├── Grand_Turk.ts
│ │ │ ├── Grenada.ts
│ │ │ ├── Guadeloupe.ts
│ │ │ ├── Guatemala.ts
│ │ │ ├── Guayaquil.ts
│ │ │ ├── Guyana.ts
│ │ │ ├── Halifax.ts
│ │ │ ├── Havana.ts
│ │ │ ├── Hermosillo.ts
│ │ │ ├── Indiana/
│ │ │ │ ├── Indianapolis.ts
│ │ │ │ ├── Knox.ts
│ │ │ │ ├── Marengo.ts
│ │ │ │ ├── Petersburg.ts
│ │ │ │ ├── Tell_City.ts
│ │ │ │ ├── Vevay.ts
│ │ │ │ ├── Vincennes.ts
│ │ │ │ └── Winamac.ts
│ │ │ ├── Inuvik.ts
│ │ │ ├── Iqaluit.ts
│ │ │ ├── Jamaica.ts
│ │ │ ├── Juneau.ts
│ │ │ ├── Kentucky/
│ │ │ │ ├── Louisville.ts
│ │ │ │ └── Monticello.ts
│ │ │ ├── Kralendijk.ts
│ │ │ ├── La_Paz.ts
│ │ │ ├── Lima.ts
│ │ │ ├── Los_Angeles.ts
│ │ │ ├── Lower_Princes.ts
│ │ │ ├── Maceio.ts
│ │ │ ├── Managua.ts
│ │ │ ├── Manaus.ts
│ │ │ ├── Marigot.ts
│ │ │ ├── Martinique.ts
│ │ │ ├── Matamoros.ts
│ │ │ ├── Mazatlan.ts
│ │ │ ├── Menominee.ts
│ │ │ ├── Merida.ts
│ │ │ ├── Metlakatla.ts
│ │ │ ├── Mexico_City.ts
│ │ │ ├── Miquelon.ts
│ │ │ ├── Moncton.ts
│ │ │ ├── Monterrey.ts
│ │ │ ├── Montevideo.ts
│ │ │ ├── Montserrat.ts
│ │ │ ├── Nassau.ts
│ │ │ ├── New_York.ts
│ │ │ ├── Nome.ts
│ │ │ ├── Noronha.ts
│ │ │ ├── North_Dakota/
│ │ │ │ ├── Beulah.ts
│ │ │ │ ├── Center.ts
│ │ │ │ └── New_Salem.ts
│ │ │ ├── Nuuk.ts
│ │ │ ├── Ojinaga.ts
│ │ │ ├── Panama.ts
│ │ │ ├── Paramaribo.ts
│ │ │ ├── Phoenix.ts
│ │ │ ├── Port-au-Prince.ts
│ │ │ ├── Port_of_Spain.ts
│ │ │ ├── Porto_Velho.ts
│ │ │ ├── Puerto_Rico.ts
│ │ │ ├── Punta_Arenas.ts
│ │ │ ├── Rankin_Inlet.ts
│ │ │ ├── Recife.ts
│ │ │ ├── Regina.ts
│ │ │ ├── Resolute.ts
│ │ │ ├── Rio_Branco.ts
│ │ │ ├── Santarem.ts
│ │ │ ├── Santiago.ts
│ │ │ ├── Santo_Domingo.ts
│ │ │ ├── Sao_Paulo.ts
│ │ │ ├── Scoresbysund.ts
│ │ │ ├── Sitka.ts
│ │ │ ├── St_Barthelemy.ts
│ │ │ ├── St_Johns.ts
│ │ │ ├── St_Kitts.ts
│ │ │ ├── St_Lucia.ts
│ │ │ ├── St_Thomas.ts
│ │ │ ├── St_Vincent.ts
│ │ │ ├── Swift_Current.ts
│ │ │ ├── Tegucigalpa.ts
│ │ │ ├── Thule.ts
│ │ │ ├── Tijuana.ts
│ │ │ ├── Toronto.ts
│ │ │ ├── Tortola.ts
│ │ │ ├── Vancouver.ts
│ │ │ ├── Whitehorse.ts
│ │ │ ├── Winnipeg.ts
│ │ │ └── Yakutat.ts
│ │ ├── Antarctica/
│ │ │ ├── Casey.ts
│ │ │ ├── Davis.ts
│ │ │ ├── DumontDUrville.ts
│ │ │ ├── Macquarie.ts
│ │ │ ├── Mawson.ts
│ │ │ ├── McMurdo.ts
│ │ │ ├── Palmer.ts
│ │ │ ├── Rothera.ts
│ │ │ ├── Syowa.ts
│ │ │ ├── Troll.ts
│ │ │ └── Vostok.ts
│ │ ├── Arctic/
│ │ │ └── Longyearbyen.ts
│ │ ├── Asia/
│ │ │ ├── Aden.ts
│ │ │ ├── Almaty.ts
│ │ │ ├── Amman.ts
│ │ │ ├── Anadyr.ts
│ │ │ ├── Aqtau.ts
│ │ │ ├── Aqtobe.ts
│ │ │ ├── Ashgabat.ts
│ │ │ ├── Atyrau.ts
│ │ │ ├── Baghdad.ts
│ │ │ ├── Bahrain.ts
│ │ │ ├── Baku.ts
│ │ │ ├── Bangkok.ts
│ │ │ ├── Barnaul.ts
│ │ │ ├── Beirut.ts
│ │ │ ├── Bishkek.ts
│ │ │ ├── Brunei.ts
│ │ │ ├── Chita.ts
│ │ │ ├── Colombo.ts
│ │ │ ├── Damascus.ts
│ │ │ ├── Dhaka.ts
│ │ │ ├── Dili.ts
│ │ │ ├── Dubai.ts
│ │ │ ├── Dushanbe.ts
│ │ │ ├── Famagusta.ts
│ │ │ ├── Gaza.ts
│ │ │ ├── Hebron.ts
│ │ │ ├── Ho_Chi_Minh.ts
│ │ │ ├── Hong_Kong.ts
│ │ │ ├── Hovd.ts
│ │ │ ├── Irkutsk.ts
│ │ │ ├── Jakarta.ts
│ │ │ ├── Jayapura.ts
│ │ │ ├── Jerusalem.ts
│ │ │ ├── Kabul.ts
│ │ │ ├── Kamchatka.ts
│ │ │ ├── Karachi.ts
│ │ │ ├── Kathmandu.ts
│ │ │ ├── Khandyga.ts
│ │ │ ├── Kolkata.ts
│ │ │ ├── Krasnoyarsk.ts
│ │ │ ├── Kuala_Lumpur.ts
│ │ │ ├── Kuching.ts
│ │ │ ├── Kuwait.ts
│ │ │ ├── Macau.ts
│ │ │ ├── Magadan.ts
│ │ │ ├── Makassar.ts
│ │ │ ├── Manila.ts
│ │ │ ├── Muscat.ts
│ │ │ ├── Nicosia.ts
│ │ │ ├── Novokuznetsk.ts
│ │ │ ├── Novosibirsk.ts
│ │ │ ├── Omsk.ts
│ │ │ ├── Oral.ts
│ │ │ ├── Phnom_Penh.ts
│ │ │ ├── Pontianak.ts
│ │ │ ├── Pyongyang.ts
│ │ │ ├── Qatar.ts
│ │ │ ├── Qostanay.ts
│ │ │ ├── Qyzylorda.ts
│ │ │ ├── Riyadh.ts
│ │ │ ├── Sakhalin.ts
│ │ │ ├── Samarkand.ts
│ │ │ ├── Seoul.ts
│ │ │ ├── Shanghai.ts
│ │ │ ├── Singapore.ts
│ │ │ ├── Srednekolymsk.ts
│ │ │ ├── Taipei.ts
│ │ │ ├── Tashkent.ts
│ │ │ ├── Tbilisi.ts
│ │ │ ├── Tehran.ts
│ │ │ ├── Thimphu.ts
│ │ │ ├── Tokyo.ts
│ │ │ ├── Tomsk.ts
│ │ │ ├── Ulaanbaatar.ts
│ │ │ ├── Urumqi.ts
│ │ │ ├── Ust-Nera.ts
│ │ │ ├── Vientiane.ts
│ │ │ ├── Vladivostok.ts
│ │ │ ├── Yakutsk.ts
│ │ │ ├── Yangon.ts
│ │ │ ├── Yekaterinburg.ts
│ │ │ └── Yerevan.ts
│ │ ├── Atlantic/
│ │ │ ├── Azores.ts
│ │ │ ├── Bermuda.ts
│ │ │ ├── Canary.ts
│ │ │ ├── Cape_Verde.ts
│ │ │ ├── Faroe.ts
│ │ │ ├── Madeira.ts
│ │ │ ├── Reykjavik.ts
│ │ │ ├── South_Georgia.ts
│ │ │ ├── St_Helena.ts
│ │ │ └── Stanley.ts
│ │ ├── Australia/
│ │ │ ├── Adelaide.ts
│ │ │ ├── Brisbane.ts
│ │ │ ├── Broken_Hill.ts
│ │ │ ├── Darwin.ts
│ │ │ ├── Eucla.ts
│ │ │ ├── Hobart.ts
│ │ │ ├── Lindeman.ts
│ │ │ ├── Lord_Howe.ts
│ │ │ ├── Melbourne.ts
│ │ │ ├── Perth.ts
│ │ │ └── Sydney.ts
│ │ ├── Europe/
│ │ │ ├── Amsterdam.ts
│ │ │ ├── Andorra.ts
│ │ │ ├── Astrakhan.ts
│ │ │ ├── Athens.ts
│ │ │ ├── Belgrade.ts
│ │ │ ├── Berlin.ts
│ │ │ ├── Bratislava.ts
│ │ │ ├── Brussels.ts
│ │ │ ├── Bucharest.ts
│ │ │ ├── Budapest.ts
│ │ │ ├── Busingen.ts
│ │ │ ├── Chisinau.ts
│ │ │ ├── Copenhagen.ts
│ │ │ ├── Dublin.ts
│ │ │ ├── Gibraltar.ts
│ │ │ ├── Guernsey.ts
│ │ │ ├── Helsinki.ts
│ │ │ ├── Isle_of_Man.ts
│ │ │ ├── Istanbul.ts
│ │ │ ├── Jersey.ts
│ │ │ ├── Kaliningrad.ts
│ │ │ ├── Kirov.ts
│ │ │ ├── Kyiv.ts
│ │ │ ├── Lisbon.ts
│ │ │ ├── Ljubljana.ts
│ │ │ ├── London.ts
│ │ │ ├── Luxembourg.ts
│ │ │ ├── Madrid.ts
│ │ │ ├── Malta.ts
│ │ │ ├── Mariehamn.ts
│ │ │ ├── Minsk.ts
│ │ │ ├── Monaco.ts
│ │ │ ├── Moscow.ts
│ │ │ ├── Oslo.ts
│ │ │ ├── Paris.ts
│ │ │ ├── Podgorica.ts
│ │ │ ├── Prague.ts
│ │ │ ├── Riga.ts
│ │ │ ├── Rome.ts
│ │ │ ├── Samara.ts
│ │ │ ├── San_Marino.ts
│ │ │ ├── Sarajevo.ts
│ │ │ ├── Saratov.ts
│ │ │ ├── Simferopol.ts
│ │ │ ├── Skopje.ts
│ │ │ ├── Sofia.ts
│ │ │ ├── Stockholm.ts
│ │ │ ├── Tallinn.ts
│ │ │ ├── Tirane.ts
│ │ │ ├── Ulyanovsk.ts
│ │ │ ├── Vaduz.ts
│ │ │ ├── Vatican.ts
│ │ │ ├── Vienna.ts
│ │ │ ├── Vilnius.ts
│ │ │ ├── Volgograd.ts
│ │ │ ├── Warsaw.ts
│ │ │ ├── Zagreb.ts
│ │ │ └── Zurich.ts
│ │ ├── Indian/
│ │ │ ├── Antananarivo.ts
│ │ │ ├── Chagos.ts
│ │ │ ├── Christmas.ts
│ │ │ ├── Cocos.ts
│ │ │ ├── Comoro.ts
│ │ │ ├── Kerguelen.ts
│ │ │ ├── Mahe.ts
│ │ │ ├── Maldives.ts
│ │ │ ├── Mauritius.ts
│ │ │ ├── Mayotte.ts
│ │ │ └── Reunion.ts
│ │ └── Pacific/
│ │ ├── Apia.ts
│ │ ├── Auckland.ts
│ │ ├── Bougainville.ts
│ │ ├── Chatham.ts
│ │ ├── Chuuk.ts
│ │ ├── Easter.ts
│ │ ├── Efate.ts
│ │ ├── Fakaofo.ts
│ │ ├── Fiji.ts
│ │ ├── Funafuti.ts
│ │ ├── Galapagos.ts
│ │ ├── Gambier.ts
│ │ ├── Guadalcanal.ts
│ │ ├── Guam.ts
│ │ ├── Honolulu.ts
│ │ ├── Kanton.ts
│ │ ├── Kiritimati.ts
│ │ ├── Kosrae.ts
│ │ ├── Kwajalein.ts
│ │ ├── Majuro.ts
│ │ ├── Marquesas.ts
│ │ ├── Midway.ts
│ │ ├── Nauru.ts
│ │ ├── Niue.ts
│ │ ├── Norfolk.ts
│ │ ├── Noumea.ts
│ │ ├── Pago_Pago.ts
│ │ ├── Palau.ts
│ │ ├── Pitcairn.ts
│ │ ├── Pohnpei.ts
│ │ ├── Port_Moresby.ts
│ │ ├── Rarotonga.ts
│ │ ├── Saipan.ts
│ │ ├── Tahiti.ts
│ │ ├── Tarawa.ts
│ │ ├── Tongatapu.ts
│ │ ├── Wake.ts
│ │ └── Wallis.ts
│ ├── transform.ts
│ ├── utils.ts
│ ├── zone.ts
│ └── zonenames.ts
├── tests/
│ ├── addDays.spec.ts
│ ├── addHours.spec.ts
│ ├── addMilliseconds.spec.ts
│ ├── addMinutes.spec.ts
│ ├── addMonths.spec.ts
│ ├── addSeconds.spec.ts
│ ├── addYears.spec.ts
│ ├── compile.spec.ts
│ ├── duration.spec.ts
│ ├── format.spec.ts
│ ├── isValid.spec.ts
│ ├── locales/
│ │ ├── ar.spec.ts
│ │ ├── az.spec.ts
│ │ ├── bn.spec.ts
│ │ ├── cs.spec.ts
│ │ ├── da.spec.ts
│ │ ├── de.spec.ts
│ │ ├── el.spec.ts
│ │ ├── en.spec.ts
│ │ ├── es.spec.ts
│ │ ├── fa.spec.ts
│ │ ├── fi.spec.ts
│ │ ├── fr.spec.ts
│ │ ├── he.spec.ts
│ │ ├── hi.spec.ts
│ │ ├── hu.spec.ts
│ │ ├── id.spec.ts
│ │ ├── it.spec.ts
│ │ ├── ja.spec.ts
│ │ ├── ko.spec.ts
│ │ ├── ms.spec.ts
│ │ ├── my.spec.ts
│ │ ├── nl.spec.ts
│ │ ├── no.spec.ts
│ │ ├── pl.spec.ts
│ │ ├── pt-BR.spec.ts
│ │ ├── pt-PT.spec.ts
│ │ ├── ro.spec.ts
│ │ ├── ru.spec.ts
│ │ ├── rw.spec.ts
│ │ ├── sr-Cyrl.spec.ts
│ │ ├── sr-Latn.spec.ts
│ │ ├── sv.spec.ts
│ │ ├── ta.spec.ts
│ │ ├── th.spec.ts
│ │ ├── tr.spec.ts
│ │ ├── uk.spec.ts
│ │ ├── uz-Cyrl.spec.ts
│ │ ├── uz-Latn.spec.ts
│ │ ├── vi.spec.ts
│ │ ├── zh-Hans.spec.ts
│ │ └── zh-Hant.spec.ts
│ ├── numerals/
│ │ ├── arab.spec.ts
│ │ ├── arabext.spec.ts
│ │ ├── beng.spec.ts
│ │ ├── latn.spec.ts
│ │ └── mymr.spec.ts
│ ├── parse.spec.ts
│ ├── plugins/
│ │ ├── microsecond.spec.ts
│ │ ├── nanosecond.spec.ts
│ │ ├── ordinal.spec.ts
│ │ ├── quarter.spec.ts
│ │ ├── timestamp.spec.ts
│ │ ├── two-digit-year.spec.ts
│ │ ├── week.spec.ts
│ │ └── zonename.spec.ts
│ ├── preparse.spec.ts
│ ├── subtract.spec.ts
│ ├── timezones/
│ │ └── timezones.spec.ts
│ ├── transform.spec.ts
│ └── utils.spec.ts
├── tools/
│ ├── locale.ts
│ ├── timezone.ts
│ └── zonename.ts
├── tsconfig.json
└── vitest.config.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*.{js,ts}]
charset = utf-8
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
================================================
FILE: .github/workflows/deploy-docs.yml
================================================
name: Deploy Starlight site to GitHub Pages
on:
push:
branches:
- master
paths:
- 'docs/**'
- 'astro.config.mjs'
- '.github/workflows/deploy-docs.yml'
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: npm
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: npm ci
- name: Build with Astro
run: npm run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: pages
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .github/workflows/test.yml
================================================
name: CI
on:
push:
branches: [ master, develop ]
pull_request:
branches: [ master, develop ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
coverage:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests with coverage
run: npm run test:coverage
- name: Read coverage summary
id: coverage
run: |
echo "pct=$(jq '.total.lines.pct' coverage/coverage-summary.json)" >> $GITHUB_OUTPUT
- name: Create badges directory
run: mkdir -p .github/badges
- name: Generate coverage badge
uses: emibcn/badge-action@v2.0.3
with:
label: 'coverage'
status: ${{ steps.coverage.outputs.pct }}%
color: ${{ fromJSON(steps.coverage.outputs.pct) >= 80 && 'green' || fromJSON(steps.coverage.outputs.pct) >= 60 && 'yellow' || 'red' }}
path: .github/badges/coverage.svg
- name: Commit coverage badge
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .github/badges/coverage.svg
git diff --staged --quiet || git commit -m "Update coverage badge"
git push
- name: Upload coverage reports
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
================================================
FILE: .gitignore
================================================
.DS_Store
.vscode/
cache/
coverage/
dist/
pages/
node_modules/
# Astro
.astro/
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 KNOWLEDGECODE
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# date-and-time
[](https://github.com/knowledgecode/date-and-time/actions/workflows/test.yml)
[](https://github.com/knowledgecode/date-and-time/actions/workflows/test.yml)
[](https://www.npmjs.com/package/date-and-time)
The simplest, most intuitive date and time library.
## Installation
```shell
npm install date-and-time
```
### ES Modules (Recommended)
```typescript
import { format } from 'date-and-time';
format(new Date(), 'ddd, MMM DD YYYY');
// => Wed, Jul 09 2025
```
### CommonJS
```typescript
const { format } = require('date-and-time');
format(new Date(), 'ddd, MMM DD YYYY');
// => Wed, Jul 09 2025
```
## CDN Usage
### Via jsDelivr
```html
```
### Via unpkg
```html
```
## Migration
Version `4.x` has been completely rewritten in TypeScript and some features from `3.x` are no longer compatible. The main changes are as follows:
- The `timezone` and `timespan` plugins have been integrated into the main library
- Tree shaking is now supported
- Supports `ES2021` and no longer supports older browsers
For details, please refer to [migration.md](https://github.com/knowledgecode/date-and-time/blob/master/docs/migration.md).
## API
For comprehensive documentation and examples, visit: **[GitHub Pages](https://knowledgecode.github.io/date-and-time/)**
## License
MIT
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
================================================
FILE: astro.config.mjs
================================================
import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
export default defineConfig({
outDir: './pages',
srcDir: './docs',
site: 'https://knowledgecode.github.io',
base: '/date-and-time',
trailingSlash: 'never',
devToolbar: {
enabled: false,
},
markdown: {
shikiConfig: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
},
},
integrations: [
starlight({
customCss: [
'./docs/styles/custom.css',
],
title: 'date-and-time',
description: 'The simplest, most intuitive date and time library',
logo: {
src: './docs/assets/logo.png',
alt: 'date-and-time',
},
social: [
{ icon: 'github', label: 'GitHub', href: 'https://github.com/knowledgecode/date-and-time' },
{ icon: 'npm', label: 'npm', href: 'https://www.npmjs.com/package/date-and-time' },
],
sidebar: [
{
label: 'Getting Started',
items: [
{ label: 'Introduction', link: '/guide' },
{ label: 'Installation', link: '/guide/installation' },
{ label: 'Quick Start', link: '/guide/quick-start' },
],
},
{
label: 'API Reference',
collapsed: true,
items: [
{ label: 'Overview', link: '/api' },
{
label: 'Core Functions',
items: [
{ label: 'format()', link: '/api/format' },
{ label: 'parse()', link: '/api/parse' },
{ label: 'compile()', link: '/api/compile' },
{ label: 'preparse()', link: '/api/preparse' },
{ label: 'isValid()', link: '/api/isvalid' },
{ label: 'transform()', link: '/api/transform' },
{ label: 'addYears()', link: '/api/addyears' },
{ label: 'addMonths()', link: '/api/addmonths' },
{ label: 'addDays()', link: '/api/adddays' },
{ label: 'addHours()', link: '/api/addhours' },
{ label: 'addMinutes()', link: '/api/addminutes' },
{ label: 'addSeconds()', link: '/api/addseconds' },
{ label: 'addMilliseconds()', link: '/api/addmilliseconds' },
{ label: 'subtract()', link: '/api/subtract' },
],
},
{
label: 'Utility Functions',
items: [
{ label: 'isLeapYear()', link: '/api/utils/isleapyear' },
{ label: 'isSameDay()', link: '/api/utils/issameday' },
{ label: 'getDaysInMonth()', link: '/api/utils/getdaysinmonth' },
{ label: 'getISOWeekYear()', link: '/api/utils/getisoweekyear' },
{ label: 'getISOWeek()', link: '/api/utils/getisoweek' },
],
},
],
},
{ label: 'Locales', link: '/locales' },
{ label: 'Timezones', link: '/timezones' },
{ label: 'Plugins', link: '/plugins' },
{ label: 'Migration Guide', link: '/migration' },
],
}),
],
});
================================================
FILE: docs/api/addDays.md
================================================
---
title: addDays()
---
Adds or subtracts days from a Date object. Handles month boundaries, leap years, and daylight saving time transitions properly.
## Syntax
```typescript
addDays(dateObj, days[, timeZone])
```
### Parameters
| Parameter | Type | Required | Description |
|------------|----------------------|----------|---------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `days` | `number` | Yes | Number of days to add (positive) or subtract (negative) |
| `timeZone` | `TimeZone \| string` | No | Timezone for the calculation |
### Returns
`Date` - A new Date object with the specified number of days added or subtracted
## Basic Examples
### Adding and Subtracting Days
```typescript
import { addDays } from 'date-and-time';
const date = new Date(2024, 7, 15); // August 15, 2024
// Add days
const future = addDays(date, 10);
console.log(future); // August 25, 2024
// Subtract days
const past = addDays(date, -5);
console.log(past); // August 10, 2024
```
### Daylight Saving Time Aware Calculations
```typescript
import { addDays } from 'date-and-time';
// Working with specific timezones
const nyDate = new Date('2024-03-10T05:00:00Z'); // March 10, 2024 05:00 UTC (DST transition day)
// Add 30 days in New York timezone
const futureNY = addDays(nyDate, 30, 'America/New_York');
console.log(futureNY); // April 9, 2024 04:00 UTC (EDT, DST adjusted)
// UTC calculation for comparison
const futureUTC = addDays(nyDate, 30, 'UTC');
console.log(futureUTC); // April 9, 2024 05:00 UTC (same time, no DST adjustment)
```
## Use Cases
### Work Day Calculations
```typescript
function addBusinessDays(date: Date, businessDays: number): Date {
let result = new Date(date);
let daysToAdd = businessDays;
while (daysToAdd > 0) {
result = addDays(result, 1);
const dayOfWeek = result.getDay();
// Skip weekends (0 = Sunday, 6 = Saturday)
if (dayOfWeek !== 0 && dayOfWeek !== 6) {
daysToAdd--;
}
}
return result;
}
const friday = new Date(2024, 7, 23); // August 23, 2024 (Friday)
const nextBusinessDay = addBusinessDays(friday, 1);
console.log(nextBusinessDay); // August 26, 2024 (Monday)
```
### Date Range Generation
```typescript
function generateDateRange(startDate: Date, endDate: Date): Date[] {
const dates: Date[] = [];
let currentDate = new Date(startDate);
while (currentDate <= endDate) {
dates.push(new Date(currentDate));
currentDate = addDays(currentDate, 1);
}
return dates;
}
const start = new Date(2024, 7, 28); // August 28, 2024
const end = new Date(2024, 8, 3); // September 3, 2024
const dateRange = generateDateRange(start, end);
console.log(dateRange);
// [Aug 28, Aug 29, Aug 30, Aug 31, Sep 1, Sep 2, Sep 3]
```
## Immutability
`addDays()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 7, 15);
const modifiedDate = addDays(originalDate, 10);
console.log(originalDate); // August 15, 2024 (unchanged)
console.log(modifiedDate); // August 25, 2024 (new object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addHours.md
================================================
---
title: addHours()
---
Adds or subtracts hours from a Date object.
## Syntax
```typescript
addHours(dateObj, hours)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|----------|----------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `hours` | `number` | Yes | Number of hours to add (positive) or subtract (negative) |
### Returns
`Date` - A new Date object with the specified number of hours added or subtracted
## Basic Examples
### Adding and Subtracting Hours
```typescript
import { addHours } from 'date-and-time';
const date = new Date(2024, 7, 15, 14, 30, 45); // August 15, 2024 14:30:45
// Add hours
const future = addHours(date, 6);
console.log(future); // August 15, 2024 20:30:45
// Subtract hours
const past = addHours(date, -3);
console.log(past); // August 15, 2024 11:30:45
```
## Use Cases
### Work Hours Calculation
```typescript
function addWorkingHours(startDate: Date, workHours: number): Date {
// Assuming 8-hour work days, 5 days a week
const hoursPerDay = 8;
const result = new Date(startDate);
let remainingHours = workHours;
while (remainingHours > 0) {
const dayOfWeek = result.getDay();
// Skip weekends
if (dayOfWeek === 0 || dayOfWeek === 6) {
result.setDate(result.getDate() + 1);
continue;
}
const hoursToAdd = Math.min(remainingHours, hoursPerDay);
const newTime = addHours(result, hoursToAdd);
result.setTime(newTime.getTime());
remainingHours -= hoursToAdd;
if (remainingHours > 0) {
// Move to next day, reset to start of work day
result.setDate(result.getDate() + 1);
result.setHours(9, 0, 0, 0); // 9 AM start
}
}
return result;
}
const projectStart = new Date(2024, 7, 15, 9, 0); // August 15, 2024 09:00
const completion = addWorkingHours(projectStart, 24); // 24 working hours
console.log(completion);
```
### Shift Scheduling
```typescript
function generateShiftSchedule(startDate: Date, shiftHours: number, numberOfShifts: number): Date[] {
const shifts: Date[] = [];
let currentStart = new Date(startDate);
for (let i = 0; i < numberOfShifts; i++) {
shifts.push(new Date(currentStart));
currentStart = addHours(currentStart, shiftHours);
}
return shifts;
}
const firstShift = new Date(2024, 7, 15, 6, 0); // August 15, 2024 06:00
const schedule = generateShiftSchedule(firstShift, 8, 5); // 5 shifts of 8 hours each
console.log(schedule);
// [
// August 15, 2024 06:00, // Shift 1
// August 15, 2024 14:00, // Shift 2
// August 15, 2024 22:00, // Shift 3
// August 16, 2024 06:00, // Shift 4
// August 16, 2024 14:00 // Shift 5
// ]
```
## Immutability
`addHours()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 7, 15, 14, 30);
const modifiedDate = addHours(originalDate, 5);
console.log(originalDate); // August 15, 2024 14:30:00 (unchanged)
console.log(modifiedDate); // August 15, 2024 19:30:00 (new object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addMilliseconds.md
================================================
---
title: addMilliseconds()
---
Adds or subtracts milliseconds from a Date object.
## Syntax
```typescript
addMilliseconds(dateObj, milliseconds)
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------|----------|-----------------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `milliseconds` | `number` | Yes | Number of milliseconds to add (positive) or subtract (negative) |
### Returns
`Date` - A new Date object with the specified number of milliseconds added or subtracted
## Basic Examples
### Adding and Subtracting Milliseconds
```typescript
import { addMilliseconds } from 'date-and-time';
const date = new Date(2024, 7, 15, 14, 30, 45, 123); // August 15, 2024 14:30:45.123
// Add milliseconds
const future = addMilliseconds(date, 500);
console.log(future); // August 15, 2024 14:30:45.623
// Subtract milliseconds
const past = addMilliseconds(date, -200);
console.log(past); // August 15, 2024 14:30:44.923
```
## Use Cases
### High-Precision Timing
```typescript
class PrecisionTimer {
private startTime: Date
start(): void {
this.startTime = new Date();
}
elapsedMs(): number {
if (!this.startTime) {
return 0;
}
return Date.now() - this.startTime.getTime();
}
addPreciseDelay(baseTime: Date, delayMs: number): Date {
return addMilliseconds(baseTime, delayMs);
}
scheduleNextExecution(intervalMs: number): Date {
return addMilliseconds(new Date(), intervalMs);
}
}
const timer = new PrecisionTimer();
timer.start();
// ... perform operations ...
console.log(`Operation took: ${timer.elapsedMs()}ms`);
const nextRun = timer.scheduleNextExecution(150); // Schedule 150ms from now
console.log(`Next execution at: ${nextRun.toISOString()}`);
```
### Animation Frame Scheduling
```typescript
function createAnimationSchedule(startTime: Date, frameRate: number, duration: number) {
const frameInterval = 1000 / frameRate; // ms per frame
const totalFrames = Math.floor((duration * 1000) / frameInterval);
const schedule: { frame: number, time: Date }[] = [];
for (let frame = 0; frame < totalFrames; frame++) {
const frameTime = addMilliseconds(startTime, frame * frameInterval);
schedule.push({ frame, time: frameTime });
}
return schedule;
}
const animationStart = new Date(); // Animation starts now
const frames = createAnimationSchedule(animationStart, 60, 2); // 60 FPS for 2 seconds
console.log(`Animation has ${frames.length} frames`);
console.log('First 5 frames:');
frames.slice(0, 5).forEach(f => {
console.log(`Frame ${f.frame}: ${f.time.toISOString()}`);
});
```
## Immutability
`addMilliseconds()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 7, 15, 14, 30, 45, 123);
const modifiedDate = addMilliseconds(originalDate, 500);
console.log(originalDate); // August 15, 2024 14:30:45.123 (unchanged)
console.log(modifiedDate); // August 15, 2024 14:30:45.623 (new object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addMinutes.md
================================================
---
title: addMinutes()
---
Adds or subtracts minutes from a Date object.
## Syntax
```typescript
addMinutes(dateObj, minutes)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|----------|------------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `minutes` | `number` | Yes | Number of minutes to add (positive) or subtract (negative) |
### Returns
`Date` - A new Date object with the specified number of minutes added or subtracted
## Basic Examples
### Adding and Subtracting Minutes
```typescript
import { addMinutes } from 'date-and-time';
const date = new Date(2024, 7, 15, 14, 30, 45); // August 15, 2024 14:30:45
// Add minutes
const future = addMinutes(date, 25);
console.log(future); // August 15, 2024 14:55:45
// Subtract minutes
const past = addMinutes(date, -15);
console.log(past); // August 15, 2024 14:15:45
```
## Use Cases
### Appointment Scheduling
```typescript
function scheduleAppointments(startTime: Date, appointmentLength: number, count: number): Date[] {
const appointments: Date[] = [];
let currentTime = new Date(startTime);
for (let i = 0; i < count; i++) {
appointments.push(new Date(currentTime));
currentTime = addMinutes(currentTime, appointmentLength);
}
return appointments;
}
const firstAppointment = new Date(2024, 7, 15, 9, 0); // August 15, 2024 09:00
const schedule = scheduleAppointments(firstAppointment, 30, 6); // 6 appointments, 30 min each
console.log(schedule);
// [
// August 15, 2024 09:00,
// August 15, 2024 09:30,
// August 15, 2024 10:00,
// August 15, 2024 10:30,
// August 15, 2024 11:00,
// August 15, 2024 11:30
// ]
```
### Pomodoro Timer
```typescript
class PomodoroTimer {
private workMinutes = 25;
private shortBreakMinutes = 5;
private longBreakMinutes = 15;
createSession(startTime: Date, cycles: number = 4) {
const schedule: { type: string, start: Date, end: Date }[] = [];
let currentTime = new Date(startTime);
for (let i = 0; i < cycles; i++) {
// Work session
const workEnd = addMinutes(currentTime, this.workMinutes);
schedule.push({
type: 'work',
start: new Date(currentTime),
end: workEnd
});
currentTime = workEnd;
// Break session
const breakMinutes = (i === cycles - 1) ? this.longBreakMinutes : this.shortBreakMinutes;
const breakEnd = addMinutes(currentTime, breakMinutes);
schedule.push({
type: i === cycles - 1 ? 'long-break' : 'short-break',
start: new Date(currentTime),
end: breakEnd
});
currentTime = breakEnd;
}
return schedule;
}
}
const pomodoro = new PomodoroTimer();
const session = pomodoro.createSession(new Date(2024, 7, 15, 9, 0));
console.log(session);
```
## Immutability
`addMinutes()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 7, 15, 14, 30);
const modifiedDate = addMinutes(originalDate, 45);
console.log(originalDate); // August 15, 2024 14:30:00 (unchanged)
console.log(modifiedDate); // August 15, 2024 15:15:00 (new object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addMonths.md
================================================
---
title: addMonths()
---
Adds or subtracts months from a Date object. Handles month boundaries, leap years, and varying month lengths appropriately.
## Syntax
```typescript
addMonths(dateObj, months[, timeZone])
```
### Parameters
| Parameter | Type | Required | Description |
|------------|----------------------|----------|-----------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `months` | `number` | Yes | Number of months to add (positive) or subtract (negative) |
| `timeZone` | `TimeZone \| string` | No | Timezone for the calculation |
### Returns
`Date` - A new Date object with the specified number of months added or subtracted
## Basic Examples
### Adding and Subtracting Months
```typescript
import { addMonths } from 'date-and-time';
const date = new Date(2024, 0, 15); // January 15, 2024
// Add months
const future = addMonths(date, 6);
console.log(future); // July 15, 2024
// Subtract months
const past = addMonths(date, -3);
console.log(past); // October 15, 2023
```
### Daylight Saving Time Aware Calculations
```typescript
import { addMonths } from 'date-and-time';
// Working with specific timezones
const nyDate = new Date('2024-03-10T05:00:00Z'); // March 10, 2024 05:00 UTC (DST transition day)
// Add 6 months in New York timezone
const futureNY = addMonths(nyDate, 6, 'America/New_York');
console.log(futureNY); // September 10, 2024 04:00 UTC (EDT, DST adjusted)
// UTC calculation for comparison
const futureUTC = addMonths(nyDate, 6, 'UTC');
console.log(futureUTC); // September 10, 2024 05:00 UTC (same time, no DST adjustment)
```
## Use Cases
### Payment Due Dates
```typescript
function calculatePaymentSchedule(startDate: Date, months: number): Date[] {
const schedule: Date[] = [];
for (let i = 1; i <= months; i++) {
schedule.push(addMonths(startDate, i));
}
return schedule;
}
const loanStart = new Date(2024, 0, 15); // January 15, 2024
const payments = calculatePaymentSchedule(loanStart, 12);
console.log(payments);
// [February 15, March 15, April 15, ..., January 15]
```
### Quarterly Reports
```typescript
function getQuarterlyDates(year: number): Date[] {
const q1 = new Date(year, 0, 1); // January 1
return [
q1, // Q1
addMonths(q1, 3), // Q2 - April 1
addMonths(q1, 6), // Q3 - July 1
addMonths(q1, 9) // Q4 - October 1
];
}
const quarters2024 = getQuarterlyDates(2024);
console.log(quarters2024);
```
## Edge Cases and Behavior
### End-of-Month Dates
```typescript
const endOfMonth = new Date(2024, 0, 31); // January 31, 2024
console.log(addMonths(endOfMonth, 1)); // February 29, 2024 (Feb has 29 days)
console.log(addMonths(endOfMonth, 2)); // March 31, 2024 (back to 31st)
console.log(addMonths(endOfMonth, 3)); // April 30, 2024 (April has 30 days)
```
### February Edge Cases
```typescript
// February 28 in non-leap year
const feb28 = new Date(2025, 1, 28); // February 28, 2025
console.log(addMonths(feb28, 12)); // February 28, 2026
console.log(addMonths(feb28, -12)); // February 28, 2024 (leap year, but stays at 28)
// February 29 in leap year
const feb29 = new Date(2024, 1, 29); // February 29, 2024
console.log(addMonths(feb29, 1)); // March 29, 2024
console.log(addMonths(feb29, -1)); // January 29, 2024
```
## Immutability
`addMonths()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 0, 15);
const modifiedDate = addMonths(originalDate, 6);
console.log(originalDate); // January 15, 2024 (unchanged)
console.log(modifiedDate); // July 15, 2024 (new object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addSeconds.md
================================================
---
title: addSeconds()
---
Adds or subtracts seconds from a Date object.
## Syntax
```typescript
addSeconds(dateObj, seconds)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|----------|------------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `seconds` | `number` | Yes | Number of seconds to add (positive) or subtract (negative) |
### Returns
`Date` - A new Date object with the specified number of seconds added or subtracted
## Basic Examples
### Adding and Subtracting Seconds
```typescript
import { addSeconds } from 'date-and-time';
const date = new Date(2024, 7, 15, 14, 30, 45, 123); // August 15, 2024 14:30:45.123
// Add seconds
const future = addSeconds(date, 30);
console.log(future); // August 15, 2024 14:31:15.123
// Subtract seconds
const past = addSeconds(date, -20);
console.log(past); // August 15, 2024 14:30:25.123
```
## Use Cases
### Countdown Timers
```typescript
function createCountdown(duration: number): { start: Date, end: Date, remaining: () => number } {
const start = new Date();
const end = addSeconds(start, duration);
return {
start,
end,
remaining: () => Math.max(0, Math.floor((end.getTime() - Date.now()) / 1000))
};
}
const countdown = createCountdown(300); // 5 minute countdown
console.log(`Countdown ends at: ${countdown.end.toLocaleTimeString()}`);
console.log(`Time remaining: ${countdown.remaining()} seconds`);
// Use in a timer
const updateCountdown = () => {
const remaining = countdown.remaining();
if (remaining > 0) {
console.log(`${remaining} seconds left`);
setTimeout(updateCountdown, 1000);
} else {
console.log('Time up!');
}
};
updateCountdown();
```
### Precise Time Intervals
```typescript
function generateTimeIntervals(startTime: Date, intervalSeconds: number, count: number): Date[] {
const intervals: Date[] = [];
let currentTime = new Date(startTime);
for (let i = 0; i < count; i++) {
intervals.push(new Date(currentTime));
currentTime = addSeconds(currentTime, intervalSeconds);
}
return intervals;
}
const start = new Date(2024, 7, 15, 12, 0, 0); // August 15, 2024 12:00:00
const intervals = generateTimeIntervals(start, 15, 8); // Every 15 seconds, 8 times
console.log(intervals);
// [12:00:00, 12:00:15, 12:00:30, 12:00:45, 12:01:00, 12:01:15, 12:01:30, 12:01:45]
```
## Immutability
`addSeconds()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 7, 15, 14, 30, 45);
const modifiedDate = addSeconds(originalDate, 120);
console.log(originalDate); // August 15, 2024 14:30:45 (unchanged)
console.log(modifiedDate); // August 15, 2024 14:32:45 (new object);
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/addYears.md
================================================
---
title: addYears()
---
Adds or subtracts years from a Date object. Handles leap years and edge cases appropriately.
## Syntax
```typescript
addYears(dateObj, years[, timeZone])
```
### Parameters
| Parameter | Type | Required | Description |
|------------|----------------------|----------|----------------------------------------------------------|
| `dateObj` | `Date` | Yes | The base Date object |
| `years` | `number` | Yes | Number of years to add (positive) or subtract (negative) |
| `timeZone` | `TimeZone \| string` | No | Timezone for the calculation |
### Returns
`Date` - A new Date object with the specified number of years added or subtracted
## Basic Examples
### Adding and Subtracting Years
```typescript
import { addYears } from 'date-and-time';
const date = new Date(2024, 0, 15); // January 15, 2024
// Add years
const future = addYears(date, 3);
console.log(future); // January 15, 2027
// Subtract years
const past = addYears(date, -2);
console.log(past); // January 15, 2022
```
### Daylight Saving Time Aware Calculations
```typescript
import { addYears } from 'date-and-time';
// Working with specific timezones
const nyDate = new Date('2024-03-10T05:00:00Z'); // March 10, 2024 05:00 UTC (DST transition day)
// Add years in New York timezone
const futureNY = addYears(nyDate, 1, 'America/New_York');
console.log(futureNY); // March 10, 2025 04:00 UTC (EST, DST adjusted)
// UTC calculation for comparison
const futureUTC = addYears(nyDate, 1, 'UTC');
console.log(futureUTC); // March 10, 2025 05:00 UTC (same time, no DST adjustment)
```
## Use Cases
### Age Calculation
```typescript
function calculateAge(birthDate: Date): number {
const now = new Date();
const thisYear = addYears(birthDate, now.getFullYear() - birthDate.getFullYear());
if (thisYear > now) {
return now.getFullYear() - birthDate.getFullYear() - 1;
}
return now.getFullYear() - birthDate.getFullYear();
}
const birthDate = new Date(1990, 6, 15); // July 15, 1990;
console.log(calculateAge(birthDate)); // Current age
```
### Financial Year Calculations
```typescript
function getFinancialYearEnd(date: Date): Date {
const currentYear = date.getFullYear();
const financialYearEnd = new Date(currentYear, 2, 31); // March 31
if (date <= financialYearEnd) {
return financialYearEnd;
} else {
return addYears(financialYearEnd, 1); // Next year's March 31
}
}
const someDate = new Date(2024, 5, 15); // June 15, 2024
console.log(getFinancialYearEnd(someDate)); // March 31, 2025
```
## Edge Cases and Behavior
### February 29 Handling
```typescript
// Starting from February 29 (leap year)
const feb29 = new Date(2024, 1, 29); // February 29, 2024
// Adding to non-leap years
console.log(addYears(feb29, 1)); // February 28, 2025
console.log(addYears(feb29, 2)); // February 28, 2026
console.log(addYears(feb29, 3)); // February 28, 2027
console.log(addYears(feb29, 4)); // February 29, 2028 (leap year)
```
### Negative Years
```typescript
const date = new Date(2024, 6, 15); // July 15, 2024
// Go back in time
console.log(addYears(date, -10)); // July 15, 2014
console.log(addYears(date, -100)); // July 15, 1924
```
## Immutability
`addYears()` does not modify the original Date object:
```typescript
const originalDate = new Date(2024, 0, 15);
const modifiedDate = addYears(originalDate, 5);
console.log(originalDate); // January 15, 2024 (unchanged)
console.log(modifiedDate); // January 15, 2029 (new object)
```
## See Also
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
- [`subtract()`](./subtract) - Calculate differences with Duration objects
================================================
FILE: docs/api/compile.md
================================================
---
title: compile()
---
Precompiles a format string into a reusable compiled object for improved performance when the same format pattern is used repeatedly.
## Syntax
```typescript
compile(formatString)
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------|----------|-------------------------------|
| `formatString` | `string` | Yes | The format pattern to compile |
### Returns
`CompiledObject` - A compiled format object that can be reused with `format()` and `parse()`
## Basic Usage
```typescript
import { compile, format, parse } from 'date-and-time';
// Compile once
const pattern = compile('YYYY-MM-DD HH:mm:ss');
// Use multiple times - much faster than parsing the format string each time
const date1 = new Date(2025, 7, 23, 14, 30, 45);
const date2 = new Date(2025, 7, 24, 9, 15, 30);
const formatted1 = format(date1, pattern); // => 2025-08-23 14:30:45
const formatted2 = format(date2, pattern); // => 2025-08-24 09:15:30
// Also works with parse()
const parsed = parse('2025-08-25 16:20:10', pattern);
```
## Performance Benefits
The `compile()` function provides significant performance improvements for repeated operations:
### Without Compilation (Slower)
```typescript
import { format } from 'date-and-time';
const dates = Array.from({ length: 1000 }, () => new Date());
// Format string is parsed 1000 times
dates.forEach(date => {
format(date, 'YYYY-MM-DD HH:mm:ss.SSS [GMT]ZZ');
});
```
### With Compilation (Faster)
```typescript
import { format, compile } from 'date-and-time';
const dates = Array.from({ length: 1000 }, () => new Date());
const pattern = compile('YYYY-MM-DD HH:mm:ss.SSS [GMT]ZZ');
// Format string is compiled once, reused 1000 times
dates.forEach(date => {
format(date, pattern); // Much faster!
});
```
## Real-world Examples
### Logging System
```typescript
import { compile, format } from 'date-and-time';
class Logger {
private timestampPattern = compile('\\[YYYY-MM-DD HH:mm:ss.SSS\\]');
log(level: string, message: string) {
const timestamp = format(new Date(), this.timestampPattern);
console.log(`${timestamp} ${level.toUpperCase()}: ${message}`);
}
}
const logger = new Logger();
logger.log('info', 'Application started');
logger.log('error', 'Database connection failed');
// [2025-08-23 14:30:45.123] INFO: Application started
// [2025-08-23 14:30:45.124] ERROR: Database connection failed
```
### Template Engine Integration
```typescript
import { compile, format } from 'date-and-time';
class EmailTemplateEngine {
private patterns = {
timestamp: compile('YYYY-MM-DD HH:mm:ss'),
friendly: compile('MMMM D, YYYY [at] h:mm A'),
fileDate: compile('YYYY-MM-DD')
};
generateEmail(user: string, data: any): string {
const now = new Date();
return `
Dear ${user},
This report was generated on ${format(now, this.patterns.friendly)}.
System timestamp: ${format(now, this.patterns.timestamp)}
Report date: ${format(data.reportDate, this.patterns.fileDate)}
Best regards,
System
`.trim();
}
}
const engine = new EmailTemplateEngine();
const email = engine.generateEmail('John', {
reportDate: new Date(2025, 7, 23)
});
```
### API Response Formatting
```typescript
import { compile, format } from 'date-and-time';
class ApiService {
private isoPattern = compile('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
private friendlyPattern = compile('MMMM D, YYYY [at] h:mm A');
formatResponse(data: any[]) {
return data.map(item => ({
...item,
createdAt: format(item.createdAt, this.isoPattern, { timeZone: 'UTC' }),
createdAtFriendly: format(item.createdAt, this.friendlyPattern)
}));
}
}
```
### Batch File Operations
```typescript
import { compile, format } from 'date-and-time';
import { writeFileSync } from 'fs';
const filenamePattern = compile('YYYY-MM-DD_HH-mm-ss');
function generateReports(data: any[]) {
const timestamp = format(new Date(), filenamePattern);
data.forEach((report, index) => {
const filename = `report_${index}_${timestamp}.json`;
writeFileSync(filename, JSON.stringify(report));
});
}
```
## Advanced Usage
### Multiple Compiled Patterns
```typescript
import { compile, format } from 'date-and-time';
import en from 'date-and-time/locales/en';
import ja from 'date-and-time/locales/ja';
class MultiFormatHandler {
private patterns = {
iso: compile('YYYY-MM-DD[T]HH:mm:ss[Z]'),
friendly: compile('MMMM D, YYYY [at] h:mm A'),
japanese: compile('YYYY年M月D日(ddd) HH:mm'),
filename: compile('YYYYMMDD_HHmmss')
};
format(date: Date, type: keyof typeof this.patterns) {
const pattern = this.patterns[type];
switch (type) {
case 'iso':
return format(date, pattern, { timeZone: 'UTC' });
case 'japanese':
return format(date, pattern, { locale: ja });
default:
return format(date, pattern);
}
}
}
const handler = new MultiFormatHandler();
const date = new Date();
console.log(handler.format(date, 'iso')); // => 2025-08-23T14:30:45Z
console.log(handler.format(date, 'friendly')); // => August 23, 2025 at 2:30 PM
console.log(handler.format(date, 'japanese')); // => 2025年8月23日(土) 14:30
console.log(handler.format(date, 'filename')); // => 20250823_143045
```
### Conditional Compilation
```typescript
import { compile, format } from 'date-and-time';
class SmartFormatter {
private cache = new Map();
private getCompiledPattern(formatString: string) {
if (!this.cache.has(formatString)) {
this.cache.set(formatString, compile(formatString));
}
return this.cache.get(formatString);
}
format(date: Date, formatString: string, options?: any) {
const pattern = this.getCompiledPattern(formatString);
return format(date, pattern, options);
}
}
const formatter = new SmartFormatter();
// First call compiles the pattern
formatter.format(new Date(), 'YYYY-MM-DD');
// Subsequent calls reuse the compiled pattern
formatter.format(new Date(), 'YYYY-MM-DD'); // Faster!
```
## Best Practices
### 1. Compile Once, Use Many Times
```typescript
// ✅ Good - compile once
const pattern = compile('YYYY-MM-DD HH:mm:ss');
for (const date of dates) {
format(date, pattern);
}
// ❌ Bad - compiles every time
for (const date of dates) {
format(date, 'YYYY-MM-DD HH:mm:ss');
}
```
### 2. Cache Compiled Patterns
```typescript
// ✅ Good - cached patterns
class DateFormatter {
private static patterns = {
iso: compile('YYYY-MM-DD[T]HH:mm:ss[Z]'),
short: compile('MM/DD/YYYY'),
long: compile('MMMM D, YYYY')
};
static format(date: Date, type: keyof typeof DateFormatter.patterns) {
return format(date, DateFormatter.patterns[type]);
}
}
```
### 3. Lazy Compilation
```typescript
// ✅ Good - lazy compilation for dynamic patterns
class DynamicFormatter {
private cache = new Map();
format(date: Date, pattern: string) {
if (!this.cache.has(pattern)) {
this.cache.set(pattern, compile(pattern));
}
return format(date, this.cache.get(pattern)!);
}
}
```
## See Also
- [`format()`](./format) - Format Date objects using compiled patterns
- [`parse()`](./parse) - Parse date strings using compiled patterns
- [`preparse()`](./preparse) - Parse and return intermediate parsing results
- [`transform()`](./transform) - Transform date strings between formats
================================================
FILE: docs/api/format.md
================================================
---
title: format()
---
Formats a Date object according to the specified format string.
## Syntax
```typescript
format(dateObj, formatString[, options])
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------------------------|----------|--------------------------------------|
| `dateObj` | `Date` | Yes | The Date object to format |
| `formatString` | `string \| CompiledObject` | Yes | The format string or compiled object |
| `options` | `FormatterOptions` | No | Formatter options for customization |
### Returns
`string` - The formatted date string
## Basic Examples
```typescript
import { format } from 'date-and-time';
const now = new Date();
format(now, 'YYYY/MM/DD HH:mm:ss');
// => 2025/08/23 14:30:45
format(now, 'ddd, MMM DD YYYY');
// => Sat, Aug 23 2025
format(now, 'hh:mm A [GMT]Z');
// => 02:30 PM GMT-0700
```
## Format Tokens
### Date Tokens
| Token | Description | Output Examples |
|--------|----------------------------|-------------------|
| `YYYY` | 4-digit year | 0999, 2015 |
| `YY` | 2-digit year | 99, 01, 15 |
| `Y` | Year without zero padding | 2, 44, 888, 2015 |
| `MMMM` | Full month name | January, December |
| `MMM` | Short month name | Jan, Dec |
| `MM` | Month (01-12) | 01, 12 |
| `M` | Month without zero padding | 1, 12 |
| `DD` | Day (01-31) | 02, 31 |
| `D` | Day without zero padding | 2, 31 |
### Day of Week Tokens
| Token | Description | Output Examples |
|--------|---------------------|-----------------|
| `dddd` | Full day name | Friday, Sunday |
| `ddd` | Short day name | Fri, Sun |
| `dd` | Very short day name | Fr, Su |
### Time Tokens
| Token | Description | Output Examples |
|-------|---------------------------------------------|-----------------|
| `HH` | Hour in 24-hour format | 23, 08 |
| `H` | Hour in 24-hour format without zero padding | 23, 8 |
| `hh` | Hour in 12-hour format | 11, 08 |
| `h` | Hour in 12-hour format without zero padding | 11, 8 |
| `mm` | Minutes | 14, 07 |
| `m` | Minutes without zero padding | 14, 7 |
| `ss` | Seconds | 05, 10 |
| `s` | Seconds without zero padding | 5, 10 |
| `SSS` | 3-digit milliseconds | 753, 022 |
| `SS` | 2-digit milliseconds | 75, 02 |
| `S` | 1-digit milliseconds | 7, 0 |
### AM/PM Tokens
| Token | Description | Output Examples |
|-------|--------------------------------|-----------------|
| `A` | Uppercase AM/PM | AM, PM |
| `AA` | Uppercase AM/PM (with periods) | A.M., P.M. |
| `a` | Lowercase AM/PM | am, pm |
| `aa` | Lowercase AM/PM (with periods) | a.m., p.m. |
### Timezone Tokens
| Token | Description | Output Examples |
|-------|----------------------------|-----------------|
| `Z` | Timezone offset | +0100, -0800 |
| `ZZ` | Timezone offset with colon | +01:00, -08:00 |
### Plugin Tokens
Additional tokens available with plugins:
| Token | Description | Output Examples | Plugin Required |
|--------|-------------------------------------|-----------------------|-----------------|
| `DDD` | Ordinal representation | 1st, 2nd, 3rd | ordinal |
| `Q` | Quarter of year | 1, 2, 3, 4 | quarter |
| `t` | Unix timestamp (seconds) | 0, 1000000000 | timestamp |
| `T` | Unix timestamp (milliseconds) | 0, 1000000000000 | timestamp |
| `W` | ISO week number | 1, 27, 53 | week |
| `WW` | ISO week number (zero-padded) | 01, 27, 53 | week |
| `G` | ISO week year | 2024, 2025 | week |
| `GG` | ISO week year (2-digit zero-padded) | 24, 25 | week |
| `GGGG` | ISO week year (4-digit zero-padded) | 2024, 2025 | week |
| `z` | Short timezone name | PST, EST | zonename |
| `zz` | Long timezone name | Pacific Standard Time | zonename |
For available plugins, see the [`plugins`](#plugins) option in FormatterOptions.
## FormatterOptions
The `FormatterOptions` object allows you to customize the formatting behavior:
```typescript
interface FormatterOptions {
locale?: Locale;
timeZone?: TimeZone | string;
numeral?: Numeral;
calendar?: 'gregory' | 'buddhist';
hour12?: 'h11' | 'h12';
hour24?: 'h23' | 'h24';
plugins?: FormatterPlugin[];
}
```
### locale
**Type**: `Locale`
**Default**: `en` (English)
Specifies the locale for localized formatting of month names, day names, and meridiem indicators.
```typescript
import { format } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
import es from 'date-and-time/locales/es';
const date = new Date();
// Japanese formatting
format(date, 'YYYY年M月D日(ddd)', { locale: ja });
// => 2025年8月23日(土)
// Spanish formatting
format(date, 'dddd, D [de] MMMM [de] YYYY', { locale: es });
// => sábado, 23 de agosto de 2025
```
For a complete list of all supported locales with import examples, see [Supported Locales](../locales).
### timeZone
**Type**: `TimeZone | string`
**Default**: `undefined` (local timezone)
Converts the date to the specified timezone before formatting.
```typescript
import { format } from 'date-and-time';
const date = new Date();
format(date, 'YYYY-MM-DD HH:mm:ss [JST]', { timeZone: 'Asia/Tokyo' });
// => 2025-08-23 23:30:45 JST
format(date, 'YYYY-MM-DD HH:mm:ss [EST]', { timeZone: 'America/New_York' });
// => 2025-08-23 09:30:45 EST
format(date, 'YYYY-MM-DD HH:mm:ss [UTC]', { timeZone: 'UTC' });
// => 2025-08-23 14:30:45 UTC
```
For a complete list of all supported timezones, see [Supported Timezones](../timezones).
### numeral
**Type**: `Numeral`
**Default**: `latn` (Latin numerals)
Specifies the numeral system for formatting numbers.
```typescript
import { format } from 'date-and-time';
import arab from 'date-and-time/numerals/arab';
import beng from 'date-and-time/numerals/beng';
const date = new Date();
// Arabic-Indic numerals
format(date, 'DD/MM/YYYY', { numeral: arab });
// => ٠٨/٠٧/٢٠٢٥
// Bengali numerals
format(date, 'DD/MM/YYYY', { numeral: beng });
// => ০৮/০৭/২০২৫
```
**Available numeral systems:**
- `latn` - Latin numerals (0-9) - default
- `arab` - Arabic-Indic numerals (٠-٩)
- `arabext` - Extended Arabic-Indic numerals (۰-۹)
- `beng` - Bengali numerals (০-৯)
- `mymr` - Myanmar numerals (၀-၉)
### calendar
**Type**: `"gregory" | "buddhist"`
**Default**: `"gregory"`
Specifies the calendar system for date calculations.
```typescript
import { format } from 'date-and-time';
const date = new Date();
// Gregorian calendar (default)
format(date, 'MMMM D, YYYY');
// => August 23, 2025
// Buddhist calendar (543 years ahead)
format(date, 'MMMM D, YYYY', { calendar: 'buddhist' });
// => August 23, 2568
```
### hour12
**Type**: `"h11" | "h12"`
**Default**: `"h12"`
Controls the 12-hour format interpretation. Use h11 for 11-hour format (0-11) or h12 for 12-hour format (1-12).
```typescript
import { format } from 'date-and-time';
const midnight = new Date(2025, 7, 23, 0, 30, 0); // 12:30 AM
// h12 format (1-12)
format(midnight, 'h:mm A', { hour12: 'h12' });
// => 12:30 AM
// h11 format (0-11)
format(midnight, 'h:mm A', { hour12: 'h11' });
// => 0:30 AM
```
### hour24
**Type**: `"h23" | "h24"`
**Default**: `"h23"`
Controls the 24-hour format interpretation. Use h23 for 23-hour format (0-23) or h24 for 24-hour format (1-24).
```typescript
import { format } from 'date-and-time';
const midnight = new Date(2025, 7, 23, 0, 30, 0);
// h23 format (0-23)
format(midnight, 'H:mm', { hour24: 'h23' });
// => 0:30
// h24 format (1-24)
format(midnight, 'H:mm', { hour24: 'h24' });
// => 24:30
```
### plugins
**Type**: `FormatterPlugin[]`
**Default**: `undefined`
Enables additional format tokens provided by plugins. Plugins extend the formatter with special tokens that are not included in the core library.
```typescript
import { format } from 'date-and-time';
import { formatter as ordinal } from 'date-and-time/plugins/ordinal';
import { formatter as zonename } from 'date-and-time/plugins/zonename';
const date = new Date();
// Use ordinal plugin
format(date, 'MMMM DDD, YYYY', { plugins: [ordinal] });
// => August 23rd, 2025
// Use zonename plugin
format(date, 'YYYY-MM-DD HH:mm z', { plugins: [zonename] });
// => 2025-08-23 14:30 PDT
// Use multiple plugins together
format(date, 'MMMM DDD, YYYY h:mm A zz', { plugins: [ordinal, zonename] });
// => August 23rd, 2025 2:30 PM Pacific Daylight Time
```
For a complete list of available plugins, see [Plugins](../plugins).
## Advanced Usage
### Comments in Format Strings
Parts of the format string enclosed in square brackets are output literally:
```typescript
import { format } from 'date-and-time';
const date = new Date();
format(date, '[Today is] dddd, MMMM D, YYYY');
// => Today is Saturday, August 23, 2025
format(date, 'YYYY-MM-DD[T]HH:mm:ss[Z]');
// => 2025-08-23T14:30:45Z
format(date, '[Report generated on] YYYY/MM/DD [at] HH:mm');
// => Report generated on 2025/08/23 at 14:30
// Escape square brackets to output them literally
format(date, '\\[YYYY-MM-DD HH:mm:ss\\]');
// => [2025-08-23 14:30:45]
```
### Complex Localized Formatting
```typescript
import { format } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
const date = new Date();
format(date, 'YYYY年MMMM月D日dddd Ah:mm:ss [GMT]Z', {
timeZone: 'Asia/Tokyo',
locale: ja
});
// => 2025年8月23日土曜日 午後11:30:45 GMT+0900
```
### Business and Technical Formats
```typescript
import { format } from 'date-and-time';
const date = new Date();
// ISO 8601 format
format(date, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]', { timeZone: 'UTC' });
// => 2025-08-23T14:30:45.123Z
// RFC 2822 format
format(date, 'ddd, DD MMM YYYY HH:mm:ss ZZ');
// => Sat, 23 Aug 2025 14:30:45 +09:00
// Log timestamp
format(date, '\\[YYYY-MM-DD HH:mm:ss.SSS]\\');
// => [2025-08-23 14:30:45.123]
// File naming
format(date, 'YYYYMMDD_HHmmss');
// => 20250823_143045
```
## Performance Considerations
For repeated formatting with the same pattern, use [`compile()`](./compile) to precompile the format string:
```typescript
import { format, compile } from 'date-and-time';
// Compile once
const pattern = compile('YYYY-MM-DD HH:mm:ss');
// Reuse for better performance
const dates = [new Date(), new Date(), new Date()];
dates.forEach(date => {
console.log(format(date, pattern));
});
```
## See Also
- [`compile()`](./compile) - Precompile format patterns for performance
- [`transform()`](./transform) - Transform date strings between formats
================================================
FILE: docs/api/index.md
================================================
---
title: API Reference
---
Welcome to the comprehensive API reference for date-and-time v4.x. This section provides detailed documentation for all available functions, types, and options.
## Core Functions
### Formatting and Parsing
| Function | Description |
|------------------------------|-----------------------------------------------|
| [`format()`](./format) | Convert Date objects to formatted strings |
| [`parse()`](./parse) | Parse date strings into Date objects |
| [`compile()`](./compile) | Precompile format patterns for performance |
| [`preparse()`](./preparse) | Parse and return intermediate parsing results |
| [`isValid()`](./isValid) | Validate date string formats |
| [`transform()`](./transform) | Transform date strings between formats |
### Date Arithmetic
| Function | Description |
|--------------------------------------------------------|--------------------------------------------------|
| [`addYears()`](./add-functions#addyears) | Add/subtract years from dates |
| [`addMonths()`](./add-functions#addmonths) | Add/subtract months from dates |
| [`addDays()`](./add-functions#adddays) | Add/subtract days from dates |
| [`addHours()`](./add-functions#addhours) | Add/subtract hours from dates |
| [`addMinutes()`](./add-functions#addminutes) | Add/subtract minutes from dates |
| [`addSeconds()`](./add-functions#addseconds) | Add/subtract seconds from dates |
| [`addMilliseconds()`](./add-functions#addmilliseconds) | Add/subtract milliseconds from dates |
| [`subtract()`](./subtract) | Calculate time differences with Duration objects |
### Utility Functions
| Function | Description |
|----------------------------------------------|----------------------------------------|
| [`isLeapYear()`](./utils/isLeapYear) | Check if a year is a leap year |
| [`isSameDay()`](./utils/isSameDay) | Check if two dates are on the same day |
| [`getDaysInMonth()`](./utils/getDaysInMonth) | Get the number of days in a month |
| [`getISOWeekYear()`](./utils/getISOWeekYear) | Get the ISO week year for a date |
| [`getISOWeek()`](./utils/getISOWeek) | Get the ISO week number for a date |
## Quick Examples
### Basic Usage
```typescript
import { format, parse, isValid } from 'date-and-time'
// Formatting
const date = new Date()
format(date, 'YYYY-MM-DD HH:mm:ss');
// => 2025-08-23 14:30:45
// Parsing
const parsed = parse('2025-08-23 14:30:45', 'YYYY-MM-DD HH:mm:ss');
// => Date object
// Validation
isValid('2025-02-29', 'YYYY-MM-DD'); // => false (not a leap year)
```
### With Options
```typescript
import { format } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
format(new Date(), 'YYYY年M月D日(ddd) HH:mm', {
locale: ja,
timeZone: 'Asia/Tokyo'
});
// => 2025年8月23日(土) 23:30
```
## Supported Locales
date-and-time supports 40+ locales. Import only the ones you need:
```typescript
// Examples
import ar from 'date-and-time/locales/ar'; // Arabic
import ja from 'date-and-time/locales/ja'; // Japanese
import es from 'date-and-time/locales/es'; // Spanish
import fr from 'date-and-time/locales/fr'; // French
import de from 'date-and-time/locales/de'; // German
import ru from 'date-and-time/locales/ru'; // Russian
import zhHans from 'date-and-time/locales/zh-Hans'; // Simplified Chinese
```
For a complete list of all supported locales with import examples, see [Supported Locales](../locales).
## Supported Timezones
Complete IANA timezone database support. Pass an IANA timezone name string directly to any function:
```typescript
format(new Date(), 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
format(new Date(), 'YYYY-MM-DD HH:mm:ss', { timeZone: 'America/New_York' });
```
For a complete list of all supported timezones, see [Supported Timezones](../timezones).
## Numeral Systems
Support for different numeral systems:
```typescript
import arab from 'date-and-time/numerals/arab'; // Arabic-Indic
import beng from 'date-and-time/numerals/beng'; // Bengali
import mymr from 'date-and-time/numerals/mymr'; // Myanmar
import latn from 'date-and-time/numerals/latn'; // Latin (default)
format(new Date(), 'DD/MM/YYYY', { numeral: arab });
// => ٠٨/٠٧/٢٠٢٥
```
## Error Handling
### Parse Failures
```typescript
import { parse, isValid } from 'date-and-time';
// Always check validity first
if (!isValid('invalid-date', 'YYYY-MM-DD')) {
throw new Error('Invalid date format');
}
// Or check parse results
const result = parse('invalid-date', 'YYYY-MM-DD');
if (isNaN(result.getTime())) {
throw new Error('Parse failed');
}
```
### Type Safety
```typescript
import { format, FormatterOptions } from 'date-and-time';
// TypeScript will catch type errors
const options: FormatterOptions = {
locale: 'invalid', // ❌ TypeScript error
timeZone: 123 // ❌ TypeScript error
};
```
## Performance Tips
1. **Use `compile()`** for repeated operations:
```typescript
const pattern = compile('YYYY-MM-DD HH:mm:ss');
// Reuse pattern for better performance
```
2. **Import only what you need**:
```typescript
import { format } from 'date-and-time'; // ✅ Tree-shakable
import * as date from 'date-and-time'; // ❌ Imports everything
```
## Migration from v3.x
If you're migrating from version 3.x, see the [Migration Guide](../migration) for detailed upgrade instructions and breaking changes.
================================================
FILE: docs/api/isValid.md
================================================
---
title: isValid()
---
Validates whether a date string conforms to the specified format pattern and represents a valid date.
## Syntax
```typescript
isValid(dateString, formatString[, options])
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------------------------|----------|------------------------------------------------------------------------------------|
| `dateString` | `string` | Yes | The date string to validate |
| `formatString` | `string \| CompiledObject` | Yes | The format pattern or compiled object |
| `options` | `ParserOptions` | No | Parser options for validation (see [`parse()`](./parse#parseroptions) for details) |
### Returns
`boolean` - `true` if the date string is valid and matches the format, `false` otherwise
## Basic Examples
```typescript
import { isValid } from 'date-and-time';
// Valid dates
isValid('2025-08-23', 'YYYY-MM-DD'); // => true
isValid('08/23/2025', 'MM/DD/YYYY'); // => true
isValid('14:30:45', 'HH:mm:ss'); // => true
isValid('2:30 PM', 'h:mm A'); // => true
// Invalid dates
isValid('2025-02-30', 'YYYY-MM-DD'); // => false (Feb 30th doesn't exist)
isValid('2025-13-01', 'YYYY-MM-DD'); // => false (month 13 doesn't exist)
isValid('25:30:00', 'HH:mm:ss'); // => false (hour 25 doesn't exist)
isValid('invalid-date', 'YYYY-MM-DD'); // => false (doesn't match format)
// Format mismatch
isValid('2025-08-23', 'MM/DD/YYYY'); // => false (wrong format)
isValid('08/23/2025', 'YYYY-MM-DD'); // => false (wrong format)
```
## Validation with Options
### Locale Validation
```typescript
import { isValid } from 'date-and-time';
import es from 'date-and-time/locales/es';
// Spanish month names
isValid('23 de agosto de 2025', 'D [de] MMMM [de] YYYY', { locale: es }); // => true
isValid('23 de invalid de 2025', 'D [de] MMMM [de] YYYY', { locale: es }); // => false
```
### Case-Insensitive Validation
```typescript
import { isValid } from 'date-and-time';
// Case-sensitive (default)
isValid('AUGUST 23, 2025', 'MMMM D, YYYY'); // => false
isValid('august 23, 2025', 'MMMM D, YYYY'); // => false
// Case-insensitive
isValid('AUGUST 23, 2025', 'MMMM D, YYYY', { ignoreCase: true }); // => true
isValid('august 23, 2025', 'MMMM D, YYYY', { ignoreCase: true }); // => true
isValid('August 23, 2025', 'MMMM D, YYYY'); // => true (correct case)
```
### defaultDate Validation
Use `defaultDate` to provide context for validation of partial date strings. The most practical use case is leap year-aware validation of month-day strings.
```typescript
import { isValid } from 'date-and-time';
// Leap day validation — result depends on the year
isValid('02-29', 'MM-DD', { defaultDate: { Y: 2024 } }); // => true (2024 is a leap year)
isValid('02-29', 'MM-DD', { defaultDate: { Y: 2023 } }); // => false (2023 is not a leap year)
isValid('02-29', 'MM-DD'); // => false (default year 1970 is not a leap year)
// Day range validation — depends on both year and month
isValid('29', 'D', { defaultDate: { Y: 2024, M: 2 } }); // => true (Feb 2024 has 29 days)
isValid('31', 'D', { defaultDate: { Y: 2024, M: 4 } }); // => false (April has 30 days)
```
**Note**: Values provided in `defaultDate` are also subject to range validation. For example, an out-of-range `H` value in `defaultDate` will cause `isValid()` to return `false`.
## Advanced Validation Patterns
### Multiple Format Validation
```typescript
import { isValid } from 'date-and-time';
function isValidDate(dateString: string): boolean {
const formats = [
'YYYY-MM-DD',
'MM/DD/YYYY',
'DD.MM.YYYY',
'MMMM D, YYYY',
'MMM D, YYYY'
];
return formats.some(format => isValid(dateString, format));
}
// Usage
console.log(isValidDate('2025-08-23')); // => true
console.log(isValidDate('08/23/2025')); // => true
console.log(isValidDate('23.08.2025')); // => true
console.log(isValidDate('August 23, 2025')); // => true
console.log(isValidDate('invalid-date')); // => false
```
### Business Rule Validation
```typescript
import { isValid, parse } from 'date-and-time';
function isBusinessDay(dateString: string, format: string): boolean {
// First check if it's a valid date
if (!isValid(dateString, format)) {
return false;
}
// Parse and check if it's a weekday
const date = parse(dateString, format);
const dayOfWeek = date.getDay();
// 0 = Sunday, 6 = Saturday
return dayOfWeek >= 1 && dayOfWeek <= 5;
}
// Usage
console.log(isBusinessDay('2025-08-23', 'YYYY-MM-DD')); // => false (Saturday)
console.log(isBusinessDay('2025-08-25', 'YYYY-MM-DD')); // => true (Monday)
```
### Range Validation
```typescript
import { isValid, parse } from 'date-and-time';
function isValidInRange(
dateString: string,
format: string,
minDate: Date,
maxDate: Date
): boolean {
if (!isValid(dateString, format)) {
return false;
}
const date = parse(dateString, format);
return date >= minDate && date <= maxDate;
}
// Usage
const min = new Date(2025, 0, 1); // Jan 1, 2025
const max = new Date(2025, 11, 31); // Dec 31, 2025
console.log(isValidInRange('2025-08-23', 'YYYY-MM-DD', min, max)); // => true
console.log(isValidInRange('2024-08-23', 'YYYY-MM-DD', min, max)); // => false
```
## Performance with Compiled Patterns
For repeated validation, use `compile()` for better performance:
```typescript
import { isValid, compile } from 'date-and-time';
// Compile once
const pattern = compile('YYYY-MM-DD HH:mm:ss');
// Validate multiple times (faster)
const dateStrings = [
'2025-08-23 14:30:45',
'2025-08-24 09:15:30',
'2025-02-30 12:00:00', // Invalid
'2025-08-25 16:45:20'
];
const validDates = dateStrings.filter(dateString =>
isValid(dateString, pattern)
);
console.log('Valid dates:', validDates);
// => ['2025-08-23 14:30:45', '2025-08-24 09:15:30', '2025-08-25 16:45:20']
```
## Common Use Cases
### Form Input Validation
```typescript
import { isValid, parse } from 'date-and-time';
class DateInputValidator {
static validateBirthDate(dateString: string): boolean {
if (!isValid(dateString, 'YYYY-MM-DD')) {
return false;
}
const date = parse(dateString, 'YYYY-MM-DD');
const now = new Date();
// Must be in the past and reasonable range
return date < now && date > new Date(1900, 0, 1);
}
static validateAppointment(dateString: string): boolean {
if (!isValid(dateString, 'YYYY-MM-DD HH:mm')) {
return false;
}
const date = parse(dateString, 'YYYY-MM-DD HH:mm');
const now = new Date();
// Must be in the future
return date > now;
}
}
```
### API Input Validation
```typescript
import { isValid, parse } from 'date-and-time';
function validateApiDateRange(startDate: string, endDate: string) {
const format = 'YYYY-MM-DD';
// Check both dates are valid
if (!isValid(startDate, format) || !isValid(endDate, format)) {
throw new Error('Invalid date format. Expected YYYY-MM-DD');
}
const start = parse(startDate, format);
const end = parse(endDate, format);
// Check logical order
if (start >= end) {
throw new Error('Start date must be before end date');
}
return { start, end };
}
```
## See Also
- [`parse()`](./parse) - Parse validated date strings into Date objects
- [`compile()`](./compile) - Precompile format patterns for performance
- [`preparse()`](./preparse) - Parse and return intermediate parsing results
================================================
FILE: docs/api/parse.md
================================================
---
title: parse()
---
Parses a formatted date string into a Date object according to the specified format pattern.
## Syntax
```typescript
parse(dateString, formatString[, options])
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------------------------|----------|---------------------------------------|
| `dateString` | `string` | Yes | The date string to parse |
| `formatString` | `string \| CompiledObject` | Yes | The format pattern or compiled object |
| `options` | `ParserOptions` | No | Parser options for customization |
### Returns
`Date` - The parsed Date object, or Invalid Date if parsing fails
## Basic Examples
```typescript
import { parse } from 'date-and-time';
// Basic date parsing
parse('2025-08-23', 'YYYY-MM-DD');
// => Fri Aug 23 2025 00:00:00 GMT-0700
parse('08/23/2025', 'MM/DD/YYYY');
// => Fri Aug 23 2025 00:00:00 GMT-0700
parse('23.08.2025', 'DD.MM.YYYY');
// => Fri Aug 23 2025 00:00:00 GMT-0700
// Time parsing
parse('14:30:45', 'HH:mm:ss');
// => Thu Jan 01 1970 14:30:45 GMT-0800
parse('2:30:45 PM', 'h:mm:ss A');
// => Thu Jan 01 1970 14:30:45 GMT-0800
// Combined date and time
parse('2025-08-23 14:30:45', 'YYYY-MM-DD HH:mm:ss');
// => Fri Aug 23 2025 14:30:45 GMT-0700
```
## Format Tokens
### Date Tokens
| Token | Description | Input Examples |
|--------|----------------------------|-------------------|
| `YYYY` | 4-digit year | 0999, 2015 |
| `Y` | Year without zero padding | 2, 44, 888, 2015 |
| `MMMM` | Full month name | January, December |
| `MMM` | Short month name | Jan, Dec |
| `MM` | Month (01-12) | 01, 12 |
| `M` | Month without zero padding | 1, 12 |
| `DD` | Day (01-31) | 02, 31 |
| `D` | Day without zero padding | 2, 31 |
### Time Tokens
| Token | Description | Input Examples |
|-------|---------------------------------------------|----------------|
| `HH` | Hour in 24-hour format | 23, 08 |
| `H` | Hour in 24-hour format without zero padding | 23, 8 |
| `hh` | Hour in 12-hour format | 11, 08 |
| `h` | Hour in 12-hour format without zero padding | 11, 8 |
| `mm` | Minutes | 14, 07 |
| `m` | Minutes without zero padding | 14, 7 |
| `ss` | Seconds | 05, 10 |
| `s` | Seconds without zero padding | 5, 10 |
| `SSS` | 3-digit milliseconds | 753, 022 |
| `SS` | 2-digit milliseconds | 75, 02 |
| `S` | 1-digit milliseconds | 7, 0 |
### AM/PM Tokens
| Token | Description | Input Examples |
|-------|--------------------------------|----------------|
| `A` | Uppercase AM/PM | AM, PM |
| `AA` | Uppercase AM/PM (with periods) | A.M., P.M. |
| `a` | Lowercase AM/PM | am, pm |
| `aa` | Lowercase AM/PM (with periods) | a.m., p.m. |
### Timezone Tokens
| Token | Description | Input Examples |
|-------|----------------------------|----------------|
| `Z` | Timezone offset | +0100, -0800 |
| `ZZ` | Timezone offset with colon | +01:00, -08:00 |
### Plugin Tokens
Additional tokens available with plugins:
| Token | Description | Input Examples | Plugin Required |
|-------------|------------------------|----------------------|-----------------|
| `YY` | 2-digit year | 90, 00, 08, 19 | two-digit-year |
| `DDD` | Ordinal representation | 1st, 2nd, 3rd | ordinal |
| `dddd` | Full day name | Friday, Sunday | day-of-week |
| `ddd` | Short day name | Fri, Sun | day-of-week |
| `dd` | Very short day name | Fr, Su | day-of-week |
| `SSSSSS` | 6-digit milliseconds | 123456, 000001 | microsecond |
| `SSSSS` | 5-digit milliseconds | 12345, 00001 | microsecond |
| `SSSS` | 4-digit milliseconds | 1234, 0001 | microsecond |
| `fff` | 3-digit microseconds | 753, 022 | microsecond |
| `ff` | 2-digit microseconds | 75, 02 | microsecond |
| `f` | 1-digit microseconds | 7, 0 | microsecond |
| `SSSSSSSSS` | 9-digit milliseconds | 123456789, 000000001 | nanosecond |
| `SSSSSSSS` | 8-digit milliseconds | 12345678, 00000001 | nanosecond |
| `SSSSSSS` | 7-digit milliseconds | 1234567, 0000001 | nanosecond |
| `FFF` | 3-digit nanoseconds | 753, 022 | nanosecond |
| `FF` | 2-digit nanoseconds | 75, 02 | nanosecond |
| `F` | 1-digit nanoseconds | 7, 0 | nanosecond |
For available plugins, see the [`plugins`](#plugins) option in ParserOptions.
## ParserOptions
The `ParserOptions` object allows you to customize the parsing behavior:
```typescript
interface ParserOptions {
locale?: Locale;
timeZone?: TimeZone | string;
numeral?: Numeral;
calendar?: 'gregory' | 'buddhist';
hour12?: 'h11' | 'h12';
hour24?: 'h23' | 'h24';
ignoreCase?: boolean;
defaultDate?: ParsedComponents;
plugins?: ParserPlugin[];
}
```
### locale
**Type**: `Locale`
**Default**: `en` (English)
Specifies the locale for parsing localized month names, day names, and meridiem indicators.
```typescript
import { parse } from 'date-and-time';
import es from 'date-and-time/locales/es';
// Spanish parsing
parse('23 de agosto de 2025', 'D [de] MMMM [de] YYYY', { locale: es });
// => Fri Aug 23 2025 00:00:00 GMT-0700
```
For a complete list of all supported locales with import examples, see [Supported Locales](../locales).
### timeZone
**Type**: `TimeZone | string`
**Default**: `undefined` (local timezone)
Interprets the parsed date in the specified timezone.
**Note**: If the input string contains a timezone offset (e.g., `Z` or `ZZ` tokens), that offset takes precedence and the `timeZone` option is ignored.
```typescript
import { parse } from 'date-and-time';
// Parse using an IANA timezone name string
parse('2025-08-23 14:30:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
// => Fri Aug 23 2025 14:30:00 GMT+0900
// Parse in UTC
parse('2025-08-23 14:30:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'UTC' });
// => Fri Aug 23 2025 14:30:00 GMT+0000
// Timezone offset in input takes precedence over timeZone option
parse('2025-08-23 14:30:00 +0300', 'YYYY-MM-DD HH:mm:ss Z', { timeZone: 'Asia/Tokyo' });
// => Fri Aug 23 2025 14:30:00 GMT+0300 (Asia/Tokyo timeZone is ignored)
parse('2025-08-23T14:30:00 +05:00', 'YYYY-MM-DD[T]HH:mm:ss ZZ', { timeZone: 'America/New_York' });
// => Fri Aug 23 2025 14:30:00 GMT+0500 (America/New_York timeZone is ignored)
```
For a complete list of all supported timezones, see [Supported Timezones](../timezones).
### numeral
**Type**: `Numeral`
**Default**: `latn` (Latin numerals)
Specifies the numeral system for parsing numbers.
```typescript
import { parse } from 'date-and-time';
import arab from 'date-and-time/numerals/arab';
import beng from 'date-and-time/numerals/beng';
// Arabic-Indic numerals
parse('٠٨/٠٧/٢٠٢٥', 'DD/MM/YYYY', { numeral: arab });
// => Fri Aug 08 2025 00:00:00 GMT-0700
// Bengali numerals
parse('০৮/০৭/২০২৫', 'DD/MM/YYYY', { numeral: beng });
// => Fri Aug 08 2025 00:00:00 GMT-0700
```
**Available numeral systems:**
- `latn` - Latin numerals (0-9) - default
- `arab` - Arabic-Indic numerals (٠-٩)
- `arabext` - Extended Arabic-Indic numerals (۰-۹)
- `beng` - Bengali numerals (০-৯)
- `mymr` - Myanmar numerals (၀-၉)
### calendar
**Type**: `"gregory" | "buddhist"`
**Default**: `"gregory"`
Specifies the calendar system for date calculations.
```typescript
import { parse } from 'date-and-time';
// Gregorian calendar (default)
parse('August 23, 2025', 'MMMM D, YYYY');
// => Fri Aug 23 2025 00:00:00 GMT-0700
// Buddhist calendar (543 years behind)
parse('August 23, 2568', 'MMMM D, YYYY', { calendar: 'buddhist' });
// => Fri Aug 23 2025 00:00:00 GMT-0700
```
### hour12
**Type**: `"h11" | "h12"`
**Default**: `"h12"`
Controls the 12-hour format interpretation. Use `h11` for 11-hour format (0-11) or `h12` for 12-hour format (1-12).
```typescript
import { parse } from 'date-and-time';
// h12 format - midnight is 12 AM
parse('12:30 AM', 'h:mm A', { hour12: 'h12' });
// => Thu Jan 01 1970 00:30:00 GMT-0800
// h11 format - midnight is 0 AM
parse('0:30 AM', 'h:mm A', { hour12: 'h11' });
// => Thu Jan 01 1970 00:30:00 GMT-0800
```
### hour24
**Type**: `"h23" | "h24"`
**Default**: `"h23"`
Controls the 24-hour format interpretation. Use `h23` for 23-hour format (0-23) or `h24` for 24-hour format (1-24).
```typescript
import { parse } from 'date-and-time';
// h23 format - midnight is 0
parse('0:30', 'H:mm', { hour24: 'h23' });
// => Thu Jan 01 1970 00:30:00 GMT-0800
// h24 format - midnight is 24 (of previous day)
parse('24:30', 'H:mm', { hour24: 'h24' });
// => Thu Jan 01 1970 00:30:00 GMT-0800
```
### ignoreCase
**Type**: `boolean`
**Default**: `false`
Enables case-insensitive parsing for text elements.
```typescript
import { parse } from 'date-and-time';
// Case-sensitive (default)
parse('august 23, 2025', 'MMMM D, YYYY');
// => Invalid Date
// Case-insensitive
parse('AUGUST 23, 2025', 'MMMM D, YYYY', { ignoreCase: true });
// => Fri Aug 23 2025 00:00:00 GMT-0700
parse('fri aug 23 2025', 'ddd MMM DD YYYY', { ignoreCase: true });
// => Fri Aug 23 2025 00:00:00 GMT-0700
```
### defaultDate
**Type**: `ParsedComponents`
**Default**: `{ Y: 1970, M: 1, D: 1, m: 0, s: 0, S: 0 }`
Specifies default values for date/time components that are missing from the format string. This is useful when parsing partial strings such as time-only or month-day formats.
```typescript
interface ParsedComponents {
Y?: number; // Year
M?: number; // Month (1-12)
D?: number; // Day
H?: number; // Hour (24-hour)
A?: number; // Meridiem (0: AM, 1: PM)
h?: number; // Hour (12-hour)
m?: number; // Minute
s?: number; // Second
S?: number; // Millisecond
Z?: number; // Timezone offset in minutes (e.g., UTC+9 = -540)
}
```
**Note**: If `defaultDate.Z` is set, it takes precedence over the `timeZone` option. `Z` is in minutes, using the same sign convention as the `Z` / `ZZ` format tokens (e.g., UTC+9 = `-540`).
```typescript
import { parse } from 'date-and-time';
// Parse time-only string — fill in date from defaultDate
parse('12:30', 'HH:mm', { defaultDate: { Y: 2024, M: 3, D: 15 } });
// => Fri Mar 15 2024 12:30:00
// Parse month-day only — fill in year from defaultDate
parse('03-15', 'MM-DD', { defaultDate: { Y: 2024 } });
// => Fri Mar 15 2024 00:00:00
// Fill in time components for a date-only format
parse('2024-03-15', 'YYYY-MM-DD', { defaultDate: { H: 10, m: 30, s: 45 } });
// => Fri Mar 15 2024 10:30:45
// defaultDate.Z takes precedence over timeZone option
parse('12:30', 'HH:mm', { defaultDate: { Y: 2024, M: 3, D: 15, Z: -540 }, timeZone: 'UTC' });
// => Fri Mar 15 2024 03:30:00 UTC (interpreted as UTC+9; timeZone: 'UTC' is ignored)
```
### plugins
**Type**: `ParserPlugin[]`
**Default**: `undefined`
Enables additional parse tokens provided by plugins. Plugins extend the parser with special tokens that are not included in the core library.
```typescript
import { parse } from 'date-and-time';
import { parser as ordinal } from 'date-and-time/plugins/ordinal';
import { parser as two_digit_year } from 'date-and-time/plugins/two-digit-year';
import { parser as microsecond } from 'date-and-time/plugins/microsecond';
// Use ordinal plugin
parse('January 1st, 2025', 'MMMM DDD, YYYY', { plugins: [ordinal] });
// => Wed Jan 01 2025 00:00:00 GMT-0800
// Use two-digit-year plugin
parse('12/25/99', 'MM/DD/YY', { plugins: [two_digit_year] });
// => Sat Dec 25 1999 00:00:00 GMT-0800
// Use microsecond plugin
parse('14:30:45.123456', 'HH:mm:ss.SSSSSS', { plugins: [microsecond] });
// => Thu Jan 01 1970 14:30:45 GMT-0800
// Use multiple plugins together
parse('January 1st, 99 14:30:45.123456', 'MMMM DDD, YY HH:mm:ss.SSSSSS', {
plugins: [ordinal, two_digit_year, microsecond]
});
// => Fri Jan 01 1999 14:30:45 GMT-0800
```
For a complete list of available plugins, see [Plugins](../plugins).
## Parsing Behavior and Limitations
### Default Date and Time Values
When parsing partial dates or times, missing components are filled with default values. The default date is `January 1, 1970`, and the default time is `00:00:00.000`.
```typescript
import { parse } from 'date-and-time';
// Only time - defaults to Jan 1, 1970
parse('14:30:45', 'HH:mm:ss');
// => Thu Jan 01 1970 14:30:45 GMT-0800
// Only date - defaults to 00:00:00
parse('2025-08-23', 'YYYY-MM-DD');
// => Fri Aug 23 2025 00:00:00 GMT-0700
// Year and month - defaults to 1st day
parse('2025-08', 'YYYY-MM');
// => Fri Aug 01 2025 00:00:00 GMT-0700
// Just year - defaults to Jan 1st, 00:00:00
parse('2025', 'YYYY');
// => Wed Jan 01 2025 00:00:00 GMT-0800
```
To customize these defaults, use the [`defaultDate`](#defaultdate) option.
### Date Range Limitations
The parsable maximum date is `December 31, 9999`, and the minimum date is `January 1, 0001`.
```typescript
import { parse } from 'date-and-time';
// Valid maximum date
parse('Dec 31 9999', 'MMM D YYYY');
// => Fri Dec 31 9999 00:00:00 GMT-0800
// Invalid - exceeds maximum
parse('Dec 31 10000', 'MMM D YYYY');
// => Invalid Date
// Valid minimum date
parse('Jan 1 0001', 'MMM D YYYY');
// => Mon Jan 1 0001 00:00:00 GMT-0800
// Invalid - below minimum
parse('Jan 1 0000', 'MMM D YYYY');
// => Invalid Date
```
### UTC Input Parsing
If the input string doesn't contain a timezone offset and no `timeZone` option is specified, the function treats the input as the local timezone. To parse input as UTC, set `timeZone: 'UTC'` in the options.
```typescript
import { parse } from 'date-and-time';
// Parsed as the local timezone
parse('14:30:45', 'HH:mm:ss');
// => Thu Jan 01 1970 14:30:45 GMT-0800
// Timezone offset in input takes precedence
parse('14:30:45 +0000', 'HH:mm:ss Z');
// => Thu Jan 01 1970 14:30:45 GMT+0000
// Force UTC parsing
parse('14:30:45', 'HH:mm:ss', { timeZone: 'UTC' });
// => Thu Jan 01 1970 14:30:45 GMT+0000
```
### 12-hour Format and Meridiem
When using 12-hour format tokens (`h` or `hh`), always include the meridiem token (`A` or `a`) for correct parsing.
```typescript
import { parse } from 'date-and-time';
// Without meridiem - ambiguous time
parse('11:30:45', 'h:mm:ss');
// => Thu Jan 01 1970 11:30:45 GMT-0800 (assumes AM)
// With meridiem - unambiguous time
parse('11:30:45 PM', 'h:mm:ss A');
// => Thu Jan 01 1970 23:30:45 GMT-0800
```
## Advanced Usage
### Comments in Format Strings
Parts of the format string enclosed in square brackets are treated as literal text:
```typescript
import { parse } from 'date-and-time';
parse('Today is Saturday, August 23, 2025', '[Today is] dddd, MMMM D, YYYY');
// => Sat Aug 23 2025 00:00:00 GMT-0700
parse('2025-08-23T14:30:45Z', 'YYYY-MM-DD[T]HH:mm:ss[Z]');
// => Sat Aug 23 2025 14:30:45 GMT-0700
parse('Report generated on 2025/08/23 at 14:30', '[Report generated on] YYYY/MM/DD [at] HH:mm');
// => Sat Aug 23 2025 14:30:00 GMT-0700
// Escape square brackets to parse them from input string
parse('[2025-08-23 14:30:45]', '\\[YYYY-MM-DD HH:mm:ss\\]');
// => Sat Aug 23 2025 14:30:45 GMT-0700
```
### Wildcard Parsing
Whitespace in the format string acts as a wildcard token, allowing you to skip corresponding parts of the input string. The character count must match between the format string and input string.
```typescript
import { parse } from 'date-and-time';
// This will fail - extra content not accounted for
parse('2025/08/23 14:30:45', 'YYYY/MM/DD');
// => Invalid Date
// Use whitespace as wildcard (9 spaces to match ' 14:30:45')
parse('2025/08/23 14:30:45', 'YYYY/MM/DD ');
// => Sat Aug 23 2025 00:00:00 GMT-0700
```
### Ellipsis Token
The `...` token ignores all subsequent content in the input string. Use this token only at the end of a format string.
```typescript
import { parse } from 'date-and-time';
// Ignore everything after the date
parse('2025/08/23 14:30:45', 'YYYY/MM/DD...');
// => Sat Aug 23 2025 00:00:00 GMT-0700
// More complex example
parse('Log entry: 2025-08-23 some extra data here', '[Log entry: ]YYYY-MM-DD...');
// => Sat Aug 23 2025 00:00:00 GMT-0700
```
### Complex Localized Parsing
```typescript
import { parse } from 'date-and-time';
import fr from 'date-and-time/locales/fr';
// French with timezone
parse('samedi, 23 août 2025 à 14:30:45', 'dddd, D MMMM YYYY [à] HH:mm:ss', {
locale: fr,
timeZone: 'Europe/Paris'
});
// => Fri Aug 23 2025 14:30:45 GMT+0200
```
### Business and Technical Formats
```typescript
import { parse } from 'date-and-time';
// ISO 8601 format
parse('2025-08-23T14:30:45.123Z', 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]', { timeZone: 'UTC' });
// => Fri Aug 23 2025 14:30:45 GMT+0000
// RFC 2822 format
parse('Sat, 23 Aug 2025 14:30:45 +0900', 'ddd, DD MMM YYYY HH:mm:ss ZZ');
// => Sat Aug 23 2025 14:30:45 GMT+0900
// File naming format
parse('20250823_143045', 'YYYYMMDD_HHmmss');
// => Sat Aug 23 2025 14:30:45 GMT-0700
```
## Error Handling
### When Parsing Fails
If the `parse()` function fails to parse the input, it returns an `Invalid Date` object. Note that `Invalid Date` is still a Date object, not `NaN` or `null`.
```typescript
import { parse } from 'date-and-time';
// Example of parsing failure
const result = parse('invalid-date', 'YYYY-MM-DD');
// Check if parsing failed
if (isNaN(result.getTime())) {
console.error('Parse failed - invalid date');
} else {
console.log('Successfully parsed:', result);
}
// Common parsing failures
parse('Jam 1 2017', 'MMM D YYYY'); // Invalid - 'Jam' is not a valid month
parse('2025-02-30', 'YYYY-MM-DD'); // Invalid - Feb 30th doesn't exist
parse('2025-13-01', 'YYYY-MM-DD'); // Invalid - month 13 doesn't exist
parse('25:30:00', 'HH:mm:ss'); // Invalid - hour 25 doesn't exist
parse('12 hours 34', 'HH hours mm'); // Invalid - format mismatch
```
## Performance Considerations
For repeated parsing with the same pattern, use [`compile()`](./compile):
```typescript
import { parse, compile } from 'date-and-time';
// Compile once
const pattern = compile('YYYY-MM-DD HH:mm:ss');
// Reuse for better performance
const dateStrings = ['2025-08-23 14:30:45', '2025-08-24 09:15:30'];
dateStrings.forEach(dateString => {
const parsed = parse(dateString, pattern);
console.log(parsed);
});
```
## Common Parsing Patterns
### Log Timestamps
```typescript
import { parse } from 'date-and-time';
const logLine = '[2025-08-23 14:30:45.123] Application started';
const timestamp = parse(logLine, ' YYYY-MM-DD HH:mm:ss.SSS ...');
// => Sat Aug 23 2025 14:30:45 GMT-0700
// For different log formats
const syslogLine = 'Aug 23 14:30:45 server: Process started';
const syslogTimestamp = parse(syslogLine, 'MMM DD HH:mm:ss...');
// => Sat Aug 23 1970 14:30:45 GMT-0700
```
### API Responses
```typescript
import { parse } from 'date-and-time';
const apiTimestamp = '2025-08-23T14:30:45Z';
const date = parse(apiTimestamp, 'YYYY-MM-DD[T]HH:mm:ss[Z]', { timeZone: 'UTC' });
```
### User Input
```typescript
import { parse } from 'date-and-time';
function parseUserDate(input: string) {
const formats = [
'YYYY-MM-DD',
'MM/DD/YYYY',
'DD.MM.YYYY',
'MMMM D, YYYY'
];
for (const format of formats) {
const result = parse(input, format);
if (!isNaN(result.getTime())) {
return result;
}
}
throw new Error('Unable to parse date');
}
```
## See Also
- [`compile()`](./compile) - Precompile format patterns for performance
- [`preparse()`](./preparse) - Parse and return intermediate parsing results
- [`isValid()`](./isValid) - Validate date string formats
================================================
FILE: docs/api/preparse.md
================================================
---
title: preparse()
---
Pre-parses date strings and returns intermediate parsing results. This function is useful when you need to examine parsing details before creating a final Date object.
## Syntax
```typescript
preparse(dateString, formatString[, options])
```
### Parameters
| Parameter | Type | Required | Description |
|----------------|----------------------------|----------|--------------------------------------------------------------------------|
| `dateString` | `string` | Yes | The date string to parse |
| `formatString` | `string \| CompiledObject` | Yes | Format pattern string or compiled object |
| `options` | `ParserOptions` | No | Parsing options for customization (see [`parse()`](./parse#parseroptions) for details) |
### Returns
`ParseResult` - Object containing parsed date components
```typescript
interface ParseResult {
Y?: number // Year
M?: number // Month (1-12)
D?: number // Day
H?: number // Hours (24-hour format, 0-23)
A?: number // AM/PM (0 = AM, 1 = PM)
h?: number // Hours (12-hour format, 1-12)
m?: number // Minutes (0-59)
s?: number // Seconds (0-59)
S?: number // Milliseconds (0-999)
SS?: number // 2-digit milliseconds (0-99)
SSS?: number // 3-digit milliseconds (0-999)
Z?: number // Timezone offset in minutes
_index?: number // Current parsing position
_length?: number // Total length of input string
_match?: number // Number of matched tokens
}
```
## Basic Examples
### Simple Date Parsing
```typescript
import { preparse } from 'date-and-time';
const result = preparse('2025-08-23 14:30:45', 'YYYY-MM-DD HH:mm:ss');
console.log(result);
// {
// Y: 2025,
// M: 8,
// D: 23,
// H: 14,
// m: 30,
// s: 45
// }
```
### With 12-hour Format
```typescript
const result = preparse('2025-08-23 2:30:45 PM', 'YYYY-MM-DD h:mm:ss A');
console.log(result);
// {
// Y: 2025,
// M: 8,
// D: 23,
// A: 1, // PM
// h: 2,
// m: 30,
// s: 45
// }
```
### With Localized Content
```typescript
import { preparse } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
const result = preparse('2025年8月23日', 'YYYY年M月D日', { locale: ja });
console.log(result);
// {
// Y: 2025,
// M: 8,
// D: 23
// }
```
## ParserOptions
The `options` parameter accepts the same `ParserOptions` as the [`parse()`](./parse#parseroptions) function. This includes locale, timezone, numeral system, calendar, case sensitivity, hour format settings, and `defaultDate`. Refer to the parse documentation for complete details on all available options.
## Use Cases
### Validation Before Parsing
```typescript
import { preparse, parse, isValid } from 'date-and-time';
function safeParse(dateString: string, format: string) {
const result = preparse(dateString, format);
// Check if required components are present
if (result.Y && result.M && result.D) {
return parse(dateString, format);
}
throw new Error('Missing required date components');
}
```
### Custom Date Validation
```typescript
function validateBusinessDay(dateString: string, format: string) {
const result = preparse(dateString, format);
if (result.Y && result.M && result.D) {
const date = new Date(result.Y, result.M - 1, result.D);
const dayOfWeek = date.getDay();
if (dayOfWeek === 0 || dayOfWeek === 6) {
throw new Error('Business days only (Monday-Friday)');
}
return date;
}
throw new Error('Invalid date format');
}
```
## Error Handling
If parsing fails, `preparse()` returns an object with parsing metadata but without the main date components (Y, M, D, H, etc.).
```typescript
const result = preparse('invalid-date', 'YYYY-MM-DD');
console.log(result);
// {
// _index: 0,
// _length: 12,
// _match: 0
// }
// Check for successful parsing by looking for date components
if (!result.Y && !result.M && !result.D) {
console.log('Parsing failed - no date components found');
}
// Alternative: check the _match property
if (result._match === 0) {
console.log('Parsing failed - no tokens matched');
}
```
## See Also
- [`parse()`](./parse) - Parse formatted date strings into Date objects
- [`compile()`](./compile) - Precompile format patterns for performance
- [`isValid()`](./isValid) - Validate date string formats
================================================
FILE: docs/api/subtract.md
================================================
---
title: subtract()
---
Calculates the difference between two Date objects and returns a rich Duration object with multiple time units and formatting options.
## Syntax
```typescript
subtract(date1, date2)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|--------|----------|------------------------|
| `date1` | `Date` | Yes | The earlier/start date |
| `date2` | `Date` | Yes | The later/end date |
### Returns
`Duration` - Rich duration object containing the time difference with properties for years, months, days, hours, minutes, seconds, and milliseconds
## Basic Examples
### Calculating Time Differences
```typescript
import { subtract } from 'date-and-time';
const start = new Date(2024, 0, 1, 10, 30, 0); // January 1, 2024 10:30:00
const end = new Date(2024, 0, 1, 14, 45, 30); // January 1, 2024 14:45:30
const duration = subtract(start, end);
console.log(duration.toHours().value); // 4.258333...
console.log(duration.toMinutes().value); // 255.5
console.log(duration.toSeconds().value); // 15330
const hoursParts = duration.toHours().toParts();
console.log(hoursParts.hours); // 4
console.log(hoursParts.minutes); // 15
console.log(hoursParts.seconds); // 30
```
### Cross-Day Calculation
```typescript
const start = new Date(2024, 6, 15, 22, 30); // July 15, 2024 22:30
const end = new Date(2024, 6, 18, 8, 15); // July 18, 2024 08:15
const duration = subtract(start, end);
const daysParts = duration.toDays().toParts();
console.log(daysParts.days); // 2
console.log(daysParts.hours); // 9
console.log(daysParts.minutes); // 45
console.log(duration.toHours().value); // 57.75 (total hours as decimal)
```
### Age Calculation
```typescript
const birthDate = new Date(1990, 5, 15); // June 15, 1990
const today = new Date(); // Current date
const age = subtract(birthDate, today);
const ageParts = age.toDays().toParts();
// Note: Simple age calculation (not accounting for leap years)
console.log(`Age: ${Math.floor(ageParts.days / 365)} years`);
// Get total days lived
console.log(`Total days lived: ${ageParts.days}`);
```
## Duration Object Methods
The returned Duration object provides methods to convert and format durations. The Duration can also be directly instantiated with a millisecond value:
```typescript
class Duration {
constructor(milliseconds: number) // Create Duration instance directly
// Convert to different time units with value and formatting capabilities
toNanoseconds(): DurationDescriptor
toMicroseconds(): DurationDescriptor
toMilliseconds(): DurationDescriptor
toSeconds(): DurationDescriptor
toMinutes(): DurationDescriptor
toHours(): DurationDescriptor
toDays(): DurationDescriptor
}
interface DurationDescriptor {
value: number // Total duration in the specified unit
format: (formatString: string, numeral?: Numeral) => string // Format duration with custom pattern
toParts: () => T // Get duration broken down into parts
}
// Example part interfaces
interface HoursParts {
hours: number
minutes: number
seconds: number
milliseconds: number
microseconds: number
nanoseconds: number
}
```
### Creating Duration Instances Directly
```typescript
import { Duration } from 'date-and-time';
// Create a Duration for 2 hours (7200000 milliseconds)
const duration = new Duration(7200000);
console.log(duration.toHours().value); // 2
console.log(duration.toMinutes().value); // 120
// Format the duration
console.log(duration.toHours().format('H[h] m[m]')); // "2h 0m"
```
### Advanced Duration Formatting
```typescript
const start = new Date(2024, 7, 15, 9, 30, 45);
const end = new Date(2024, 7, 18, 16, 15, 20);
const duration = subtract(start, end);
// Various formatting options
console.log(duration.toDays().format('D[d] H[h] m[m]')); // "3d 6h 44m"
console.log(duration.toHours().format('H:mm:ss')); // "78:44:35"
console.log(duration.toMinutes().format('[Total minutes:] m')); // "Total minutes: 4724"
console.log(duration.toDays().format('D[day], H:mm:ss.SSS')); // "3day, 6:44:35.000"
```
## Use Cases
### Work Session Tracking
```typescript
const clockIn = new Date(2024, 7, 15, 9, 0); // August 15, 2024 09:00
const clockOut = new Date(2024, 7, 15, 17, 45); // August 15, 2024 17:45
const duration = subtract(clockIn, clockOut);
console.log(duration.toHours().value); // 8.75
console.log(duration.toHours().format('H:mm')); // "8:45"
console.log(duration.toHours().format('H[h] m[m]')); // "8h 45m"
```
### Performance Monitoring
```typescript
const start = performance.now();
// ... some operation ...
const end = performance.now();
// Create Duration directly from millisecond difference
const duration = new Duration(end - start);
console.log(duration.toMilliseconds().format('SSS[ms]')); // "234ms"
```
## Edge Cases and Behavior
### Negative Durations
When the first argument is later than the second argument, `subtract()` returns negative duration values. This behavior allows for flexible date comparison in either direction.
```typescript
// Comparing dates in reverse chronological order
const later = new Date(2024, 7, 15, 14, 30); // 2:30 PM
const earlier = new Date(2024, 7, 15, 10, 15); // 10:15 AM
const negativeDuration = subtract(later, earlier);
console.log(negativeDuration.toHours().value); // -4.25 (negative value)
console.log(negativeDuration.toMinutes().value); // -255 (all values are negative)
// Format methods handle negative values appropriately
console.log(negativeDuration.toHours().format('H[h] m[m]')); // "-4h 15m"
```
### Negative Zero
An edge case of negative durations occurs when the difference is negative but the integer part of certain units is zero. This affects both `toParts()` and `format()` output differently.
```typescript
// Short negative duration (less than 1 day but more than 1 hour)
const date1 = new Date(2024, 7, 15, 14, 30); // 2:30 PM
const date2 = new Date(2024, 7, 15, 12, 15); // 12:15 PM
const duration = subtract(date1, date2);
console.log(duration.toDays().value); // -0.09375 (negative but less than 1 day)
// toParts() shows negative signs on all non-zero unit values
const parts = duration.toDays().toParts();
console.log(parts); // { days: 0, hours: -2, minutes: -15, seconds: 0, ... }
// format() places a single negative sign at the beginning, potentially creating "-0"
console.log(duration.toDays().format('D[day], H:mm:ss')); // "-0day, 2:15:00"
```
## Immutability
Both input Date objects remain unchanged:
```typescript
const date1 = new Date(2024, 7, 15, 14, 30);
const date2 = new Date(2024, 7, 15, 12, 15);
const duration = subtract(date2, date1);
console.log(date1); // Unchanged
console.log(date2); // Unchanged
console.log(duration.toHours().value); // 2.25 (new Duration object)
```
## See Also
- [`addYears()`](./addYears) - Add/subtract years
- [`addMonths()`](./addMonths) - Add/subtract months
- [`addDays()`](./addDays) - Add/subtract days
- [`addHours()`](./addHours) - Add/subtract hours
- [`addMinutes()`](./addMinutes) - Add/subtract minutes
- [`addSeconds()`](./addSeconds) - Add/subtract seconds
- [`addMilliseconds()`](./addMilliseconds) - Add/subtract milliseconds
================================================
FILE: docs/api/transform.md
================================================
---
title: transform()
---
Transforms date strings from one format to another. This is a convenience function that combines parse() and format() operations.
## Syntax
```typescript
transform(dateString, sourceFormat, targetFormat[, parserOptions, formatterOptions])
```
### Parameters
| Parameter | Type | Required | Description |
|--------------------|----------------------------|----------|-------------------------------------------|
| `dateString` | `string` | Yes | The input date string to transform |
| `sourceFormat` | `string \| CompiledObject` | Yes | Source format pattern or compiled pattern |
| `targetFormat` | `string \| CompiledObject` | Yes | Target format pattern or compiled pattern |
| `parserOptions` | `ParserOptions` | No | Options for parsing the source string |
| `formatterOptions` | `FormatterOptions` | No | Options for formatting the target string |
### Returns
`string` - The transformed date string in the target format
## Basic Examples
### Format Transformation
```typescript
import { transform } from 'date-and-time';
// ISO to US format
const result = transform('2025-08-23', 'YYYY-MM-DD', 'MM/DD/YYYY');
console.log(result); // '08/23/2025'
// Add time components
const withTime = transform('2025-08-23', 'YYYY-MM-DD', 'DD/MM/YYYY HH:mm:ss');
console.log(withTime); // '23/08/2025 00:00:00'
```
### Time Format Conversion
```typescript
// 24-hour to 12-hour format
const time12 = transform('14:30:45', 'HH:mm:ss', 'h:mm:ss A');
console.log(time12); // '2:30:45 PM'
// 12-hour to 24-hour format
const time24 = transform('2:30:45 PM', 'h:mm:ss A', 'H:mm:ss');
console.log(time24); // '14:30:45'
```
### With Localized Formats
```typescript
import es from 'date-and-time/locales/es';
// Transform Spanish to English UTC
const localized = transform(
'viernes, 23 ago 2025 14:30:45 GMT+0200',
'dddd, DD MMM YYYY HH:mm:ss [GMT]Z',
'ddd, DD MMM YYYY HH:mm:ss [GMT]',
{ locale: es }
);
console.log(localized); // 'Fri, 23 Aug 2025 12:30:45 GMT'
```
### Using Compiled Patterns
```typescript
import { compile, transform } from 'date-and-time';
// Precompile for better performance
const sourcePattern = compile('YYYY-MM-DD HH:mm:ss');
const targetPattern = compile('DD/MM/YYYY h:mm:ss A');
const result = transform(
'2025-08-23 14:30:45',
sourcePattern,
targetPattern
);
console.log(result); // '23/08/2025 2:30:45 PM'
```
## Use Cases
### API Response Transformation
```typescript
function normalizeApiDates(apiResponse: any) {
// Transform API dates to display format
if (apiResponse.created_at) {
apiResponse.created_at = transform(
apiResponse.created_at,
'YYYY-MM-DD[T]HH:mm:ss[Z]',
'MMM DD, YYYY [at] h:mm A'
);
}
return apiResponse;
}
const data = { created_at: '2025-08-23T14:30:45Z' };
console.log(normalizeApiDates(data));
// { created_at: 'Aug 23, 2025 at 2:30 PM' }
```
### Batch Format Conversion
```typescript
function convertDateFormats(dates: string[], sourceFormat: string, targetFormat: string) {
return dates.map(date => transform(date, sourceFormat, targetFormat));
}
const dates = ['2025-08-23', '2025-08-24', '2025-08-25'];
const converted = convertDateFormats(dates, 'YYYY-MM-DD', 'DD/MM/YYYY');
console.log(converted);
// ['23/08/2025', '24/08/2025', '25/08/2025']
```
### Form Input Standardization
```typescript
function standardizeUserInput(userDate: string, userFormat: string) {
// Always convert user input to ISO format for storage
return transform(userDate, userFormat, 'YYYY-MM-DD');
}
const userInput = '23/08/2025';
const standardized = standardizeUserInput(userInput, 'DD/MM/YYYY');
console.log(standardized); // '2025-08-23'
```
## Implementation Details
The `transform()` function is a convenience wrapper that internally:
1. Parses the input string using the source format
2. Formats the resulting Date object using the target format
```typescript
// transform() is equivalent to:
const date = parse(dateString, sourceFormat);
const result = format(date, targetFormat);
// But provides a cleaner API:
const result = transform(dateString, sourceFormat, targetFormat);
```
## See Also
- [`format()`](./format) - Format Date objects using compiled patterns
- [`compile()`](./compile) - Precompile format patterns for performance
================================================
FILE: docs/api/utils/getDaysInMonth.md
================================================
---
title: getDaysInMonth()
---
Returns the number of days in a given month of a specific year. Correctly handles leap years when calculating February.
## Syntax
```typescript
getDaysInMonth(date)
getDaysInMonth(year, month)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|------------------|----------------------------------------|
| `date` | `Date` | Yes (overload 1) | The date object whose month to examine |
| `year` | `number` | Yes (overload 2) | The Gregorian year (1–9999) |
| `month` | `number` | Yes (overload 2) | The month (1–12) |
### Returns
`number` - The number of days in the specified month
## Basic Examples
### Using a Date Object
```typescript
import { getDaysInMonth } from 'date-and-time';
getDaysInMonth(new Date(2024, 1, 1)); // => 29 (Feb 2024, leap year)
getDaysInMonth(new Date(2023, 1, 1)); // => 28 (Feb 2023, not a leap year)
getDaysInMonth(new Date(2025, 0, 1)); // => 31 (January 2025)
```
### Using Year and Month Numbers
```typescript
import { getDaysInMonth } from 'date-and-time';
getDaysInMonth(2024, 2); // => 29 (Feb 2024, leap year)
getDaysInMonth(2023, 2); // => 28 (Feb 2023, not a leap year)
getDaysInMonth(2025, 4); // => 30 (April 2025)
getDaysInMonth(2025, 12); // => 31 (December 2025)
```
## See Also
- [`isLeapYear()`](./isLeapYear) - Check if a year is a leap year
- [`addMonths()`](../addMonths) - Add months to a date
================================================
FILE: docs/api/utils/getISOWeek.md
================================================
---
title: getISOWeek()
---
Returns the ISO 8601 week number (1–53) for a given date. ISO weeks start on Monday, and week 1 is the week containing the first Thursday of the year.
## Syntax
```typescript
getISOWeek(date)
getISOWeek(year, month, day)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|------------------|-----------------------------|
| `date` | `Date` | Yes (overload 1) | The date object to examine |
| `year` | `number` | Yes (overload 2) | The Gregorian year (1–9999) |
| `month` | `number` | Yes (overload 2) | The month (1–12) |
| `day` | `number` | Yes (overload 2) | The day (1–31) |
### Returns
`number` - The ISO week number (1–53) for the given date
## Basic Examples
### Using a Date Object
```typescript
import { getISOWeek } from 'date-and-time';
getISOWeek(new Date(2025, 0, 1)); // => 1 (Jan 1, 2025 is in week 1)
getISOWeek(new Date(2025, 5, 15)); // => 24 (Jun 15, 2025 is in week 24)
```
### Using Year, Month, and Day
```typescript
import { getISOWeek } from 'date-and-time';
getISOWeek(2025, 1, 1); // => 1
getISOWeek(2025, 6, 15); // => 24
```
### Years with Week 53
Some years have 53 ISO weeks (when January 1 is a Thursday, or a Wednesday in a leap year):
```typescript
import { getISOWeek } from 'date-and-time';
getISOWeek(new Date(2020, 11, 31)); // => 53 (Dec 31, 2020)
getISOWeek(2020, 12, 31); // => 53
```
## See Also
- [`getISOWeekYear()`](./getISOWeekYear) - Get the ISO week year for a date
- [week plugin](../../plugins#week) - Format ISO week dates with `format()`
================================================
FILE: docs/api/utils/getISOWeekYear.md
================================================
---
title: getISOWeekYear()
---
Returns the ISO 8601 week year for a given date. The ISO week year may differ from the calendar year near the start and end of the year, because ISO weeks always start on Monday and the first week of the year is the one containing the first Thursday of the year.
## Syntax
```typescript
getISOWeekYear(date)
getISOWeekYear(year, month, day)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|------------------|-----------------------------|
| `date` | `Date` | Yes (overload 1) | The date object to examine |
| `year` | `number` | Yes (overload 2) | The Gregorian year (1–9999) |
| `month` | `number` | Yes (overload 2) | The month (1–12) |
| `day` | `number` | Yes (overload 2) | The day (1–31) |
### Returns
`number` - The ISO week year corresponding to the given date
## Basic Examples
### Using a Date Object
```typescript
import { getISOWeekYear } from 'date-and-time';
getISOWeekYear(new Date(2025, 5, 15)); // => 2025 (mid-year, same as calendar year)
```
### Year Boundary Cases
Near year boundaries, the ISO week year can differ from the calendar year:
```typescript
import { getISOWeekYear } from 'date-and-time';
// Dec 30, 2024 is in ISO week 1 of 2025
getISOWeekYear(new Date(2024, 11, 30)); // => 2025
getISOWeekYear(2024, 12, 30); // => 2025
// Jan 1, 2016 is in ISO week 53 of 2015
getISOWeekYear(new Date(2016, 0, 1)); // => 2015
getISOWeekYear(2016, 1, 1); // => 2015
```
## See Also
- [`getISOWeek()`](./getISOWeek) - Get the ISO week number for a date
- [week plugin](../../plugins#week) - Format ISO week dates with `format()`
================================================
FILE: docs/api/utils/isLeapYear.md
================================================
---
title: isLeapYear()
---
Determines if a given year is a leap year according to the Gregorian calendar rules.
## Syntax
```typescript
isLeapYear(year)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|----------|----------|-------------------|
| `year` | `number` | Yes | The year to check |
### Returns
`boolean` - Returns `true` if the year is a leap year, `false` otherwise
## Basic Examples
### Checking Leap Years
```typescript
import { isLeapYear } from 'date-and-time';
console.log(isLeapYear(2024)); // true (divisible by 4)
console.log(isLeapYear(2023)); // false (not divisible by 4)
console.log(isLeapYear(2000)); // true (divisible by 400)
console.log(isLeapYear(1900)); // false (divisible by 100 but not by 400)
```
### Working with Date Objects
```typescript
function checkDateLeapYear(date: Date): boolean {
return isLeapYear(date.getFullYear());
}
const dates = [
new Date(2024, 1, 29), // February 29, 2024
new Date(2023, 1, 28), // February 28, 2023
new Date(2000, 1, 29) // February 29, 2000
];
dates.forEach(date => {
const year = date.getFullYear();
console.log(`${year}: ${isLeapYear(year) ? 'Leap year' : 'Not a leap year'}`);
});
```
## Edge Cases
### Historical Context
```typescript
// Note: Gregorian calendar was adopted in 1582
// Before that, different leap year rules applied
function isHistoricalAccurate(year: number): boolean {
if (year < 1582) {
console.warn('Year is before Gregorian calendar adoption (1582)');
// Julian calendar had simpler rule: every 4 years
return year % 4 === 0;
}
return isLeapYear(year);
}
console.log(isHistoricalAccurate(1500)); // true (Julian calendar rule)
console.log(isHistoricalAccurate(1700)); // false (Gregorian calendar rule)
```
================================================
FILE: docs/api/utils/isSameDay.md
================================================
---
title: isSameDay()
---
Checks if two Date objects represent the same calendar day, regardless of time.
## Syntax
```typescript
isSameDay(date1, date2)
```
### Parameters
| Parameter | Type | Required | Description |
|-----------|--------|----------|-----------------------------------|
| `date1` | `Date` | Yes | The first Date object to compare |
| `date2` | `Date` | Yes | The second Date object to compare |
### Returns
`boolean` - Returns `true` if both dates are on the same calendar day, `false` otherwise
## Basic Examples
### Comparing Calendar Days
```typescript
import { isSameDay } from 'date-and-time';
const morning = new Date(2024, 7, 15, 9, 30, 0); // August 15, 2024 09:30:00
const evening = new Date(2024, 7, 15, 18, 45, 30); // August 15, 2024 18:45:30
const nextDay = new Date(2024, 7, 16, 9, 30, 0); // August 16, 2024 09:30:00
console.log(isSameDay(morning, evening)); // true (same day, different times)
console.log(isSameDay(morning, nextDay)); // false (different days)
```
### Ignoring Time Components
```typescript
const startOfDay = new Date(2024, 7, 15, 0, 0, 0, 0); // August 15, 2024 00:00:00.000
const endOfDay = new Date(2024, 7, 15, 23, 59, 59, 999); // August 15, 2024 23:59:59.999
console.log(isSameDay(startOfDay, endOfDay)); // true
// Even milliseconds don't matter for day comparison
const precise1 = new Date(2024, 7, 15, 12, 30, 45, 123);
const precise2 = new Date(2024, 7, 15, 12, 30, 45, 456);
console.log(isSameDay(precise1, precise2)); // true
```
================================================
FILE: docs/content.config.ts
================================================
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({
loader: glob({
pattern: '**/*.{md,mdx}',
base: './docs',
}),
schema: docsSchema(),
}),
};
================================================
FILE: docs/env.d.ts
================================================
///
================================================
FILE: docs/guide/index.md
================================================
---
title: Introduction
---
**date-and-time** is the simplest, most intuitive date and time library for JavaScript and TypeScript. Built from the ground up with modern development practices, it provides a comprehensive set of tools for date manipulation, formatting, parsing, and timezone handling.
## Why date-and-time?
### 🚀 Modern & Performant
- Written entirely in **TypeScript** with ES2021 target
- **Tree-shakable** modules for optimal bundle size
- **Zero dependencies** for core functionality
- Full **ES Modules** and **CommonJS** support
### 🌍 Internationalization Ready
- Support for **40+ locales** with native month/day names
- Multiple **calendar systems** (Gregorian, Buddhist)
- **Numeral systems** (Latin, Arabic, Bengali, Myanmar)
- **Timezone-aware** formatting and parsing
### 🎯 Developer Experience
- **Full TypeScript** support with comprehensive type definitions
- **IntelliSense** support in modern editors
- **Consistent API** design across all functions
- **Extensive documentation** and examples
### 📦 Production Ready
- **Node.js 18+** support
- **Modern browser** compatibility (Chrome 85+, Firefox 78+, Safari 14+)
- **Comprehensive test suite** with high coverage
- **Battle-tested** in production environments
## Key Features
### Formatting and Parsing
- **`format()`** - Convert Date objects to formatted strings
- **`parse()`** - Parse date strings into Date objects
- **`compile()`** - Precompile format strings for performance
- **`preparse()`** - Parse date strings and return intermediate results
- **`isValid()`** - Validate date string formats
- **`transform()`** - Transform date strings between different formats
### Date Arithmetic
- **`addYears()`, `addMonths()`, `addDays()`** - Date addition
- **`addHours()`, `addMinutes()`, `addSeconds()`, `addMilliseconds()`** - Time addition
- **`subtract()`** - Calculate time differences with Duration objects
### Utility Functions
- **`isLeapYear()`** - Check if a year is a leap year
- **`isSameDay()`** - Check if two dates are on the same day
- **`getDaysInMonth()`** - Get the number of days in a month
- **`getISOWeekYear()`** - Get the ISO week year for a date (follows ISO 8601)
- **`getISOWeek()`** - Get the ISO week number for a date (1–53, follows ISO 8601)
### Advanced Features
- **Timezone Support** - Comprehensive timezone data from timezonedb
- **Locale Support** - 40+ languages with native formatting
- **Plugin System** - Extend formatters and parsers
- **Duration Objects** - Rich time difference calculations
## Version 4.x Highlights
Version 4.x represents a complete rewrite with significant improvements:
### 🔄 Breaking Changes
- **TypeScript-first** development approach
- **Integrated plugins** - timezone and timespan functionality built-in
- **New API signatures** - options objects replace boolean parameters
- **Modern JavaScript** - ES2021 features throughout
### 📈 Performance Improvements
- **Reduced bundle size** with tree-shaking
### 🛠 Developer Improvements
- **Expanded language support** - Now supporting 40+ locales
- **Improved TypeScript** inference and completion
- **Comprehensive documentation** with live examples
## Architecture
```typescript
import { format, parse } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
// Core functionality
const date = new Date();
const formatted = format(date, 'YYYY/MM/DD');
// Localized formatting
const localized = format(date, 'YYYY年M月D日', { locale: ja });
// Timezone-aware operations
const tokyoTime = format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
```
## Browser and Environment Support
### Node.js
- **Node.js 18.0.0+** (LTS recommended)
- Full ES Modules support
- CommonJS compatibility
### Browsers
| Browser | Minimum Version |
|---------|-----------------|
| Chrome | 85+ |
| Firefox | 78+ |
| Safari | 14+ |
| Edge | 85+ |
### Module Systems
- **ES Modules** (`.mjs`, `type: "module"`)
- **CommonJS** (`.cjs`, traditional Node.js)
- **TypeScript** (4.5+)
- **Bundlers** (Webpack, Rollup, Vite, etc.)
## Getting Started
Ready to start using date-and-time? Continue to the [Installation Guide](./installation) to set up the library in your project.
================================================
FILE: docs/guide/installation.mdx
================================================
---
title: Installation
---
import { Aside, Tabs, TabItem } from '@astrojs/starlight/components';
Get started with date-and-time in your project using your preferred package manager.
## Package Manager Installation
```bash
npm install date-and-time
```
```bash
yarn add date-and-time
```
```bash
pnpm add date-and-time
```
## Requirements
### Runtime Requirements
- **Node.js**: Version 18.0.0 or higher
- **Browsers**: ES2021 support required
### Development Requirements (optional)
- **TypeScript**: Version 4.5 or higher for full type support
- **Modern bundler**: For optimal tree-shaking (Webpack 5+, Rollup, Vite, etc.)
## Import Methods
date-and-time supports both ES Modules and CommonJS, allowing you to use the import style that best fits your project.
### ES Modules (Recommended)
```typescript
import { format, parse } from 'date-and-time';
format(new Date(), 'YYYY/MM/DD');
// => 2025/08/23
```
### CommonJS
```typescript
const { format, parse } = require('date-and-time');
format(new Date(), 'YYYY/MM/DD');
// => 2025/08/23
```
## Importing Locales and Timezones
Locales and timezones are distributed as separate modules to support tree shaking:
### Locale Imports
```typescript
// Import specific locales
import ja from 'date-and-time/locales/ja';
import es from 'date-and-time/locales/es';
import fr from 'date-and-time/locales/fr';
// Use in formatting
format(new Date(), 'YYYY年M月D日', { locale: ja });
format(new Date(), 'D [de] MMMM [de] YYYY', { locale: es });
format(new Date(), 'D MMMM YYYY', { locale: fr });
```
For a complete list of all supported locales with import examples, see [Supported Locales](../locales).
### Timezone Usage
Pass an IANA timezone name string directly to any function that accepts a timezone option:
```typescript
format(new Date(), 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
format(new Date(), 'YYYY-MM-DD HH:mm:ss', { timeZone: 'America/New_York' });
```
For a complete list of all supported timezones, see [Supported Timezones](../timezones).
### Numeral Systems
```typescript
// Import numeral systems
import arab from 'date-and-time/numerals/arab';
import beng from 'date-and-time/numerals/beng';
format(new Date(), 'DD/MM/YYYY', { numeral: arab });
// => ٠٨/٠٧/٢٠٢٥
```
## Plugin Imports
Some advanced features are available as plugins:
```typescript
import { format } from 'date-and-time';
// Import specific plugins
import microsecond from 'date-and-time/plugins/microsecond';
import ordinal from 'date-and-time/plugins/ordinal';
import zonename from 'date-and-time/plugins/zonename';
// Use plugin-specific tokens with plugins specified in options
format(new Date(), 'MMMM DDD, YYYY', { plugins: [ordinal] }); // with ordinal plugin
format(new Date(), 'HH:mm:ss.SSSSSS', { plugins: [microsecond] }); // with microsecond plugin
```
## CDN Usage
For browser-only projects, you can use date-and-time directly from a CDN:
### Via jsDelivr
```html
```
### Via unpkg
```html
```
## Bundle Size
## Verification
After installation, verify that the library works correctly:
```typescript
import { format } from 'date-and-time';
console.log(format(new Date(), 'YYYY/MM/DD HH:mm:ss'));
// Should output current date in YYYY/MM/DD HH:mm:ss format
```
## Next Steps
Now that you have date-and-time installed, you can:
1. **[Quick Start](./quick-start)** - Learn the basics with simple examples
2. **[API Reference](/api/)** - Dive deep into all available functions
## Troubleshooting
### TypeScript Issues
If you encounter TypeScript errors, ensure you're using TypeScript 4.5+ and have the latest version of date-and-time:
```bash
npm install typescript@latest date-and-time@latest
```
### Module Resolution Issues
For Node.js projects using ES Modules, ensure your `package.json` includes:
```json
{
"type": "module"
}
```
For CommonJS projects, this field should be omitted or set to `"commonjs"`.
================================================
FILE: docs/guide/quick-start.md
================================================
---
title: Quick Start
---
This guide will get you up and running with date-and-time in just a few minutes.
## Basic Example
```typescript
import { format, parse } from 'date-and-time';
const now = new Date();
// Format a date
const formatted = format(now, 'YYYY/MM/DD HH:mm:ss');
console.log(formatted);
// => 2025/08/23 14:30:45
// Parse a date string
const parsed = parse('2025/08/23 14:30:45', 'YYYY/MM/DD HH:mm:ss');
console.log(parsed);
// => Fri Aug 23 2025 14:30:45 GMT+0900
```
## Common Format Patterns
### Date Formats
```typescript
import { format } from 'date-and-time';
const date = new Date();
format(date, 'YYYY-MM-DD'); // => 2025-08-23
format(date, 'MM/DD/YYYY'); // => 08/23/2025
format(date, 'DD.MM.YYYY'); // => 23.08.2025
format(date, 'MMMM D, YYYY'); // => August 23, 2025
format(date, 'ddd, MMM DD YYYY'); // => Sat, Aug 23 2025
```
### Time Formats
```typescript
format(date, 'HH:mm:ss'); // => 14:30:45 (24-hour)
format(date, 'hh:mm:ss A'); // => 02:30:45 PM (12-hour)
format(date, 'h:mm A'); // => 2:30 PM (12-hour, no leading zero)
```
### Combined DateTime Formats
```typescript
format(date, 'YYYY-MM-DD HH:mm:ss'); // => 2025-08-23 14:30:45
format(date, 'ddd, MMM D, YYYY [at] h:mm A');
// => Sat, Aug 23, 2025 at 2:30 PM
format(date, '[Today is] dddd'); // => Today is Saturday
```
## Working with Locales
```typescript
import { format } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
import es from 'date-and-time/locales/es';
import fr from 'date-and-time/locales/fr';
const date = new Date();
// Japanese
format(date, 'YYYY年M月D日(ddd)', { locale: ja });
// => 2025年8月23日(土)
// Spanish
format(date, 'dddd, D [de] MMMM [de] YYYY', { locale: es });
// => sábado, 23 de agosto de 2025
// French
format(date, 'dddd D MMMM YYYY', { locale: fr });
// => samedi 23 août 2025
```
For a complete list of all supported locales with import examples, see [Supported Locales](../locales).
## Timezone Operations
```typescript
import { format, parse } from 'date-and-time';
const date = new Date();
// Format in a specific timezone
format(date, 'YYYY-MM-DD HH:mm:ss [EST]', { timeZone: 'America/New_York' });
// => 2025-08-23 09:30:45 EST
// UTC formatting
format(date, 'YYYY-MM-DD HH:mm:ss [UTC]', { timeZone: 'UTC' });
// => 2025-08-23 14:30:45 UTC
// Parsing in timezone
parse('2025-08-23 23:30:45', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
// => Fri Aug 23 2025 23:30:45 GMT+0900
```
For a complete list of all supported timezones, see [Supported Timezones](../timezones).
## Date Arithmetic
```typescript
import { addDays, addHours, addMonths, subtract } from 'date-and-time';
const date = new Date(2025, 7, 23); // Aug 23, 2025
// Add time
const nextWeek = addDays(date, 7); // Aug 30, 2025
const nextMonth = addMonths(date, 1); // Sep 23, 2025
const inFiveHours = addHours(date, 5); // Aug 23, 2025 05:00:00
// Subtract time (use negative values)
const lastWeek = addDays(date, -7); // Aug 16, 2025
// Calculate differences
const start = new Date(2025, 7, 23, 10, 0, 0);
const end = new Date(2025, 7, 23, 14, 30, 0);
const duration = subtract(start, end);
console.log(duration.toHours().value); // => 4.5
console.log(duration.toMinutes().value); // => 270
```
## Validation
```typescript
import { isValid, parse } from 'date-and-time';
// Check if a date string is valid
isValid('2025/08/23', 'YYYY/MM/DD'); // => true
isValid('2025/02/30', 'YYYY/MM/DD'); // => false (no Feb 30th)
isValid('invalid-date', 'YYYY/MM/DD'); // => false
// Safe parsing with validation
if (isValid('2025/08/23', 'YYYY/MM/DD')) {
const date = parse('2025/08/23', 'YYYY/MM/DD');
console.log('Parsed successfully:', date);
} else {
console.log('Invalid date format');
}
```
## Performance Optimization
For repeated operations with the same format pattern, use `compile()`:
```typescript
import { compile, format, parse } from 'date-and-time';
// Compile the pattern once
const pattern = compile('YYYY/MM/DD HH:mm:ss');
// Reuse for multiple operations (faster)
const dates = [new Date(), new Date(), new Date()];
dates.forEach(date => {
console.log(format(date, pattern));
});
```
## Error Handling
```typescript
import { parse } from 'date-and-time';
// parse() returns Invalid Date on failure
const result = parse('invalid-date', 'YYYY/MM/DD');
// Check for parsing errors
if (isNaN(result.getTime())) {
console.error('Failed to parse date');
} else {
console.log('Successfully parsed:', result);
}
```
## Next Steps
Now that you're familiar with the basics:
1. **[API Reference](/api/)** - Explore all available functions
2. **[Plugins](../plugins)** - Extend functionality with microsecond precision, ordinals, and more
3. **[Migration Guide](../migration)** - If upgrading from v3.x
================================================
FILE: docs/index.mdx
================================================
---
title: date-and-time
description: The simplest, most intuitive date and time library
template: splash
hero:
title: The simplest, most intuitive date and time library
tagline: Modern TypeScript library for date manipulation with full ES Modules support.
image:
alt: date-and-time
file: ./assets/logo.png
actions:
- text: Get Started
link: /date-and-time/guide
icon: right-arrow
variant: primary
- text: API Reference
link: /date-and-time/api
variant: minimal
- text: View on GitHub
link: https://github.com/knowledgecode/date-and-time
icon: external
variant: minimal
---
import { Card, CardGrid, Tabs, TabItem } from '@astrojs/starlight/components';
## Features
Written in TypeScript with ES2021 target. Tree-shakable modules for optimal bundle size.
Support for 40+ locales and multiple calendar systems. Arabic, Bengali, Myanmar numerals.
Complete timezone handling with IANA timezone database built-in.
Full TypeScript support with comprehensive type definitions and IntelliSense.
Import only what you need. Optimized for modern bundlers with sideEffects false.
Extensible plugin system allows you to extend formatters and parsers.
## Quick Example
```typescript
import { format, parse, addDays } from 'date-and-time';
import ja from 'date-and-time/locales/ja';
const now = new Date();
// Basic formatting
format(now, 'YYYY/MM/DD HH:mm:ss');
// => 2025/08/23 14:30:45
// Localized formatting
format(now, 'YYYY年M月D日(ddd)', { locale: ja });
// => 2025年8月23日(金)
// Timezone-aware formatting
format(now, 'YYYY-MM-DD HH:mm:ss [EST]', { timeZone: 'America/New_York' });
// => 2025-08-23 09:30:45 EST
// Parsing
const date = parse('2025/08/23 14:30:45', 'YYYY/MM/DD HH:mm:ss');
console.log(date)
// Date arithmetic
const futureDate = addDays(now, 7);
console.log(format(futureDate, 'YYYY/MM/DD'));
```
## Key Features in v4.x
- **Complete TypeScript rewrite** with enhanced type safety
- **Tree-shaking support** for better bundle optimization
- **Integrated timezone and timespan plugins** into the core library
- **Modern JavaScript** targeting ES2021 (Node.js ≥18 required)
- **Enhanced API** with options objects instead of boolean flags
- **Improved locale handling** with per-function locale specification
## Browser & Environment Support
- **Node.js**: 18+
- **Browsers**: Chrome 85+, Firefox 78+, Safari 14+, Edge 85+
- **Module Systems**: ES Modules, CommonJS
- **TypeScript**: 4.5+
## Installation
```bash
npm install date-and-time
```
```bash
yarn add date-and-time
```
```bash
pnpm add date-and-time
```
## Community
- [GitHub Repository](https://github.com/knowledgecode/date-and-time)
- [npm Package](https://www.npmjs.com/package/date-and-time)
- [Issue Tracker](https://github.com/knowledgecode/date-and-time/issues)
================================================
FILE: docs/locales.md
================================================
---
title: Locales
---
Locales customize the language-specific strings used in date formatting and parsing — month names, day-of-week names, and AM/PM indicators. By default, the library uses English (`en`). To use another language, import the corresponding locale module and pass it as the `locale` option.
```typescript
import { format, parse } from 'date-and-time';
import es from 'date-and-time/locales/es';
const date = new Date('2025-08-23T12:00:00');
format(date, 'MMMM D, YYYY', { locale: es });
// => agosto 23, 2025
format(date, 'ddd, D MMM', { locale: es });
// => sáb, 23 ago
```
## Supported Locales
The following 41 locales are available:
### ar (Arabic)
```typescript
import ar from 'date-and-time/locales/ar';
```
### az (Azerbaijani)
```typescript
import az from 'date-and-time/locales/az';
```
### bn (Bengali)
```typescript
import bn from 'date-and-time/locales/bn';
```
### cs (Czech)
```typescript
import cs from 'date-and-time/locales/cs';
```
### da (Danish)
```typescript
import da from 'date-and-time/locales/da';
```
### de (German)
```typescript
import de from 'date-and-time/locales/de';
```
### el (Greek)
```typescript
import el from 'date-and-time/locales/el';
```
### en (English)
```typescript
import en from 'date-and-time/locales/en';
```
### es (Spanish)
```typescript
import es from 'date-and-time/locales/es';
```
### fa (Persian)
```typescript
import fa from 'date-and-time/locales/fa';
```
### fi (Finnish)
```typescript
import fi from 'date-and-time/locales/fi';
```
### fr (French)
```typescript
import fr from 'date-and-time/locales/fr';
```
### he (Hebrew)
```typescript
import he from 'date-and-time/locales/he';
```
### hi (Hindi)
```typescript
import hi from 'date-and-time/locales/hi';
```
### hu (Hungarian)
```typescript
import hu from 'date-and-time/locales/hu';
```
### id (Indonesian)
```typescript
import id from 'date-and-time/locales/id';
```
### it (Italian)
```typescript
import it from 'date-and-time/locales/it';
```
### ja (Japanese)
```typescript
import ja from 'date-and-time/locales/ja';
```
### ko (Korean)
```typescript
import ko from 'date-and-time/locales/ko';
```
### ms (Malay)
```typescript
import ms from 'date-and-time/locales/ms';
```
### my (Burmese)
```typescript
import my from 'date-and-time/locales/my';
```
### nl (Dutch)
```typescript
import nl from 'date-and-time/locales/nl';
```
### no (Norwegian)
```typescript
import no from 'date-and-time/locales/no';
```
### pl (Polish)
```typescript
import pl from 'date-and-time/locales/pl';
```
### pt-BR (Brazilian Portuguese)
```typescript
import ptBR from 'date-and-time/locales/pt-BR';
```
### pt-PT (European Portuguese)
```typescript
import ptPT from 'date-and-time/locales/pt-PT';
```
### ro (Romanian)
```typescript
import ro from 'date-and-time/locales/ro';
```
### ru (Russian)
```typescript
import ru from 'date-and-time/locales/ru';
```
### rw (Kinyarwanda)
```typescript
import rw from 'date-and-time/locales/rw';
```
### sr-Cyrl (Serbian Cyrillic)
```typescript
import srCyrl from 'date-and-time/locales/sr-Cyrl';
```
### sr-Latn (Serbian Latin)
```typescript
import srLatn from 'date-and-time/locales/sr-Latn';
```
### sv (Swedish)
```typescript
import sv from 'date-and-time/locales/sv';
```
### ta (Tamil)
```typescript
import ta from 'date-and-time/locales/ta';
```
### th (Thai)
```typescript
import th from 'date-and-time/locales/th';
```
### tr (Turkish)
```typescript
import tr from 'date-and-time/locales/tr';
```
### uk (Ukrainian)
```typescript
import uk from 'date-and-time/locales/uk';
```
### uz-Cyrl (Uzbek Cyrillic)
```typescript
import uzCyrl from 'date-and-time/locales/uz-Cyrl';
```
### uz-Latn (Uzbek Latin)
```typescript
import uzLatn from 'date-and-time/locales/uz-Latn';
```
### vi (Vietnamese)
```typescript
import vi from 'date-and-time/locales/vi';
```
### zh-Hans (Simplified Chinese)
```typescript
import zhHans from 'date-and-time/locales/zh-Hans';
```
### zh-Hant (Traditional Chinese)
```typescript
import zhHant from 'date-and-time/locales/zh-Hant';
```
================================================
FILE: docs/migration.md
================================================
---
title: Migration Guide
---
Version `4.x` has been completely rewritten in TypeScript and some features from `3.x` are no longer compatible. This section explains the changes to each feature and the migration methods.
## Installation
Version `4.x` adopts a modern development style and no longer supports older browsers. Module imports are only supported in ES Modules or CommonJS style. Additionally, since functions can now be imported directly, it is more likely to reduce the final module size through bundler tree shaking.
### ES Modules (Recommended)
```typescript
import { format } from 'date-and-time';
format(new Date(), 'ddd, MMM DD YYYY');
// => Wed, Jul 09 2025
```
### CommonJS
```typescript
const { format } = require('date-and-time');
format(new Date(), 'ddd, MMM DD YYYY');
// => Wed, Jul 09 2025
```
## CDN Usage
For browser-only projects, you can use date-and-time directly from a CDN:
### Via jsDelivr
```html
```
### Via unpkg
```html
```
## API
### format
The third argument has been changed from `boolean` to `FormatterOptions`. With `FormatterOptions`, you can now specify timezone and locale settings. If you previously set the third argument to `true` to output in UTC timezone, you can achieve the same output as follows:
```typescript
import { format } from 'date-and-time';
format(new Date(), 'ddd, MMM DD YYYY hh:mm A [GMT]Z', { timeZone: 'UTC' });
// => Fri, Jan 02 2015 07:14 AM GMT+0000
```
Additionally, since the `timezone` plugin has been integrated into the main library, the `formatTZ` function is now obsolete. Pass an IANA timezone name string directly to the `timeZone` option:
```typescript
import { format } from 'date-and-time';
const now = new Date();
format(now, 'YYYY-MM-DD HH:mm:ss [EST]', { timeZone: 'America/New_York' });
// => 2025-08-23 09:30:45 EST
```
### parse
The third argument has been changed from `boolean` to `ParserOptions`. With `ParserOptions`, you can now specify timezone and locale settings. If you previously set the third argument to `true` to parse input in UTC timezone, you can achieve the same output as follows:
```typescript
import { parse } from 'date-and-time';
parse('11:14:05 PM', 'h:mm:ss A', { timeZone: 'UTC' });
// => Jan 02 1970 23:14:05 GMT+0000
```
Additionally, since the `timezone` plugin has been integrated into the main library, the `parseTZ` function is now obsolete. Pass an IANA timezone name string directly to the `timeZone` option:
```typescript
import { parse } from 'date-and-time';
import fr from 'date-and-time/locales/fr';
parse(
'02 janv. 2015, 11:14:05 PM', 'DD MMM YYYY, h:mm:ss A',
{ timeZone: 'Europe/Paris', locale: fr }
);
// => Jan 02 2015 23:14:05 GMT+0100
```
### preparse
The third argument has been changed from `boolean` to `ParserOptions`. With `ParserOptions`, you can now specify timezone and locale settings. If you previously set the third argument to `true` to parse input in UTC timezone, you can achieve the same output as follows:
```typescript
import { preparse } from 'date-and-time';
preparse('11:14:05 PM', 'h:mm:ss A', { timeZone: 'UTC' });
{
A: 1,
h: 11,
m: 14,
s: 5,
_index: 11,
_length: 11,
_match: 4
}
```
Additionally, the `PreparseResult` object returned by the `preparse` function has the following changes:
- Properties for tokens that were not read are not included. For example, in the code example above, since the string does not contain a date part, properties representing dates such as `Y`, `M`, and `D` are not included.
- Read values are returned as-is. For example, previously, time read in 12-hour format was converted to 24-hour format, but this is no longer done.
### isValid
The following usage that takes `PreparseResult` as an argument is now obsolete.
```typescript
import { isValid, preparse } from 'date-and-time';
const pr = preparse('11:14:05 PM', 'h:mm:ss A');
// This usage is no longer supported
isValid(pr);
```
Other changes are the same as for the `parse` function.
### transform
The fourth argument has been changed from `boolean` to `FormatterOptions`. With `FormatterOptions`, you can now specify timezone and locale settings. Additionally, `ParserOptions` has been added as a parameter before `FormatterOptions`. Since the `timezone` plugin has been integrated into the main library, the `transformTZ` function is now obsolete.
```typescript
import { transform } from 'date-and-time';
// Convert 24-hour format to 12-hour format
transform('13:05', 'HH:mm', 'hh:mm A', { timeZone: 'UTC' }, { timeZone: 'UTC' });
// => 01:05 PM
// Convert East Coast time to West Coast time
transform(
'3/8/2020 1:05 PM', 'D/M/YYYY h:mm A', 'D/M/YYYY h:mm A',
{ timeZone: 'America/New_York' }, { timeZone: 'America/Los_Angeles' }
);
// => 3/8/2020 10:05 AM
```
### addYears
The third argument has been changed from `boolean` to `TimeZone | UTC`. If you previously set the third argument to `true` to calculate in UTC timezone, you can achieve the same output as follows:
```typescript
import { addYears } from 'date-and-time';
const now = new Date(Date.UTC(2024, 2, 11, 1));
// => Mar 11 2024 01:00:00 GMT+0000
addYears(now, 1, 'UTC');
// => Mar 11 2025 01:00:00 GMT+0000
```
Additionally, since the `timezone` plugin has been integrated into the main library, the `addYearsTZ` function is now obsolete. Pass an IANA timezone name string directly:
```typescript
import { addYears } from 'date-and-time';
const now = new Date(2024, 2, 11, 1);
// => Mar 11 2024 01:00:00 GMT-07:00
addYears(now, 1, 'America/Los_Angeles');
// => Mar 11 2025 01:00:00 GMT-07:00
```
### addMonths
The changes are the same as for the `addYears` function.
### addDays
The changes are the same as for the `addYears` function.
### subtract
The calculation order has been reversed. Previously, the second argument was subtracted from the first argument, but now the first argument is subtracted from the second argument.
Additionally, the return value object has been changed to `Duration`. You can achieve the same output as before as follows:
```typescript
import { subtract } from 'date-and-time';
const yesterday = new Date(2015, 0, 1);
const today = new Date(2015, 0, 2);
subtract(yesterday, today).toDays().value; // => 1
subtract(yesterday, today).toHours().value; // => 24
subtract(yesterday, today).toMinutes().value; // => 1440
subtract(yesterday, today).toSeconds().value; // => 86400
subtract(yesterday, today).toMilliseconds().value; // => 86400000
```
### timeSpan
The `timeSpan` plugin is now obsolete as it has been integrated into the main library's `subtract` function. Please note that the argument order of the `subtract` function has changed. You can achieve the same output as before as follows:
```typescript
import { subtract } from 'date-and-time';
const new_years_day = new Date(2020, 0, 1);
const now = new Date(2020, 2, 5, 1, 2, 3, 4);
subtract(new_years_day, now).toDays().format('D HH:mm:ss.SSS');
// => 64 01:02:03.004
subtract(new_years_day, now).toHours().format('H [hours] m [minutes] s [seconds]');
// => 1537 hours 2 minutes 3 seconds
subtract(new_years_day, now).toMinutes().format('mmmmmmmmmm [minutes]');
// => 0000092222 minutes
```
## Locale
The method for switching locales has changed. Previously, the locale used throughout the library was switched, but now it is specified as a function argument. Below is a code example for the `format` function.
```typescript
import { format } from 'date-and-time';
import es from 'date-and-time/locales/es';
format(new Date(), 'dddd, D [de] MMMM [de] YYYY, h:mm aa [GMT]ZZ', { locale: es });
// => miércoles, 23 de julio de 2025, 12:38 a.m. GMT-07:00
```
## Plugins
The following plugins are now obsolete as they have been integrated into the main library:
- `meridiem`
- `timespan`
- `timezone`
The custom plugin feature that existed up to 3.x is not yet supported at this time.
================================================
FILE: docs/plugins.md
================================================
---
title: Plugins
---
`date-and-time` adopts a plugin system. Special tokens used relatively infrequently are provided as plugins outside the main library. By adding plugins as needed, you can use those tokens in `Formatter` and `Parser`. Here, `Formatter` refers to the output engine used by the `format` function, and `Parser` refers to the parsing engine used by the `parse`, `preparse`, and `isValid` functions. These engines are extended by adding plugins as arguments to these functions.
## Installation
### ESModules (Recommended)
```typescript
import { format } from 'date-and-time';
import { formatter as foobar } from 'date-and-time/plugins/foobar';
format(new Date(), 'ddd, MMM DD YYYY', { plugins: [foobar] });
```
### CommonJS
```typescript
const { format } = require('date-and-time');
const foobar = require('date-and-time/plugins/foobar');
format(new Date(), 'ddd, MMM DD YYYY', { plugins: [foobar.formatter] });
```
## day-of-week
This plugin adds tokens to the `Parser` for reading the day of the week. Since the day of the week does not provide information that identifies a specific date, it is a meaningless token, but it can be used to skip that portion when the string you want to read contains a day of the week.
### Parser
| Token | Meaning | Input Examples |
|-------|---------------------|----------------|
| dddd | Full day name | Friday, Sunday |
| ddd | Short day name | Fri, Sun |
| dd | Very short day name | Fr, Su |
```typescript
import { parse } from 'date-and-time';
import { parser as day_of_week } from 'date-and-time/plugins/day-of-week';
parse(
'Thursday, March 05, 2020', 'dddd, MMMM, D YYYY',
{ plugins: [day_of_week] }
);
```
## microsecond
This plugin adds tokens to the `Parser` for reading microseconds. Since the precision of JavaScript's Date type is milliseconds, these tokens are meaningless, but they can be used to skip that portion when the string you want to read contains microseconds.
### Parser
| Token | Meaning | Input Examples |
|--------|----------------------|----------------|
| SSSSSS | 6-digit milliseconds | 123456, 000001 |
| SSSSS | 5-digit milliseconds | 12345, 00001 |
| SSSS | 4-digit milliseconds | 1234, 0001 |
| fff | 3-digit microseconds | 753, 022 |
| ff | 2-digit microseconds | 75, 02 |
| f | 1-digit microseconds | 7, 0 |
```typescript
import { parse } from 'date-and-time';
import { parser as microsecond } from 'date-and-time/plugins/microsecond';
parse('12:34:56.123456', 'HH:mm:ss.SSSSSS', { plugins: [microsecond] });
parse('12:34:56 123.456', 'HH:mm:ss SSS.fff', { plugins: [microsecond] });
```
## nanosecond
This plugin adds tokens to the `Parser` for reading nanoseconds. Since the precision of JavaScript's Date type is milliseconds, these tokens are meaningless, but they can be used to skip that portion when the string you want to read contains nanoseconds.
### Parser
| Token | Meaning | Input Examples |
|-----------|----------------------|----------------------|
| SSSSSSSSS | 9-digit milliseconds | 123456789, 000000001 |
| SSSSSSSS | 8-digit milliseconds | 12345678, 00000001 |
| SSSSSSS | 7-digit milliseconds | 1234567, 0000001 |
| FFF | 3-digit nanoseconds | 753, 022 |
| FF | 2-digit nanoseconds | 75, 02 |
| F | 1-digit nanoseconds | 7, 0 |
```typescript
import { parse } from 'date-and-time';
import { parser as microsecond } from 'date-and-time/plugins/microsecond';
import { parser as nanosecond } from 'date-and-time/plugins/nanosecond';
parse(
'12:34:56.123456789',
'HH:mm:ss.SSSSSSSSS',
{ plugins: [microsecond, nanosecond] }
);
parse(
'12:34:56 123456.789',
'HH:mm:ss SSSSSS.FFF',
{ plugins: [microsecond, nanosecond] }
);
```
## ordinal
This plugin adds tokens to the `Formatter` and `Parser` for outputting or reading ordinal representations of days. This ordinal representation is limited to English and is not supported for locales other than English.
### Formatter
| Token | Meaning | Output Examples |
|-------|-------------------------------|-----------------|
| DDD | Ordinal representation of day | 1st, 2nd, 3rd |
```typescript
import { format } from 'date-and-time';
import { formatter as ordinal } from 'date-and-time/plugins/ordinal';
format(new Date(), 'MMM DDD YYYY', { plugins: [ordinal] });
// => Jan 1st 2019
```
### Parser
| Token | Meaning | Input Examples |
|-------|-------------------------------|----------------|
| DDD | Ordinal representation of day | 1st, 2nd, 3rd |
```typescript
import { parse } from 'date-and-time';
import { parser as ordinal } from 'date-and-time/plugins/ordinal';
parse('Jan 1st 2019', 'MMM DDD YYYY', { plugins: [ordinal] });
```
## quarter
This plugin adds a token to the `Formatter` for outputting the quarter of the year.
### Formatter
| Token | Meaning | Output Examples |
|-------|-----------------|-----------------|
| Q | Quarter of year | 1, 2, 3, 4 |
```typescript
import { format } from 'date-and-time';
import { formatter as quarter } from 'date-and-time/plugins/quarter';
format(new Date(2025, 0, 1), 'YYYY [Q]Q', { plugins: [quarter] });
// => 2025 Q1
format(new Date(2025, 9, 1), 'YYYY [Q]Q', { plugins: [quarter] });
// => 2025 Q4
```
## timestamp
This plugin adds tokens to the `Formatter` for outputting Unix timestamps.
### Formatter
| Token | Meaning | Output Examples |
|-------|-------------------------------|------------------|
| t | Unix timestamp (seconds) | 0, 1000000000 |
| T | Unix timestamp (milliseconds) | 0, 1000000000000 |
```typescript
import { format } from 'date-and-time';
import { formatter as timestamp } from 'date-and-time/plugins/timestamp';
format(new Date(1000000000000), 't', { plugins: [timestamp] });
// => 1000000000
format(new Date(1000000000000), 'T', { plugins: [timestamp] });
// => 1000000000000
```
## two-digit-year
This plugin adds tokens to the `Parser` for reading 2-digit years. This token identifies years based on the following rules:
- Values of 70 or above are interpreted as 1900s
- Values of 69 or below are interpreted as 2000s
### Parser
| Token | Meaning | Input Examples |
|-------|--------------|----------------|
| YY | 2-digit year | 90, 00, 08, 19 |
```typescript
import { parse } from 'date-and-time';
import { parser as two_digit_year } from 'date-and-time/plugins/two-digit-year';
parse('Dec 25 69', 'MMM DD YY', { plugins: [two_digit_year] });
// => Dec 25 2069
parse('Dec 25 70', 'MMM DD YY', { plugins: [two_digit_year] });
// => Dec 25 1970
```
## week
This plugin adds tokens to the `Formatter` for outputting ISO week dates. These tokens follow
the ISO 8601 week date system, where weeks start on Monday and the first week of
the year is the one that contains the first Thursday.
### Formatter
| Token | Meaning | Output Examples |
|-------|-------------------------------------|-----------------|
| W | ISO week number | 1, 27, 53 |
| WW | ISO week number (zero-padded) | 01, 27, 53 |
| G | ISO week year | 2024, 2025 |
| GG | ISO week year (2-digit zero-padded) | 24, 25 |
| GGGG | ISO week year (4-digit zero-padded) | 2024, 2025 |
```typescript
import { format } from 'date-and-time';
import { formatter as week } from 'date-and-time/plugins/week';
format(new Date(2024, 0, 1), 'GGGG-[W]WW', { plugins: [week] });
// => 2024-W01
// Note: Dec 30, 2024 belongs to ISO week year 2025
format(new Date(2024, 11, 30), 'YYYY vs GGGG [W]W', { plugins: [week] });
// => 2024 vs 2025 W1
```
## zonename
This plugin adds tokens to the `Formatter` for outputting timezone names. These timezone names are limited to English and are not supported for locales other than English.
### Formatter
| Token | Meaning | Output Examples |
|-------|---------------------|-----------------------|
| z | Short timezone name | PST, EST |
| zz | Long timezone name | Pacific Standard Time |
```typescript
import { format } from 'date-and-time';
import { formatter as zonename } from 'date-and-time/plugins/zonename';
format(
new Date(),
'MMMM DD YYYY H:mm zz',
{ plugins: [zonename] }
);
// March 14 2021 1:59 Pacific Standard Time
format(
new Date(),
'MMMM DD YYYY H:mm z',
{ plugins: [zonename], timeZone: 'Asia/Tokyo' }
);
// March 14 2021 18:59 JST
```
================================================
FILE: docs/styles/custom.css
================================================
/* ─── Font sizes (match VitePress heading scale) ─── */
:root {
--sl-text-h1: 1.75rem;
--sl-text-h2: 1.5rem;
--sl-text-h3: 1.25rem;
--sl-text-h4: 1.125rem;
}
@media (min-width: 50em) {
:root {
--sl-text-h1: 1.75rem;
--sl-text-h2: 1.5rem;
--sl-text-h3: 1.25rem;
--sl-text-h4: 1.125rem;
}
}
/* ─── Colors (neutral, matching VitePress) ─── */
:root {
--sl-color-text: rgba(235, 235, 245, 0.86);
/* Accent: #5672cd — dark mode */
--sl-color-accent-low: hsl(226, 40%, 18%);
--sl-color-accent: hsl(226, 54%, 57%);
--sl-color-accent-high: hsl(226, 80%, 85%);
}
:root[data-theme='light'] {
--sl-color-text: rgba(60, 60, 67);
--sl-color-hairline: rgba(60, 60, 67, 0.12);
--sl-color-hairline-light: rgba(60, 60, 67, 0.08);
/* Accent: #5672cd — light mode */
--sl-color-accent-low: hsl(226, 60%, 94%);
--sl-color-accent: hsl(226, 54%, 47%);
--sl-color-accent-high: hsl(226, 54%, 28%);
}
/* ─── h2 border-top (VitePress section divider style) ─── */
.sl-markdown-content h2:not(:where(.not-content *)) {
border-top: 1px solid var(--sl-color-hairline);
padding-top: 24px;
margin-top: 2em;
}
/* ─── Left sidebar menu line-height ─── */
.sidebar-content a,
.sidebar-content summary {
line-height: 1.6;
}
/* ─── "On this page" TOC line-height ─── */
starlight-toc a {
line-height: 1.6;
}
/* ─── Tables ─── */
.sl-markdown-content table:not(:where(.not-content *)) {
border-collapse: collapse;
margin: 20px 0;
font-size: 14px;
width: 100%;
}
.sl-markdown-content tr:not(:where(.not-content *)) {
border-top: 1px solid var(--sl-color-hairline);
border-bottom: 1px solid var(--sl-color-hairline);
transition: background-color 0.25s;
}
/* Zebra stripe (dark mode default) */
.sl-markdown-content tr:nth-child(2n):not(:where(.not-content *)) {
background-color: var(--sl-color-gray-6);
}
:root[data-theme='light'] .sl-markdown-content tr:nth-child(2n):not(:where(.not-content *)) {
background-color: var(--sl-color-gray-7);
}
/* th (dark mode default) */
.sl-markdown-content th:not(:where(.not-content *)) {
border: var(--ec-brdWd) solid var(--ec-brdCol);
padding: 8px 16px;
background-color: var(--sl-color-gray-6);
color: var(--sl-color-gray-3);
}
:root[data-theme='light'] .sl-markdown-content th:not(:where(.not-content *)) {
background-color: var(--sl-color-gray-7);
}
.sl-markdown-content td:not(:where(.not-content *)) {
border: var(--ec-brdWd) solid var(--ec-brdCol);
padding: 8px 16px;
}
/* ─── Pagination ─── */
.pagination-links {
margin-top: 40px;
padding-top: 24px;
border-top: 1px solid var(--sl-color-hairline);
}
.pagination-links a {
align-items: center;
gap: 0.75rem;
border-color: var(--sl-color-hairline);
border-radius: 8px;
padding: 16px;
box-shadow: none;
transition: border-color 0.25s;
}
.pagination-links a:hover {
border-color: var(--sl-color-accent);
}
.pagination-links a > span {
font-size: 0.75rem;
color: var(--sl-color-gray-3);
letter-spacing: 0.4px;
}
.pagination-links .link-title {
font-size: var(--sl-text-base);
line-height: 1.4;
color: var(--sl-color-white);
margin-top: 4px;
}
:root[data-theme='light'] .pagination-links .link-title {
color: var(--sl-color-gray-1);
}
.pagination-links svg {
color: var(--sl-color-accent);
flex-shrink: 0;
}
/* ─── Hero image ─── */
.hero img {
width: 320px;
height: 320px;
}
/* ─── Cards ─── */
/* Dark mode default */
article.card {
background-color: var(--sl-color-gray-6);
border: 1px solid var(--sl-color-gray-6);
border-radius: 12px;
transition: border-color 0.25s;
}
/* Light mode override */
:root[data-theme='light'] article.card {
background-color: var(--sl-color-gray-7);
border-color: var(--sl-color-gray-7);
}
article.card:hover {
border-color: var(--sl-color-accent);
}
article.card .title {
color: inherit;
}
================================================
FILE: docs/timezones.md
================================================
---
title: Timezones
---
Timezone support lets you format and parse dates in any timezone, regardless of the local system timezone. Pass an IANA timezone name string as the `timeZone` option to any function that accepts it — no additional imports are needed for the recommended approach.
```typescript
import { format } from 'date-and-time';
const date = new Date();
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
// => 2025-08-23 23:30:45
```
## Import Methods
There are three ways to import and use timezones with the date-and-time library:
### Method 1: IANA Timezone Name String (Recommended)
Pass an IANA timezone name string directly to any function that accepts a timezone option. No imports are required — just use the timezone name as a string.
```typescript
import { format } from 'date-and-time';
const date = new Date();
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' });
// => 2025-08-23 23:30:45
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: 'America/New_York' });
// => 2025-08-23 09:30:45
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Europe/London' });
// => 2025-08-23 14:30:45
```
The string `"UTC"` is treated specially by this library and is processed faster than other timezone strings. While other strings that represent UTC (e.g., `"Etc/UTC"`) are also recognized, using `"UTC"` is always recommended.
### Method 2: Consolidated Import (Deprecated)
**This approach is deprecated and will be removed in the next major version. Use IANA timezone name strings instead.**
Import multiple timezones from a single module using named imports.
```typescript
import { format } from 'date-and-time';
import { Tokyo, New_York, London, Sydney } from 'date-and-time/timezone';
const date = new Date();
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: Tokyo }); // JST
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: New_York }); // EST/EDT
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: London }); // GMT/BST
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: Sydney }); // AEDT/AEST
```
### Method 3: Individual Import (Deprecated)
**This approach is deprecated and will be removed in the next major version. Use IANA timezone name strings instead.**
Import each timezone you need directly from its module path.
```typescript
import { format } from 'date-and-time';
import Tokyo from 'date-and-time/timezones/Asia/Tokyo';
import New_York from 'date-and-time/timezones/America/New_York';
const date = new Date();
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: Tokyo });
// => 2025-08-23 23:30:45
format(date, 'YYYY-MM-DD HH:mm:ss', { timeZone: New_York });
// => 2025-08-23 09:30:45
```
## Regions
The timezones listed below are confirmed to work — since this library internally relies on the `Intl` API, other timezones supported by your runtime may also work.
1. [Africa](#africa)
2. [America](#america)
3. [Antarctica](#antarctica)
4. [Arctic](#arctic)
5. [Asia](#asia)
6. [Atlantic](#atlantic)
7. [Australia](#australia)
8. [Europe](#europe)
9. [Indian](#indian)
10. [Pacific](#pacific)
## Africa
- Africa/Abidjan
- Africa/Accra
- Africa/Addis_Ababa
- Africa/Algiers
- Africa/Asmara
- Africa/Bamako
- Africa/Bangui
- Africa/Banjul
- Africa/Bissau
- Africa/Blantyre
- Africa/Brazzaville
- Africa/Bujumbura
- Africa/Cairo
- Africa/Casablanca
- Africa/Ceuta
- Africa/Conakry
- Africa/Dakar
- Africa/Dar_es_Salaam
- Africa/Djibouti
- Africa/Douala
- Africa/El_Aaiun
- Africa/Freetown
- Africa/Gaborone
- Africa/Harare
- Africa/Johannesburg
- Africa/Juba
- Africa/Kampala
- Africa/Khartoum
- Africa/Kigali
- Africa/Kinshasa
- Africa/Lagos
- Africa/Libreville
- Africa/Lome
- Africa/Luanda
- Africa/Lubumbashi
- Africa/Lusaka
- Africa/Malabo
- Africa/Maputo
- Africa/Maseru
- Africa/Mbabane
- Africa/Mogadishu
- Africa/Monrovia
- Africa/Nairobi
- Africa/Ndjamena
- Africa/Niamey
- Africa/Nouakchott
- Africa/Ouagadougou
- Africa/Porto-Novo
- Africa/Sao_Tome
- Africa/Tripoli
- Africa/Tunis
- Africa/Windhoek
## America
- America/Adak
- America/Anchorage
- America/Anguilla
- America/Antigua
- America/Araguaina
- America/Argentina/Buenos_Aires
- America/Argentina/Catamarca
- America/Argentina/Cordoba
- America/Argentina/Jujuy
- America/Argentina/La_Rioja
- America/Argentina/Mendoza
- America/Argentina/Rio_Gallegos
- America/Argentina/Salta
- America/Argentina/San_Juan
- America/Argentina/San_Luis
- America/Argentina/Tucuman
- America/Argentina/Ushuaia
- America/Aruba
- America/Asuncion
- America/Atikokan
- America/Bahia_Banderas
- America/Bahia
- America/Barbados
- America/Belem
- America/Belize
- America/Blanc-Sablon
- America/Boa_Vista
- America/Bogota
- America/Boise
- America/Cambridge_Bay
- America/Campo_Grande
- America/Cancun
- America/Caracas
- America/Cayenne
- America/Cayman
- America/Chicago
- America/Chihuahua
- America/Ciudad_Juarez
- America/Costa_Rica
- America/Coyhaique
- America/Creston
- America/Cuiaba
- America/Curacao
- America/Danmarkshavn
- America/Dawson_Creek
- America/Dawson
- America/Denver
- America/Detroit
- America/Dominica
- America/Edmonton
- America/Eirunepe
- America/El_Salvador
- America/Fort_Nelson
- America/Fortaleza
- America/Glace_Bay
- America/Goose_Bay
- America/Grand_Turk
- America/Grenada
- America/Guadeloupe
- America/Guatemala
- America/Guayaquil
- America/Guyana
- America/Halifax
- America/Havana
- America/Hermosillo
- America/Indiana/Indianapolis
- America/Indiana/Knox
- America/Indiana/Marengo
- America/Indiana/Petersburg
- America/Indiana/Tell_City
- America/Indiana/Vevay
- America/Indiana/Vincennes
- America/Indiana/Winamac
- America/Inuvik
- America/Iqaluit
- America/Jamaica
- America/Juneau
- America/Kentucky/Louisville
- America/Kentucky/Monticello
- America/Kralendijk
- America/La_Paz
- America/Lima
- America/Los_Angeles
- America/Lower_Princes
- America/Maceio
- America/Managua
- America/Manaus
- America/Marigot
- America/Martinique
- America/Matamoros
- America/Mazatlan
- America/Menominee
- America/Merida
- America/Metlakatla
- America/Mexico_City
- America/Miquelon
- America/Moncton
- America/Monterrey
- America/Montevideo
- America/Montserrat
- America/Nassau
- America/New_York
- America/Nome
- America/Noronha
- America/North_Dakota/Beulah
- America/North_Dakota/Center
- America/North_Dakota/New_Salem
- America/Nuuk
- America/Ojinaga
- America/Panama
- America/Paramaribo
- America/Phoenix
- America/Port_of_Spain
- America/Port-au-Prince
- America/Porto_Velho
- America/Puerto_Rico
- America/Punta_Arenas
- America/Rankin_Inlet
- America/Recife
- America/Regina
- America/Resolute
- America/Rio_Branco
- America/Santarem
- America/Santiago
- America/Santo_Domingo
- America/Sao_Paulo
- America/Scoresbysund
- America/Sitka
- America/St_Barthelemy
- America/St_Johns
- America/St_Kitts
- America/St_Lucia
- America/St_Thomas
- America/St_Vincent
- America/Swift_Current
- America/Tegucigalpa
- America/Thule
- America/Tijuana
- America/Toronto
- America/Tortola
- America/Vancouver
- America/Whitehorse
- America/Winnipeg
- America/Yakutat
## Antarctica
- Antarctica/Casey
- Antarctica/Davis
- Antarctica/DumontDUrville
- Antarctica/Macquarie
- Antarctica/Mawson
- Antarctica/McMurdo
- Antarctica/Palmer
- Antarctica/Rothera
- Antarctica/Syowa
- Antarctica/Troll
- Antarctica/Vostok
## Arctic
- Arctic/Longyearbyen
## Asia
- Asia/Aden
- Asia/Almaty
- Asia/Amman
- Asia/Anadyr
- Asia/Aqtau
- Asia/Aqtobe
- Asia/Ashgabat
- Asia/Atyrau
- Asia/Baghdad
- Asia/Bahrain
- Asia/Baku
- Asia/Bangkok
- Asia/Barnaul
- Asia/Beirut
- Asia/Bishkek
- Asia/Brunei
- Asia/Chita
- Asia/Colombo
- Asia/Damascus
- Asia/Dhaka
- Asia/Dili
- Asia/Dubai
- Asia/Dushanbe
- Asia/Famagusta
- Asia/Gaza
- Asia/Hebron
- Asia/Ho_Chi_Minh
- Asia/Hong_Kong
- Asia/Hovd
- Asia/Irkutsk
- Asia/Jakarta
- Asia/Jayapura
- Asia/Jerusalem
- Asia/Kabul
- Asia/Kamchatka
- Asia/Karachi
- Asia/Kathmandu
- Asia/Khandyga
- Asia/Kolkata
- Asia/Krasnoyarsk
- Asia/Kuala_Lumpur
- Asia/Kuching
- Asia/Kuwait
- Asia/Macau
- Asia/Magadan
- Asia/Makassar
- Asia/Manila
- Asia/Muscat
- Asia/Nicosia
- Asia/Novokuznetsk
- Asia/Novosibirsk
- Asia/Omsk
- Asia/Oral
- Asia/Phnom_Penh
- Asia/Pontianak
- Asia/Pyongyang
- Asia/Qatar
- Asia/Qostanay
- Asia/Qyzylorda
- Asia/Riyadh
- Asia/Sakhalin
- Asia/Samarkand
- Asia/Seoul
- Asia/Shanghai
- Asia/Singapore
- Asia/Srednekolymsk
- Asia/Taipei
- Asia/Tashkent
- Asia/Tbilisi
- Asia/Tehran
- Asia/Thimphu
- Asia/Tokyo
- Asia/Tomsk
- Asia/Ulaanbaatar
- Asia/Urumqi
- Asia/Ust-Nera
- Asia/Vientiane
- Asia/Vladivostok
- Asia/Yakutsk
- Asia/Yangon
- Asia/Yekaterinburg
- Asia/Yerevan
## Atlantic
- Atlantic/Azores
- Atlantic/Bermuda
- Atlantic/Canary
- Atlantic/Cape_Verde
- Atlantic/Faroe
- Atlantic/Madeira
- Atlantic/Reykjavik
- Atlantic/South_Georgia
- Atlantic/St_Helena
- Atlantic/Stanley
## Australia
- Australia/Adelaide
- Australia/Brisbane
- Australia/Broken_Hill
- Australia/Darwin
- Australia/Eucla
- Australia/Hobart
- Australia/Lindeman
- Australia/Lord_Howe
- Australia/Melbourne
- Australia/Perth
- Australia/Sydney
## Europe
- Europe/Amsterdam
- Europe/Andorra
- Europe/Astrakhan
- Europe/Athens
- Europe/Belgrade
- Europe/Berlin
- Europe/Bratislava
- Europe/Brussels
- Europe/Bucharest
- Europe/Budapest
- Europe/Busingen
- Europe/Chisinau
- Europe/Copenhagen
- Europe/Dublin
- Europe/Gibraltar
- Europe/Guernsey
- Europe/Helsinki
- Europe/Isle_of_Man
- Europe/Istanbul
- Europe/Jersey
- Europe/Kaliningrad
- Europe/Kirov
- Europe/Kyiv
- Europe/Lisbon
- Europe/Ljubljana
- Europe/London
- Europe/Luxembourg
- Europe/Madrid
- Europe/Malta
- Europe/Mariehamn
- Europe/Minsk
- Europe/Monaco
- Europe/Moscow
- Europe/Oslo
- Europe/Paris
- Europe/Podgorica
- Europe/Prague
- Europe/Riga
- Europe/Rome
- Europe/Samara
- Europe/San_Marino
- Europe/Sarajevo
- Europe/Saratov
- Europe/Simferopol
- Europe/Skopje
- Europe/Sofia
- Europe/Stockholm
- Europe/Tallinn
- Europe/Tirane
- Europe/Ulyanovsk
- Europe/Vaduz
- Europe/Vatican
- Europe/Vienna
- Europe/Vilnius
- Europe/Volgograd
- Europe/Warsaw
- Europe/Zagreb
- Europe/Zurich
## Indian
- Indian/Antananarivo
- Indian/Chagos
- Indian/Christmas
- Indian/Cocos
- Indian/Comoro
- Indian/Kerguelen
- Indian/Mahe
- Indian/Maldives
- Indian/Mauritius
- Indian/Mayotte
- Indian/Reunion
## Pacific
- Pacific/Apia
- Pacific/Auckland
- Pacific/Bougainville
- Pacific/Chatham
- Pacific/Chuuk
- Pacific/Easter
- Pacific/Efate
- Pacific/Fakaofo
- Pacific/Fiji
- Pacific/Funafuti
- Pacific/Galapagos
- Pacific/Gambier
- Pacific/Guadalcanal
- Pacific/Guam
- Pacific/Honolulu
- Pacific/Kanton
- Pacific/Kiritimati
- Pacific/Kosrae
- Pacific/Kwajalein
- Pacific/Majuro
- Pacific/Marquesas
- Pacific/Midway
- Pacific/Nauru
- Pacific/Niue
- Pacific/Norfolk
- Pacific/Noumea
- Pacific/Pago_Pago
- Pacific/Palau
- Pacific/Pitcairn
- Pacific/Pohnpei
- Pacific/Port_Moresby
- Pacific/Rarotonga
- Pacific/Saipan
- Pacific/Tahiti
- Pacific/Tarawa
- Pacific/Tongatapu
- Pacific/Wake
- Pacific/Wallis
================================================
FILE: docs/tsconfig.json
================================================
{
"extends": "astro/tsconfigs/base",
"include": ["../.astro/types.d.ts", "./**/*"],
"exclude": ["../node_modules"]
}
================================================
FILE: eslint.config.js
================================================
import { defineConfig } from 'eslint/config';
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import stylistic from '@stylistic/eslint-plugin';
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.strictTypeChecked,
tseslint.configs.stylisticTypeChecked,
{
ignores: ["**/*.js", "**/*.mjs", "coverage", "dist", "docs", ".astro"]
},
{
files: ['**/*.ts'],
plugins: {
'@stylistic': stylistic
},
languageOptions: {
ecmaVersion: 2021,
sourceType: 'module',
globals: {
process: true
},
parserOptions: {
projectService: true
}
},
rules: {
'@typescript-eslint/no-extraneous-class': 'off',
'accessor-pairs': 'error',
'array-callback-return': 'error',
'block-scoped-var': 'error',
'consistent-return': 'error',
'curly': 'error',
'default-case-last': 'error',
'eqeqeq': ['error', 'smart'],
'func-name-matching': 'error',
'func-style': ['error', 'expression', { overrides: { namedExports: 'ignore' } }],
'grouped-accessor-pairs': 'error',
'max-depth': 'error',
'max-nested-callbacks': 'error',
'new-cap': 'error',
'no-caller': 'error',
'no-constructor-return': 'error',
'no-div-regex': 'error',
'no-else-return': 'error',
'no-empty-static-block': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-extra-label': 'error',
'no-implicit-globals': 'error',
'no-implied-eval': 'error',
'no-iterator': 'error',
'no-label-var': 'error',
'no-labels': 'error',
'no-lone-blocks': 'error',
'no-lonely-if': 'error',
'no-multi-assign': ['error', { ignoreNonDeclaration: true }],
'no-multi-str': 'error',
'no-negated-condition': 'error',
'no-new': 'error',
'no-new-func': 'error',
'no-new-wrappers': 'error',
'no-object-constructor': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-return-assign': 'error',
'no-script-url': 'error',
'no-self-compare': 'error',
'no-sequences': 'error',
'no-shadow-restricted-names': 'error',
'no-template-curly-in-string': 'error',
'no-undef-init': 'error',
'no-unmodified-loop-condition': 'error',
'no-unneeded-ternary': 'error',
'no-unreachable-loop': 'error',
'no-useless-call': 'error',
'no-useless-computed-key': 'error',
'no-useless-concat': 'error',
'no-useless-rename': 'error',
'no-useless-return': 'error',
'no-void': 'error',
'no-warning-comments': 'error',
'operator-assignment': 'error',
'prefer-exponentiation-operator': 'error',
'prefer-numeric-literals': 'error',
'prefer-object-has-own': 'error',
'prefer-object-spread': 'error',
'prefer-promise-reject-errors': ['error', { allowEmptyReject: true }],
'prefer-regex-literals': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'radix': 'error',
'require-atomic-updates': 'error',
'symbol-description': 'error',
'unicode-bom': 'error',
'yoda': 'error',
'@stylistic/array-bracket-spacing': ['warn', 'never'],
'@stylistic/arrow-spacing': 'warn',
'@stylistic/block-spacing': 'warn',
'@stylistic/comma-dangle': 'warn',
'@stylistic/comma-spacing': 'warn',
'@stylistic/comma-style': 'warn',
'@stylistic/computed-property-spacing': 'warn',
'@stylistic/dot-location': ['warn', 'property'],
'@stylistic/eol-last': 'warn',
'@stylistic/function-call-spacing': 'warn',
'@stylistic/generator-star-spacing': 'warn',
'@stylistic/implicit-arrow-linebreak': 'warn',
'@stylistic/indent': ['warn', 2, { SwitchCase: 0, ignoreComments: true }],
'@stylistic/jsx-quotes': 'warn',
'@stylistic/key-spacing': 'warn',
'@stylistic/keyword-spacing': 'warn',
'@stylistic/linebreak-style': 'warn',
'@stylistic/lines-between-class-members': 'warn',
'@stylistic/member-delimiter-style': ['warn', { multiline: { delimiter: 'semi', requireLast: true }, singleline: { delimiter: 'semi', requireLast: false } }],
'@stylistic/new-parens': 'warn',
'@stylistic/no-extra-parens': ['warn', 'functions'],
'@stylistic/no-extra-semi': 'warn',
'@stylistic/no-floating-decimal': 'warn',
'@stylistic/no-mixed-spaces-and-tabs': 'warn',
'@stylistic/no-multi-spaces': ['warn', { ignoreEOLComments: true }],
'@stylistic/no-tabs': 'warn',
'@stylistic/no-trailing-spaces': 'warn',
'@stylistic/no-whitespace-before-property': 'warn',
'@stylistic/nonblock-statement-body-position': 'warn',
'@stylistic/object-curly-newline': 'warn',
'@stylistic/object-curly-spacing': ['warn', 'always'],
'@stylistic/padding-line-between-statements': 'warn',
'@stylistic/quotes': ['warn', 'single'],
'@stylistic/rest-spread-spacing': 'warn',
'@stylistic/semi': 'warn',
'@stylistic/semi-spacing': 'warn',
'@stylistic/semi-style': 'warn',
'@stylistic/space-before-blocks': 'warn',
'@stylistic/space-in-parens': 'warn',
'@stylistic/space-infix-ops': 'warn',
'@stylistic/space-unary-ops': 'warn',
'@stylistic/switch-colon-spacing': 'warn',
'@stylistic/template-curly-spacing': 'warn',
'@stylistic/template-tag-spacing': 'warn',
'@stylistic/wrap-iife': ['warn', 'any'],
'@stylistic/yield-star-spacing': 'warn'
}
}
);
================================================
FILE: package.json
================================================
{
"name": "date-and-time",
"version": "4.5.0",
"description": "The simplest, most intuitive date and time library",
"keywords": [
"date",
"datetime",
"duration",
"format",
"parse",
"time",
"timezone"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./plugin": {
"types": "./dist/plugin.d.ts",
"import": "./dist/plugin.js",
"require": "./dist/plugin.cjs"
},
"./timezone": {
"types": "./dist/timezone.d.ts",
"import": "./dist/timezone.js",
"require": "./dist/timezone.cjs"
},
"./locales/*": {
"types": "./dist/locales/*.d.ts",
"import": "./dist/locales/*.js",
"require": "./dist/locales/*.cjs"
},
"./numerals/*": {
"types": "./dist/numerals/*.d.ts",
"import": "./dist/numerals/*.js",
"require": "./dist/numerals/*.cjs"
},
"./plugins/*": {
"types": "./dist/plugins/*.d.ts",
"import": "./dist/plugins/*.js",
"require": "./dist/plugins/*.cjs"
},
"./timezones/*": {
"types": "./dist/timezones/*.d.ts",
"import": "./dist/timezones/*.js",
"require": "./dist/timezones/*.cjs"
}
},
"files": [
"LICENSE",
"README.md",
"dist/"
],
"scripts": {
"build": "rm -rf dist && rollup -c",
"build-watch": "rollup -c --watch",
"build:ts": "rollup -c --config-ts",
"build:types": "rollup -c --config-types",
"docs:build": "astro build",
"docs:dev": "astro dev",
"docs:preview": "astro preview",
"lint": "eslint",
"prepublishOnly": "npm run build",
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"timezone": "tsx tools/timezone.ts",
"ts": "tsc --noEmit",
"zonename": "tsx tools/zonename.ts"
},
"author": "KNOWLEDGECODE",
"license": "MIT",
"engines": {
"node": ">=18"
},
"homepage": "https://knowledgecode.github.io/date-and-time/",
"bugs": {
"url": "https://github.com/knowledgecode/date-and-time/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/knowledgecode/date-and-time.git"
},
"type": "module",
"sideEffects": false,
"devDependencies": {
"@astrojs/starlight": "^0.38.5",
"@eslint/js": "^10.0.1",
"@rollup/plugin-alias": "^6.0.0",
"@rollup/plugin-terser": "^1.0.0",
"@stylistic/eslint-plugin": "^5.10.0",
"@types/node": "^25.6.0",
"@vitest/coverage-v8": "^4.1.5",
"astro": "^6.2.2",
"eslint": "^10.3.0",
"glob": "^13.0.6",
"prettier": "^3.8.3",
"rollup": "^4.60.3",
"rollup-plugin-dts": "^6.4.1",
"rollup-plugin-esbuild": "^6.2.1",
"tsx": "^4.21.0",
"typescript-eslint": "^8.59.2",
"vitest": "^4.1.5"
}
}
================================================
FILE: rollup.config.ts
================================================
import alias from '@rollup/plugin-alias';
import esbuild from 'rollup-plugin-esbuild';
import terser from '@rollup/plugin-terser';
import { dts } from 'rollup-plugin-dts';
import { globSync } from 'glob';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const outputDir = (input: string) => input.replace(/^src/g, 'dist').replace(/\/[^/]*$/g, '');
const replacePath = (input: string) => input.replace(/(^src\/|\.ts$)/g, '');
const ts = () => {
const plugins = [
alias({ entries: [{ find: '@', replacement: resolve(dirname(fileURLToPath(import.meta.url)), 'src') }] }),
esbuild({ minify: false, target: 'es2021' }),
terser()
];
const config = (input: string | Record, outputDir: string) => ({
input,
output: [
{ dir: outputDir, format: 'es' },
{ dir: outputDir, format: 'cjs', entryFileNames: '[name].cjs' }
],
plugins
});
return [
config('src/index.ts', 'dist'),
config('src/plugin.ts', 'dist'),
config('src/timezone.ts', 'dist'),
config(Object.fromEntries(globSync('src/numerals/**/*.ts').map(input => [replacePath(input), input])), 'dist'),
globSync('src/locales/**/*.ts').map(input => config(input, outputDir(input))),
globSync('src/plugins/**/*.ts').map(input => config(input, outputDir(input))),
config(Object.fromEntries(globSync('src/timezones/**/*.ts').map(input => [replacePath(input), input])), 'dist')
].flat();
};
const types = () => {
const plugins = [
alias({ entries: [{ find: '@', replacement: resolve(dirname(fileURLToPath(import.meta.url)), 'src') }] }),
dts()
];
const config = (input: string | Record, outputDir: string) => ({
input,
output: { dir: outputDir },
plugins
});
return [
config('src/index.ts', 'dist'),
config('src/plugin.ts', 'dist'),
config('src/timezone.ts', 'dist'),
config(Object.fromEntries(globSync('src/numerals/**/*.ts').map(input => [replacePath(input), input])), 'dist'),
globSync('src/locales/**/*.ts').map(input => config(input, outputDir(input))),
globSync('src/plugins/**/*.ts').map(input => config(input, outputDir(input))),
config(Object.fromEntries(globSync('src/timezones/**/*.ts').map(input => [replacePath(input), input])), 'dist')
].flat();
};
export default (args: Record) => {
if (args['config-ts']) {
return ts();
}
if (args['config-types']) {
return types();
}
return [...ts(), ...types()];
};
================================================
FILE: src/addDays.ts
================================================
import { toParts, fromParts, isUTC } from './datetime.ts';
import { isTimeZone, createTimezoneDate } from './zone.ts';
import type { TimeZone } from './zone.ts';
/**
* Adds the specified number of days to a Date object.
* @param dateObj - The Date object to modify
* @param days - The number of days to add
* @param [timeZone] - Optional time zone object, an IANA timezone name or 'UTC' to use Coordinated Universal Time.
* @returns A new Date object with the specified number of days added
*/
export function addDays(dateObj: Date, days: number, timeZone?: TimeZone | string) {
const zoneName = isTimeZone(timeZone) ? timeZone.zone_name : timeZone ?? undefined;
if (!zoneName || isUTC(zoneName)) {
const d = new Date(dateObj.getTime());
// Handle UTC calculation
if (isUTC(timeZone)) {
d.setUTCDate(d.getUTCDate() + days);
return d;
}
// Handle local time calculation
d.setDate(d.getDate() + days);
return d;
}
// Handle timezone-specific calculation
const parts = toParts(dateObj, zoneName);
parts.day += days;
parts.timezoneOffset = 0;
return createTimezoneDate(fromParts(parts), zoneName);
}
================================================
FILE: src/addHours.ts
================================================
/**
* Adds the specified number of hours to a Date object.
* @param dateObj - The Date object to modify
* @param hours - The number of hours to add
* @returns A new Date object with the specified number of hours added
*/
export function addHours(dateObj: Date, hours: number) {
return new Date(dateObj.getTime() + hours * 3600000);
}
================================================
FILE: src/addMilliseconds.ts
================================================
/**
* Adds the specified number of milliseconds to a Date object.
* @param dateObj - The Date object to modify
* @param milliseconds - The number of milliseconds to add
* @returns A new Date object with the specified number of milliseconds added
*/
export function addMilliseconds(dateObj: Date, milliseconds: number) {
return new Date(dateObj.getTime() + milliseconds);
}
================================================
FILE: src/addMinutes.ts
================================================
/**
* Adds the specified number of minutes to a Date object.
* @param dateObj - The Date object to modify
* @param minutes - The number of minutes to add
* @returns A new Date object with the specified number of minutes added
*/
export function addMinutes(dateObj: Date, minutes: number) {
return new Date(dateObj.getTime() + minutes * 60000);
}
================================================
FILE: src/addMonths.ts
================================================
import { toParts, fromParts, isUTC } from './datetime.ts';
import { isTimeZone, createTimezoneDate } from './zone.ts';
import type { TimeZone } from './zone.ts';
/**
* Adds the specified number of months to a Date object.
* @param dateObj - The Date object to modify
* @param months - The number of months to add
* @param [timeZone] - Optional time zone object, an IANA timezone name or 'UTC' to use Coordinated Universal Time.
* @returns A new Date object with the specified number of months added
*/
export function addMonths(dateObj: Date, months: number, timeZone?: TimeZone | string) {
const zoneName = isTimeZone(timeZone) ? timeZone.zone_name : timeZone ?? undefined;
if (!zoneName || isUTC(zoneName)) {
const d = new Date(dateObj.getTime());
// Handle UTC calculation
if (isUTC(timeZone)) {
d.setUTCMonth(d.getUTCMonth() + months);
// Adjust to last day of month if new month has fewer days
if (d.getUTCDate() < dateObj.getUTCDate()) {
d.setUTCDate(0);
return d;
}
return d;
}
// Handle local time calculation
d.setMonth(d.getMonth() + months);
// Adjust to last day of month if new month has fewer days
if (d.getDate() < dateObj.getDate()) {
d.setDate(0);
return d;
}
return d;
}
// Handle timezone-specific calculation
const parts = toParts(dateObj, zoneName);
parts.month += months;
parts.timezoneOffset = 0;
const d = new Date(fromParts(parts));
if (d.getUTCDate() < parts.day) {
d.setUTCDate(0);
}
return createTimezoneDate(
fromParts({
...parts,
year: d.getUTCFullYear(),
month: d.getUTCMonth() + 1,
day: d.getUTCDate()
}),
zoneName
);
}
================================================
FILE: src/addSeconds.ts
================================================
/**
* Adds the specified number of seconds to a Date object.
* @param dateObj - The Date object to modify
* @param seconds - The number of seconds to add
* @returns A new Date object with the specified number of seconds added
*/
export function addSeconds(dateObj: Date, seconds: number) {
return new Date(dateObj.getTime() + seconds * 1000);
}
================================================
FILE: src/addYears.ts
================================================
import { addMonths } from './addMonths.ts';
import type { TimeZone } from './zone.ts';
/**
* Adds the specified number of years to a Date object.
* @param dateObj - The Date object to modify
* @param years - The number of years to add
* @param [timeZone] - Optional time zone object, an IANA timezone name or 'UTC' to use Coordinated Universal Time.
* @returns A new Date object with the specified number of years added
*/
export function addYears(dateObj: Date, years: number, timeZone?: TimeZone | string) {
return addMonths(dateObj, years * 12, timeZone);
}
================================================
FILE: src/compile.ts
================================================
/** @preserve Copyright (c) KNOWLEDGECODE - MIT License */
export type CompiledObject = string[];
// Escape sequences for literal brackets
const LBRACKET = /\\\[/g;
const RBRACKET = /\\\]/g;
// Private Use Area characters to temporarily replace literal brackets
const PUA_LBRACKET = /\uE000/g;
const PUA_RBRACKET = /\uE001/g;
// Regular expression to match format tokens, literal text, and escaped characters
const REGEXP = /\[(?:[^[\]]|\[[^[\]]*])*]|([A-Za-z])\1*|\.{3}|./g;
/**
* Compiles a format string into a tokenized array for efficient parsing and formatting.
* @param formatString - The format string to compile
* @returns A compiled array where the first element is the original format string,
* followed by tokenized format components
*/
export const compile = (formatString: string): CompiledObject => {
const array = formatString.replace(LBRACKET, '\uE000').replace(RBRACKET, '\uE001').match(REGEXP) ?? [];
return [formatString, ...array.map(token => token.replace(PUA_LBRACKET, '[').replace(PUA_RBRACKET, ']'))];
};
================================================
FILE: src/datetime.ts
================================================
import { getDateTimeFormat } from './dtf.ts';
export interface DateTimeParts {
weekday: number;
year: number;
month: number;
day: number;
hour: number;
minute: number;
second: number;
fractionalSecond: number;
timezoneOffset: number;
}
export const fromParts = (parts: DateTimeParts) => {
return Date.UTC(
parts.year,
parts.month - (parts.year < 100 ? 1900 * 12 + 1 : 1),
parts.day,
parts.hour,
parts.minute,
parts.second,
parts.fractionalSecond + parts.timezoneOffset * 60000
);
};
export const dtfToParts = (dtf: Intl.DateTimeFormat, time: number): DateTimeParts => {
return dtf.formatToParts(time)
.reduce((parts, { type, value }) => {
switch (type) {
case 'weekday':
parts[type] = 'SunMonTueWedThuFriSat'.indexOf(value) / 3;
break;
case 'hour':
parts[type] = +value % 24;
break;
case 'year':
case 'month':
case 'day':
case 'minute':
case 'second':
case 'fractionalSecond':
parts[type] = +value;
}
return parts;
}, {
weekday: 4, year: 1970, month: 1, day: 1,
hour: 0, minute: 0, second: 0, fractionalSecond: 0,
timezoneOffset: 0
});
};
export const isUTC = (timeZone: unknown): timeZone is 'UTC' => {
return typeof timeZone === 'string' && timeZone.toUpperCase() === 'UTC';
};
export const toParts = (dateObj: Date, zoneName: string): DateTimeParts => {
if (isUTC(zoneName)) {
return {
weekday: dateObj.getUTCDay(),
year: dateObj.getUTCFullYear(),
month: dateObj.getUTCMonth() + 1,
day: dateObj.getUTCDate(),
hour: dateObj.getUTCHours(),
minute: dateObj.getUTCMinutes(),
second: dateObj.getUTCSeconds(),
fractionalSecond: dateObj.getUTCMilliseconds(),
timezoneOffset: 0
};
}
const time = dateObj.getTime();
const parts = dtfToParts(getDateTimeFormat(zoneName), time);
parts.timezoneOffset = (time - fromParts(parts)) / 60000;
return parts;
};
export interface DateLike {
/**
* Returns the year of the date.
*/
getFullYear(): number;
/**
* Returns the month of the date (0-11).
*/
getMonth(): number;
/**
* Returns the day of the month (1-31).
*/
getDate(): number;
/**
* Returns the hours of the date (0-23).
*/
getHours(): number;
/**
* Returns the minutes of the date (0-59).
*/
getMinutes(): number;
/**
* Returns the seconds of the date (0-59).
*/
getSeconds(): number;
/**
* Returns the milliseconds of the date (0-999).
*/
getMilliseconds(): number;
/**
* Returns the day of the week (0-6, where 0 is Sunday).
*/
getDay(): number;
/**
* Returns the time value in milliseconds since the Unix epoch (January 1, 1970).
*/
getTime(): number;
/**
* Returns the timezone offset in minutes from UTC.
*/
getTimezoneOffset(): number;
}
export class DateTime implements DateLike {
private readonly parts: DateTimeParts;
private readonly time: number;
constructor (dateObj: Date, zoneName: string) {
this.parts = toParts(dateObj, zoneName);
this.time = dateObj.getTime();
}
getFullYear () {
return this.parts.year;
}
getMonth () {
return this.parts.month - 1;
}
getDate () {
return this.parts.day;
}
getHours () {
return this.parts.hour;
}
getMinutes () {
return this.parts.minute;
}
getSeconds () {
return this.parts.second;
}
getMilliseconds () {
return this.parts.fractionalSecond;
}
getDay () {
return this.parts.weekday;
}
getTime () {
return this.time;
}
getTimezoneOffset () {
return this.parts.timezoneOffset;
}
}
================================================
FILE: src/dtf.ts
================================================
const cache = new Map();
export const getDateTimeFormat = (zoneName: string): Intl.DateTimeFormat => {
return cache.get(zoneName) ?? (() => {
const dtf = new Intl.DateTimeFormat('en-US', {
hour12: false, weekday: 'short', year: 'numeric', month: 'numeric', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
timeZone: zoneName
});
if (zoneName) {
cache.set(zoneName, dtf);
}
return dtf;
})();
};
================================================
FILE: src/duration.ts
================================================
import { compile } from './compile.ts';
import latn from './numerals/latn.ts';
import type { Numeral } from './numeral.ts';
const comment = /^\[(.*)\]$/;
interface DurationFormatter {
D?: number;
H?: number;
m?: number;
s?: number;
S?: number;
f?: number;
F?: number;
}
const nanosecondsPart = (parts: DurationFormatter, time: DOMHighResTimeStamp) => {
parts.F = Math.trunc(time * 1000000);
return parts;
};
const microsecondsPart = (parts: DurationFormatter, time: DOMHighResTimeStamp) => {
parts.f = Math.trunc(time * 1000);
return nanosecondsPart(parts, Math.abs(time) * 1000 % 1 / 1000);
};
const millisecondsPart = (parts: DurationFormatter, time: DOMHighResTimeStamp) => {
parts.S = Math.trunc(time);
return microsecondsPart(parts, Math.abs(time) % 1);
};
const secondsPart = (parts: DurationFormatter, time: number) => {
parts.s = Math.trunc(time / 1000);
return millisecondsPart(parts, Math.abs(time) % 1000);
};
const minutesPart = (parts: DurationFormatter, time: number) => {
parts.m = Math.trunc(time / 60000);
return secondsPart(parts, Math.abs(time) % 60000);
};
const hoursPart = (parts: DurationFormatter, time: number) => {
parts.H = Math.trunc(time / 3600000);
return minutesPart(parts, Math.abs(time) % 3600000);
};
const daysPart = (parts: DurationFormatter, time: number) => {
parts.D = Math.trunc(time / 86400000);
return hoursPart(parts, Math.abs(time) % 86400000);
};
const sign = (time: number) => {
return time < 0 || time === 0 && (1 / time) === -Infinity ? '-' : '';
};
const format = (times: DurationFormatter, formatString: string, numeral: Numeral = latn) => {
const pattern = compile(formatString).slice(1);
const resolveToken = (token: string) => {
if (token[0] in times) {
const time = times[token[0] as keyof DurationFormatter] ?? 0;
return numeral.encode(`${sign(time)}${String(Math.abs(time)).padStart(token.length, '0')}`);
}
return comment.test(token) ? token.replace(comment, '$1') : token;
};
return pattern.reduce((result, token) => result + resolveToken(token), '');
};
export interface NanosecondsParts {
nanoseconds: number;
}
export interface MicrosecondsParts extends NanosecondsParts {
microseconds: number;
}
export interface MillisecondsParts extends MicrosecondsParts {
milliseconds: number;
}
export interface SecondsParts extends MillisecondsParts {
seconds: number;
}
export interface MinutesParts extends SecondsParts {
minutes: number;
}
export interface HoursParts extends MinutesParts {
hours: number;
}
export interface DaysParts extends HoursParts {
days: number;
}
export interface DurationDescriptor {
/**
* The value of the duration in the respective unit.
*/
value: number;
/**
* Formats the duration according to the provided format string.
* @param formatString - The format string to use for formatting
* @param numeral - Optional numeral object for number formatting
* @returns Formatted string representation of the duration
*/
format: (formatString: string, numeral?: Numeral) => string;
/**
* Converts the duration to an object containing the parts of the duration in the respective unit.
* @returns An object containing the parts of the duration in the respective unit.
*/
toParts: () => T;
}
export class Duration {
private readonly time: DOMHighResTimeStamp;
constructor (time: DOMHighResTimeStamp) {
this.time = time;
}
/**
* Converts the duration to nanoseconds.
* @returns DurationDescriptor with the value in nanoseconds and methods to format and get
* the parts of the duration in nanoseconds.
*/
toNanoseconds (): DurationDescriptor {
return {
value: this.time * 1000000,
format: (formatString: string, numeral?: Numeral) => {
return format(nanosecondsPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
nanoseconds: Math.trunc(this.time * 1000000) + 0
};
}
};
}
/**
* Converts the duration to microseconds.
* @returns DurationDescriptor with the value in microseconds and methods to format and get
* the parts of the duration in microseconds and nanoseconds.
*/
toMicroseconds (): DurationDescriptor {
return {
value: this.time * 1000,
format: (formatString: string, numeral?: Numeral) => {
return format(microsecondsPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
microseconds: Math.trunc(this.time * 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
/**
* Converts the duration to milliseconds.
* @returns DurationDescriptor with the value in milliseconds and methods to format and get
* the parts of the duration in milliseconds, microseconds, and nanoseconds.
*/
toMilliseconds (): DurationDescriptor {
return {
value: this.time,
format: (formatString: string, numeral?: Numeral) => {
return format(millisecondsPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
milliseconds: Math.trunc(this.time) + 0,
microseconds: Math.trunc(this.time * 1000 % 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
/**
* Converts the duration to seconds.
* @returns DurationDescriptor with the value in seconds and methods to format and get
* the parts of the duration in seconds, milliseconds, microseconds, and nanoseconds.
*/
toSeconds (): DurationDescriptor {
return {
value: this.time / 1000,
format: (formatString: string, numeral?: Numeral) => {
return format(secondsPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
seconds: Math.trunc(this.time / 1000) + 0,
milliseconds: Math.trunc(this.time % 1000) + 0,
microseconds: Math.trunc(this.time * 1000 % 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
/**
* Converts the duration to minutes.
* @returns DurationDescriptor with the value in minutes and methods to format and get
* the parts of the duration in minutes, seconds, milliseconds, microseconds, and nanoseconds.
*/
toMinutes (): DurationDescriptor {
return {
value: this.time / 60000,
format: (formatString: string, numeral?: Numeral) => {
return format(minutesPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
minutes: Math.trunc(this.time / 60000) + 0,
seconds: Math.trunc(this.time % 86400000 % 3600000 % 60000 / 1000) + 0,
milliseconds: Math.trunc(this.time % 1000) + 0,
microseconds: Math.trunc(this.time * 1000 % 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
/**
* Converts the duration to hours.
* @returns DurationDescriptor with the value in hours and methods to format and get
* the parts of the duration in hours, minutes, seconds, milliseconds, microseconds, and nanoseconds.
*/
toHours (): DurationDescriptor {
return {
value: this.time / 3600000,
format: (formatString: string, numeral?: Numeral) => {
return format(hoursPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
hours: Math.trunc(this.time / 3600000) + 0,
minutes: Math.trunc(this.time % 86400000 % 3600000 / 60000) + 0,
seconds: Math.trunc(this.time % 86400000 % 3600000 % 60000 / 1000) + 0,
milliseconds: Math.trunc(this.time % 1000) + 0,
microseconds: Math.trunc(this.time * 1000 % 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
/**
* Converts the duration to days.
* @returns DurationDescriptor with the value in days and methods to format and get
* the parts of the duration in days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds.
*/
toDays (): DurationDescriptor {
return {
value: this.time / 86400000,
format: (formatString: string, numeral?: Numeral) => {
return format(daysPart({}, this.time), formatString, numeral);
},
toParts: () => {
return {
days: Math.trunc(this.time / 86400000) + 0,
hours: Math.trunc(this.time % 86400000 / 3600000) + 0,
minutes: Math.trunc(this.time % 86400000 % 3600000 / 60000) + 0,
seconds: Math.trunc(this.time % 86400000 % 3600000 % 60000 / 1000) + 0,
milliseconds: Math.trunc(this.time % 1000) + 0,
microseconds: Math.trunc(this.time * 1000 % 1000) + 0,
nanoseconds: Math.trunc(this.time * 1000000 % 1000) + 0
};
}
};
}
}
================================================
FILE: src/format.ts
================================================
import { compile } from './compile.ts';
import { DateTime } from './datetime.ts';
import { formatter as defaultFormatter } from './formatter.ts';
import en from './locales/en.ts';
import latn from './numerals/latn.ts';
import { isTimeZone } from './zone.ts';
import type { CompiledObject } from './compile.ts';
import type { FormatterOptions } from './formatter.ts';
const comment = /^\[(.*)\]$/;
/**
* Formats a Date object according to the specified format string.
* @param dateObj - The Date object to format
* @param arg - The format string or compiled object to match against the Date object
* @param [options] - Optional formatter options for customization
* @returns The formatted date string representation
*/
export function format(dateObj: Date, arg: string | CompiledObject, options?: FormatterOptions) {
const pattern = (typeof arg === 'string' ? compile(arg) : arg).slice(1);
const zoneName = isTimeZone(options?.timeZone) ? options.timeZone.zone_name : options?.timeZone;
const dateTime = zoneName ? new DateTime(dateObj, zoneName) : dateObj;
const formatterOptions = {
hour12: options?.hour12 ?? 'h12',
hour24: options?.hour24 ?? 'h23',
numeral: options?.numeral ?? latn,
calendar: options?.calendar ?? 'gregory',
timeZone: options?.timeZone,
locale: options?.locale ?? en
};
const formatters = [...options?.plugins ?? [], defaultFormatter];
const encode = formatterOptions.numeral.encode;
const resolveToken = (token: string, compiledObj: CompiledObject) => {
for (const formatter of formatters) {
if (formatter[token]) {
return encode(formatter[token](dateTime, formatterOptions, compiledObj));
}
}
return comment.test(token) ? token.replace(comment, '$1') : token;
};
return pattern.reduce((result, token) => result + resolveToken(token, pattern), '');
}
================================================
FILE: src/formatter.ts
================================================
import type { CompiledObject } from './compile.ts';
import type { DateLike } from './datetime.ts';
import type { Locale } from './locale.ts';
import type { Numeral } from './numeral.ts';
import type { TimeZone } from './zone.ts';
export interface FormatterPluginOptions {
/**
* The hour format to use for formatting.
* This is used when the hour is in 12-hour format.
* It can be 'h11' for 11-hour format or 'h12' for 12-hour format.
*/
hour12: 'h11' | 'h12';
/**
* The hour format to use for formatting.
* This is used when the hour is in 24-hour format.
* It can be 'h23' for 23-hour format or 'h24' for 24-hour format.
*/
hour24: 'h23' | 'h24';
/**
* The numeral system to use for formatting numbers.
* This is an object that provides methods to encode and decode numbers in the specified numeral system.
*/
numeral: Numeral;
/**
* The calendar system to use for formatting dates.
* This can be 'buddhist' for Buddhist calendar or 'gregory' for Gregorian calendar.
*/
calendar: 'buddhist' | 'gregory';
/**
* The time zone to use for formatting dates and times.
* This can be a specific time zone object, an IANA time zone name, or 'UTC' to use Coordinated Universal Time.
* If not specified, it defaults to undefined, which means the local time zone will be used.
*/
timeZone: TimeZone | string | undefined;
/**
* The locale to use for formatting dates and times.
* This is an object that provides methods to get localized month names, day names, and meridiems.
*/
locale: Locale;
}
export abstract class FormatterPlugin {
[key: string]: ((d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) => string) | undefined;
}
export interface FormatterOptions extends Partial {
plugins?: FormatterPlugin[];
}
const getFullYear = (d: DateLike, calendar: 'buddhist' | 'gregory') => {
return d.getFullYear() + (calendar === 'buddhist' ? 543 : 0);
};
class DefaultFormatter extends FormatterPlugin {
YYYY (d: DateLike, options: FormatterPluginOptions) {
return `000${String(getFullYear(d, options.calendar))}`.slice(-4);
}
YY (d: DateLike, options: FormatterPluginOptions) {
return `0${String(getFullYear(d, options.calendar))}`.slice(-2);
}
Y (d: DateLike, options: FormatterPluginOptions) {
return String(getFullYear(d, options.calendar));
}
MMMM (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMonthList({ style: 'long', compiledObj });
return list[d.getMonth()] ?? '';
}
MMM (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMonthList({ style: 'short', compiledObj });
return list[d.getMonth()] ?? '';
}
MM (d: DateLike) {
return `0${String(d.getMonth() + 1)}`.slice(-2);
}
M (d: DateLike) {
return String(d.getMonth() + 1);
}
DD (d: DateLike) {
return `0${String(d.getDate())}`.slice(-2);
}
D (d: DateLike) {
return String(d.getDate());
}
HH (d: DateLike, options: FormatterPluginOptions) {
return `0${String(d.getHours() || (options.hour24 === 'h24' ? 24 : 0))}`.slice(-2);
}
H (d: DateLike, options: FormatterPluginOptions) {
return String(d.getHours() || (options.hour24 === 'h24' ? 24 : 0));
}
AA (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMeridiemList({ style: 'long', compiledObj, case: 'uppercase' });
return list[+(d.getHours() > 11)] ?? '';
}
A (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMeridiemList({ style: 'short', compiledObj, case: 'uppercase' });
return list[+(d.getHours() > 11)] ?? '';
}
aa (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMeridiemList({ style: 'long', compiledObj, case: 'lowercase' });
return list[+(d.getHours() > 11)] ?? '';
}
a (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getMeridiemList({ style: 'short', compiledObj, case: 'lowercase' });
return list[+(d.getHours() > 11)] ?? '';
}
hh (d: DateLike, options: FormatterPluginOptions) {
return `0${String(d.getHours() % 12 || (options.hour12 === 'h12' ? 12 : 0))}`.slice(-2);
}
h (d: DateLike, options: FormatterPluginOptions) {
return String(d.getHours() % 12 || (options.hour12 === 'h12' ? 12 : 0));
}
mm (d: DateLike) {
return `0${String(d.getMinutes())}`.slice(-2);
}
m (d: DateLike) {
return String(d.getMinutes());
}
ss (d: DateLike) {
return `0${String(d.getSeconds())}`.slice(-2);
}
s (d: DateLike) {
return String(d.getSeconds());
}
SSS (d: DateLike) {
return `00${String(d.getMilliseconds())}`.slice(-3);
}
SS (d: DateLike) {
return `00${String(d.getMilliseconds())}`.slice(-3, -1);
}
S (d: DateLike) {
return `00${String(d.getMilliseconds())}`.slice(-3, -2);
}
dddd (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getDayOfWeekList({ style: 'long', compiledObj });
return list[d.getDay()] ?? '';
}
ddd (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getDayOfWeekList({ style: 'short', compiledObj });
return list[d.getDay()] ?? '';
}
dd (d: DateLike, options: FormatterPluginOptions, compiledObj: CompiledObject) {
const list = options.locale.getDayOfWeekList({ style: 'narrow', compiledObj });
return list[d.getDay()] ?? '';
}
Z (d: DateLike) {
const offset = d.getTimezoneOffset();
const absOffset = Math.abs(offset);
return `${offset > 0 ? '-' : '+'}${`0${String(absOffset / 60 | 0)}`.slice(-2)}${`0${String(absOffset % 60)}`.slice(-2)}`;
}
ZZ (d: DateLike) {
const offset = d.getTimezoneOffset();
const absOffset = Math.abs(offset);
return `${offset > 0 ? '-' : '+'}${`0${String(absOffset / 60 | 0)}`.slice(-2)}:${`0${String(absOffset % 60)}`.slice(-2)}`;
}
}
export const formatter = new DefaultFormatter();
================================================
FILE: src/index.ts
================================================
export { compile } from './compile.ts';
export { format } from './format.ts';
export { preparse } from './preparse.ts';
export { isValid } from './isValid.ts';
export { parse } from './parse.ts';
export { transform } from './transform.ts';
export { addYears } from './addYears.ts';
export { addMonths } from './addMonths.ts';
export { addDays } from './addDays.ts';
export { addHours } from './addHours.ts';
export { addMinutes } from './addMinutes.ts';
export { addSeconds } from './addSeconds.ts';
export { addMilliseconds } from './addMilliseconds.ts';
export { Duration } from './duration.ts';
export { subtract } from './subtract.ts';
export {
isLeapYear,
isSameDay,
getDaysInMonth,
getISOWeekYear,
getISOWeek
} from './utils.ts';
================================================
FILE: src/isValid.ts
================================================
import { preparse } from './preparse.ts';
import { getDaysInMonth } from './utils.ts';
import type { CompiledObject } from './compile.ts';
import type { ParsedComponents, ParserOptions } from './parser.ts';
import type { PreparseResult } from './preparse.ts';
/**
* Converts a year to the Gregorian calendar year based on the specified calendar system in the parser options.
* @param year - The year to convert, which may be in a non-Gregorian calendar system (e.g., Buddhist calendar)
* @param [options] - Optional parser options that may specify the calendar system to use for conversion
* @returns The corresponding Gregorian calendar year, or undefined if the input year is undefined
*/
export const toGregorianYear = (year: number | undefined, options?: ParserOptions) => {
return year === undefined ? year : year - (options?.calendar === 'buddhist' ? 543 : 0);
};
/**
* Gets the default date components to use when certain components are missing from the input string.
* @param [defaultDate] - An object containing default date components (year, month, day, hour, minute, second, millisecond, timezone offset)
* @returns An object with all date components filled in, using the provided default values or fallback defaults (e.g., year defaults to 1970)
*/
export const getDefaultDate = (defaultDate: ParsedComponents = {}) => {
return {
Y: defaultDate.Y ?? 1970,
M: defaultDate.M ?? 1,
D: defaultDate.D ?? 1,
H: defaultDate.H,
A: defaultDate.A,
h: defaultDate.h,
m: defaultDate.m ?? 0,
s: defaultDate.s ?? 0,
S: defaultDate.S ?? 0,
Z: defaultDate.Z
};
};
/**
* Validates whether a preparse result object is valid.
* @param pr - The preparse result object to validate
* @param [options] - Optional parser options
* @returns True if the preparse result is valid, false otherwise
*/
export function validatePreparseResult(pr: PreparseResult, options?: ParserOptions) {
const [min12, max12] = options?.hour12 === 'h11' ? [0, 11] : [1, 12];
const [min24, max24] = options?.hour24 === 'h24' ? [1, 24] : [0, 23];
const range = (value: number | undefined, min: number, max: number) => value === undefined || value >= min && value <= max;
const base = getDefaultDate(options?.defaultDate);
const year = toGregorianYear(pr.Y, options) ?? base.Y;
const month = pr.M ?? base.M;
return pr._index > 0
&& pr._length > 0
&& pr._index === pr._length
&& pr._match > 0
&& range(year, 1, 9999)
&& range(month, 1, 12)
&& range(pr.D ?? base.D, 1, getDaysInMonth(year, month))
&& range(pr.H ?? base.H, min24, max24)
&& range(pr.A ?? base.A, 0, 1)
&& range(pr.h ?? base.h, min12, max12)
&& range(pr.m ?? base.m, 0, 59)
&& range(pr.s ?? base.s, 0, 59)
&& range(pr.S ?? base.S, 0, 999)
&& range(pr.Z ?? base.Z, -913, 956);
}
/**
* Validates whether a date string is valid according to the specified format.
* @param dateString - The date string to validate
* @param arg - The format string or compiled object
* @param [options] - Optional parser options
* @returns True if the date string is valid, false otherwise
*/
export function isValid(dateString: string, arg: string | CompiledObject, options?: ParserOptions) {
return validatePreparseResult(preparse(dateString, arg, options), options);
}
================================================
FILE: src/locale.ts
================================================
import type { CompiledObject } from './compile.ts';
export interface LocaleOptions {
compiledObj: CompiledObject;
style: 'long' | 'short' | 'narrow';
case?: 'uppercase' | 'lowercase';
}
export interface Locale {
getLocale: () => string;
getMonthList: (options: LocaleOptions) => string[];
getDayOfWeekList: (options: LocaleOptions) => string[];
getMeridiemList: (options: LocaleOptions) => string[];
}
================================================
FILE: src/locales/ar.ts
================================================
/**
* @file Arabic (ar)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
MMM: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
dddd: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
ddd: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
dd: ['أح', 'اث', 'ثل', 'أر', 'خم', 'جم', 'سب'],
A: ['ص', 'م'],
AA: ['ص', 'م'],
a: ['ص', 'م'],
aa: ['ص', 'م']
};
export default new class implements Locale {
getLocale () {
return 'ar';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/az.ts
================================================
/**
* @file Azerbaijani (az)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['yanvar', 'fevral', 'mart', 'aprel', 'may', 'iyun', 'iyul', 'avqust', 'sentyabr', 'oktyabr', 'noyabr', 'dekabr'],
MMM: ['yan', 'fev', 'mar', 'apr', 'may', 'iyn', 'iyl', 'avq', 'sen', 'okt', 'noy', 'dek'],
dddd: ['bazar', 'bazar ertəsi', 'çərşənbə axşamı', 'çərşənbə', 'cümə axşamı', 'cümə', 'şənbə'],
ddd: ['B.', 'B.E.', 'Ç.A.', 'Ç.', 'C.A.', 'C.', 'Ş.'],
dd: ['7', '1', '2', '3', '4', '5', '6'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'az';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/bn.ts
================================================
/**
* @file Bangla (bn)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['জানুয়ারী', 'ফেব্রুয়ারী', 'মার্চ', 'এপ্রিল', 'মে', 'জুন', 'জুলাই', 'আগস্ট', 'সেপ্টেম্বর', 'অক্টোবর', 'নভেম্বর', 'ডিসেম্বর'],
MMM: ['জানু', 'ফেব', 'মার্চ', 'এপ্রি', 'মে', 'জুন', 'জুল', 'আগ', 'সেপ', 'অক্টো', 'নভে', 'ডিসে'],
dddd: ['রবিবার', 'সোমবার', 'মঙ্গলবার', 'বুধবার', 'বৃহস্পতিবার', 'শুক্রবার', 'শনিবার'],
ddd: ['রবি', 'সোম', 'মঙ্গল', 'বুধ', 'বৃহস্পতি', 'শুক্র', 'শনি'],
dd: ['র', 'সো', 'ম', 'বু', 'বৃ', 'শু', 'শ'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'bn';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/cs.ts
================================================
/**
* @file Czech (cs)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
['ledna', 'února', 'března', 'dubna', 'května', 'června', 'července', 'srpna', 'září', 'října', 'listopadu', 'prosince']
],
MMM: [
['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
['led', 'úno', 'bře', 'dub', 'kvě', 'čvn', 'čvc', 'srp', 'zář', 'říj', 'lis', 'pro']
],
dddd: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
ddd: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
dd: ['N', 'P', 'Ú', 'S', 'Č', 'P', 'S'],
A: ['dop.', 'odp.'],
AA: ['dop.', 'odp.'],
a: ['dop.', 'odp.'],
aa: ['dop.', 'odp.']
};
export default new class implements Locale {
getLocale () {
return 'cs';
}
getMonthList (options: LocaleOptions) {
return (options.style === 'long'
? list.MMMM
: list.MMM)[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1];
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/da.ts
================================================
/**
* @file Danish (da)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['januar', 'februar', 'marts', 'april', 'maj', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'december'],
MMM: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun.', 'jul.', 'aug.', 'sep.', 'okt.', 'nov.', 'dec.'],
dddd: ['søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag'],
ddd: ['søn.', 'man.', 'tirs.', 'ons.', 'tors.', 'fre.', 'lør.'],
dd: ['sø', 'ma', 'ti', 'on', 'to', 'fr', 'lø'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'da';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/de.ts
================================================
/**
* @file German (de)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
MMM: ['Jan.', 'Feb.', 'März', 'Apr.', 'Mai', 'Juni', 'Juli', 'Aug.', 'Sept.', 'Okt.', 'Nov.', 'Dez.'],
dddd: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
ddd: ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.'],
dd: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'de';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/el.ts
================================================
/**
* @file Greek (el)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'],
['Ιανουαρίου', 'Φεβρουαρίου', 'Μαρτίου', 'Απριλίου', 'Μαΐου', 'Ιουνίου', 'Ιουλίου', 'Αυγούστου', 'Σεπτεμβρίου', 'Οκτωβρίου', 'Νοεμβρίου', 'Δεκεμβρίου']
],
MMM: ['Ιαν', 'Φεβ', 'Μαρ', 'Απρ', 'Μαΐ', 'Ιουν', 'Ιουλ', 'Αυγ', 'Σεπ', 'Οκτ', 'Νοε', 'Δεκ'],
dddd: ['Κυριακή', 'Δευτέρα', 'Τρίτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σάββατο'],
ddd: ['Κυρ', 'Δευ', 'Τρί', 'Τετ', 'Πέμ', 'Παρ', 'Σάβ'],
dd: ['Κυ', 'Δε', 'Τρ', 'Τε', 'Πε', 'Πα', 'Σα'],
A: ['ΠΜ', 'ΜΜ'],
AA: ['Π.Μ.', 'Μ.Μ.'],
a: ['πμ', 'μμ'],
aa: ['π.μ.', 'μ.μ.']
};
export default new class implements Locale {
getLocale () {
return 'el';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1]
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/en.ts
================================================
/**
* @file English (en)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
MMM: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
dddd: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
ddd: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
dd: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'en';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/es.ts
================================================
/**
* @file Spanish (es)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
MMM: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sept', 'oct', 'nov', 'dic'],
dddd: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
ddd: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
dd: ['do', 'lu', 'ma', 'mi', 'ju', 'vi', 'sá'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'es';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/fa.ts
================================================
/**
* @file Persian (fa)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['دی', 'بهمن', 'اسفند', 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر'],
MMM: ['دی', 'بهمن', 'اسفند', 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر'],
dddd: ['یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'],
ddd: ['یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'],
dd: ['ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش'],
A: ['قبلازظهر', 'بعدازظهر'],
AA: ['قبلازظهر', 'بعدازظهر'],
a: ['قبلازظهر', 'بعدازظهر'],
aa: ['قبلازظهر', 'بعدازظهر']
};
export default new class implements Locale {
getLocale () {
return 'fa';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/fi.ts
================================================
/**
* @file Finnish (fi)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
['tammikuuta', 'helmikuuta', 'maaliskuuta', 'huhtikuuta', 'toukokuuta', 'kesäkuuta', 'heinäkuuta', 'elokuuta', 'syyskuuta', 'lokakuuta', 'marraskuuta', 'joulukuuta']
],
MMM: [
['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu'],
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
],
dddd: ['sunnuntai', 'maanantaina', 'tiistaina', 'keskiviikkona', 'torstaina', 'perjantaina', 'lauantaina'],
ddd: ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la'],
dd: ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la'],
A: ['ap.', 'ip.'],
AA: ['ap.', 'ip.'],
a: ['ap.', 'ip.'],
aa: ['ap.', 'ip.']
};
export default new class implements Locale {
getLocale () {
return 'fi';
}
getMonthList (options: LocaleOptions) {
return (options.style === 'long'
? list.MMMM
: list.MMM)[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1];
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/fr.ts
================================================
/**
* @file French (fr)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
MMM: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
dddd: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
ddd: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
dd: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'fr';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/he.ts
================================================
/**
* @file Hebrew (he)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
MMM: ['ינו׳', 'פבר׳', 'מרץ', 'אפר׳', 'מאי', 'יוני', 'יולי', 'אוג׳', 'ספט׳', 'אוק׳', 'נוב׳', 'דצמ׳'],
dddd: ['יום ראשון', 'יום שני', 'יום שלישי', 'יום רביעי', 'יום חמישי', 'יום שישי', 'יום שבת'],
ddd: ['יום א׳', 'יום ב׳', 'יום ג׳', 'יום ד׳', 'יום ה׳', 'יום ו׳', 'שבת'],
dd: ['א׳', 'ב׳', 'ג׳', 'ד׳', 'ה׳', 'ו׳', 'ש׳'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'he';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/hi.ts
================================================
/**
* @file Hindi (hi)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['जनवरी', 'फ़रवरी', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुलाई', 'अगस्त', 'सितंबर', 'अक्तूबर', 'नवंबर', 'दिसंबर'],
MMM: ['जन॰', 'फ़र॰', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुल॰', 'अग॰', 'सित॰', 'अक्तू॰', 'नव॰', 'दिस॰'],
dddd: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'],
ddd: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
dd: ['र', 'सो', 'मं', 'बु', 'गु', 'शु', 'श'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'hi';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/hu.ts
================================================
/**
* @file Hungarian (hu)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['január', 'február', 'március', 'április', 'május', 'június', 'július', 'augusztus', 'szeptember', 'október', 'november', 'december'],
MMM: ['jan.', 'febr.', 'márc.', 'ápr.', 'máj.', 'jún.', 'júl.', 'aug.', 'szept.', 'okt.', 'nov.', 'dec.'],
dddd: ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'],
ddd: ['vas', 'hét', 'kedd', 'sze', 'csüt', 'pén', 'szo'],
dd: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
A: ['DE', 'DU'],
AA: ['DE.', 'DU.'],
a: ['de', 'du'],
aa: ['de.', 'du.']
};
export default new class implements Locale {
getLocale () {
return 'hu';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/id.ts
================================================
/**
* @file Indonesian (id)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'],
MMM: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'],
dddd: ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'],
ddd: ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'],
dd: ['Mg', 'Sn', 'Sl', 'Rb', 'Km', 'Jm', 'Sb'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'id';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/it.ts
================================================
/**
* @file Italian (it)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'],
MMM: ['gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic'],
dddd: ['domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato'],
ddd: ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'],
dd: ['Do', 'Lu', 'Ma', 'Me', 'Gi', 'Ve', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'it';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ja.ts
================================================
/**
* @file Japanese (ja)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'],
ddd: ['日', '月', '火', '水', '木', '金', '土'],
dd: ['日', '月', '火', '水', '木', '金', '土'],
A: ['午前', '午後'],
AA: ['午前', '午後'],
a: ['午前', '午後'],
aa: ['午前', '午後']
};
export default new class implements Locale {
getLocale () {
return 'ja';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ko.ts
================================================
/**
* @file Korean (ko)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
MMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
dddd: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'],
ddd: ['일', '월', '화', '수', '목', '금', '토'],
dd: ['일', '월', '화', '수', '목', '금', '토'],
A: ['오전', '오후'],
AA: ['오전', '오후'],
a: ['오전', '오후'],
aa: ['오전', '오후']
};
export default new class implements Locale {
getLocale () {
return 'ko';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ms.ts
================================================
/**
* @file Malay (ms)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['Januari', 'Februari', 'Mac', 'April', 'Mei', 'Jun', 'Julai', 'Ogos', 'September', 'Oktober', 'November', 'Disember'],
MMM: ['Jan', 'Feb', 'Mac', 'Apr', 'Mei', 'Jun', 'Jul', 'Ogo', 'Sep', 'Okt', 'Nov', 'Dis'],
dddd: ['Ahad', 'Isnin', 'Selasa', 'Rabu', 'Khamis', 'Jumaat', 'Sabtu'],
ddd: ['Ahd', 'Isn', 'Sel', 'Rab', 'Kha', 'Jum', 'Sab'],
dd: ['Ahd', 'Isn', 'Sel', 'Rab', 'Kha', 'Jum', 'Sab'],
A: ['PG', 'PTG'],
AA: ['PG', 'PTG'],
a: ['PG', 'PTG'],
aa: ['PG', 'PTG']
};
export default new class implements Locale {
getLocale () {
return 'ms';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/my.ts
================================================
/**
* @file Burmese (my)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['ဇန်နဝါရီ', 'ဖေဖော်ဝါရီ', 'မတ်', 'ဧပြီ', 'မေ', 'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်', 'စက်တင်ဘာ', 'အောက်တိုဘာ', 'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
MMM: ['ဇန်', 'ဖေ', 'မတ်', 'ဧ', 'မေ', 'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်', 'နို', 'ဒီ'],
dddd: ['တနင်္ဂနွေ', 'တနင်္လာ', 'အင်္ဂါ', 'ဗုဒ္ဓဟူး', 'ကြာသပတေး', 'သောကြာ', 'စနေ'],
ddd: ['တနင်္ဂနွေ', 'တနင်္လာ', 'အင်္ဂါ', 'ဗုဒ္ဓဟူး', 'ကြာသပတေး', 'သောကြာ', 'စနေ'],
dd: ['တ', 'တ', 'အ', 'ဗ', 'က', 'သ', 'စ'],
A: ['နံနက်', 'ညနေ'],
AA: ['နံနက်', 'ညနေ'],
a: ['နံနက်', 'ညနေ'],
aa: ['နံနက်', 'ညနေ']
};
export default new class implements Locale {
getLocale () {
return 'my';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/nl.ts
================================================
/**
* @file Dutch (nl)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
MMM: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
dddd: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
ddd: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
dd: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'nl';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/no.ts
================================================
/**
* @file Norwegian (no)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember'],
MMM: ['jan.', 'feb.', 'mars', 'apr.', 'mai', 'juni', 'juli', 'aug.', 'sep.', 'okt.', 'nov.', 'des.'],
dddd: ['søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag'],
ddd: ['søn.', 'man.', 'tir.', 'ons.', 'tor.', 'fre.', 'lør.'],
dd: ['søn.', 'man.', 'tir.', 'ons.', 'tor.', 'fre.', 'lør.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'no';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/pl.ts
================================================
/**
* @file Polish (pl)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień'],
['stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca', 'lipca', 'sierpnia', 'września', 'października', 'listopada', 'grudnia']
],
MMM: ['sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru'],
dddd: ['niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota'],
ddd: ['niedz.', 'pon.', 'wt.', 'śr.', 'czw.', 'pt.', 'sob.'],
dd: ['ndz.', 'pn.', 'wt.', 'śr.', 'cz.', 'pt.', 'so.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'pl';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1]
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/pt-BR.ts
================================================
/**
* @file Brazilian Portuguese (pt-BR)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
MMM: ['jan.', 'fev.', 'mar.', 'abr.', 'mai.', 'jun.', 'jul.', 'ago.', 'set.', 'out.', 'nov.', 'dez.'],
dddd: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
ddd: ['dom.', 'seg.', 'ter.', 'qua.', 'qui.', 'sex.', 'sáb.'],
dd: ['1ª', '2ª', '3ª', '4ª', '5ª', '6ª', '7ª'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'pt-BR';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/pt-PT.ts
================================================
/**
* @file European Portuguese (pt-PT)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
MMM: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
dddd: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
ddd: ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'],
dd: ['Do', '2ª', '3ª', '4ª', '5ª', '6ª', 'Sa'],
A: ['da manhã', 'da tarde'],
AA: ['da manhã', 'da tarde'],
a: ['da manhã', 'da tarde'],
aa: ['da manhã', 'da tarde']
};
export default new class implements Locale {
getLocale () {
return 'pt-PT';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ro.ts
================================================
/**
* @file Romanian (ro)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['ianuarie', 'februarie', 'martie', 'aprilie', 'mai', 'iunie', 'iulie', 'august', 'septembrie', 'octombrie', 'noiembrie', 'decembrie'],
MMM: ['ian.', 'feb.', 'mar.', 'apr.', 'mai', 'iun.', 'iul.', 'aug.', 'sept.', 'oct.', 'nov.', 'dec.'],
dddd: ['duminică', 'luni', 'marți', 'miercuri', 'joi', 'vineri', 'sâmbătă'],
ddd: ['dum.', 'lun.', 'mar.', 'mie.', 'joi', 'vin.', 'sâm.'],
dd: ['du', 'lu', 'ma', 'mi', 'jo', 'vi', 'sâ'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'ro';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ru.ts
================================================
/**
* @file Russian (ru)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'],
['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
],
MMM: [
['янв.', 'февр.', 'март', 'апр.', 'май', 'июнь', 'июль', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.'],
['янв.', 'февр.', 'мар.', 'апр.', 'мая', 'июн.', 'июл.', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.']
],
dddd: ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'],
ddd: ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
dd: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'ru';
}
getMonthList (options: LocaleOptions) {
return (options.style === 'long'
? list.MMMM
: list.MMM)[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1];
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/rw.ts
================================================
/**
* @file Kinyarwanda (rw)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['Mutarama', 'Gashyantare', 'Werurwe', 'Mata', 'Gicurasi', 'Kamena', 'Nyakanga', 'Kanama', 'Nzeri', 'Ukwakira', 'Ugushyingo', 'Ukuboza'],
MMM: ['mut.', 'gas.', 'wer.', 'mat.', 'gic.', 'kam.', 'nya.', 'kan.', 'nze.', 'ukw.', 'ugu.', 'uku.'],
dddd: ['Ku cyumweru', 'Kuwa mbere', 'Kuwa kabiri', 'Kuwa gatatu', 'Kuwa kane', 'Kuwa gatanu', 'Kuwa gatandatu'],
ddd: ['cyu.', 'mbe.', 'kab.', 'gtu.', 'kan.', 'gnu.', 'gnd.'],
dd: ['cyu.', 'mbe.', 'kab.', 'gtu.', 'kan.', 'gnu.', 'gnd.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'rw';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/sr-Cyrl.ts
================================================
/**
* @file Serbian (sr-Cyrl)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
MMM: ['јан', 'феб', 'мар', 'апр', 'мај', 'јун', 'јул', 'авг', 'сеп', 'окт', 'нов', 'дец'],
dddd: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
ddd: ['нед', 'пон', 'уто', 'сре', 'чет', 'пет', 'суб'],
dd: ['нед', 'пон', 'уто', 'сре', 'чет', 'пет', 'суб'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'sr-Cyrl';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/sr-Latn.ts
================================================
/**
* @file Serbian (sr-Latn)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
MMM: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'avg', 'sep', 'okt', 'nov', 'dec'],
dddd: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
ddd: ['ned', 'pon', 'uto', 'sre', 'čet', 'pet', 'sub'],
dd: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'sr-Latn';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/sv.ts
================================================
/**
* @file Swedish (sv)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['januari', 'februari', 'mars', 'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober', 'november', 'december'],
MMM: ['jan.', 'feb.', 'mars', 'apr.', 'maj', 'juni', 'juli', 'aug.', 'sep.', 'okt.', 'nov.', 'dec.'],
dddd: ['söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag'],
ddd: ['sön', 'mån', 'tis', 'ons', 'tors', 'fre', 'lör'],
dd: ['sö', 'må', 'ti', 'on', 'to', 'fr', 'lö'],
A: ['fm', 'em'],
AA: ['fm', 'em'],
a: ['fm', 'em'],
aa: ['fm', 'em']
};
export default new class implements Locale {
getLocale () {
return 'sv';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/ta.ts
================================================
/**
* @file Tamil (ta)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['ஜனவரி', 'பிப்ரவரி', 'மார்ச்', 'ஏப்ரல்', 'மே', 'ஜூன்', 'ஜூலை', 'ஆகஸ்ட்', 'செப்டம்பர்', 'அக்டோபர்', 'நவம்பர்', 'டிசம்பர்'],
MMM: ['ஜன.', 'பிப்.', 'மார்.', 'ஏப்.', 'மே', 'ஜூன்', 'ஜூலை', 'ஆக.', 'செப்.', 'அக்.', 'நவ.', 'டிச.'],
dddd: ['ஞாயிறு', 'திங்கள்', 'செவ்வாய்', 'புதன்', 'வியாழன்', 'வெள்ளி', 'சனி'],
ddd: ['ஞாயி.', 'திங்.', 'செவ்.', 'புத.', 'வியா.', 'வெள்.', 'சனி'],
dd: ['ஞா', 'தி', 'செ', 'பு', 'வி', 'வெ', 'ச'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
export default new class implements Locale {
getLocale () {
return 'ta';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/th.ts
================================================
/**
* @file Thai (th)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
MMM: ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'],
dddd: ['วันอาทิตย์', 'วันจันทร์', 'วันอังคาร', 'วันพุธ', 'วันพฤหัสบดี', 'วันศุกร์', 'วันเสาร์'],
ddd: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
dd: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
A: ['ก่อนเที่ยง', 'หลังเที่ยง'],
AA: ['ก่อนเที่ยง', 'หลังเที่ยง'],
a: ['ก่อนเที่ยง', 'หลังเที่ยง'],
aa: ['ก่อนเที่ยง', 'หลังเที่ยง']
};
export default new class implements Locale {
getLocale () {
return 'th';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/tr.ts
================================================
/**
* @file Turkish (tr)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'],
MMM: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
dddd: ['Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'],
ddd: ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'],
dd: ['Pz', 'Pt', 'Sa', 'Ça', 'Pe', 'Cu', 'Ct'],
A: ['ÖÖ', 'ÖS'],
AA: ['ÖÖ', 'ÖS'],
a: ['ÖÖ', 'ÖS'],
aa: ['ÖÖ', 'ÖS']
};
export default new class implements Locale {
getLocale () {
return 'tr';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/uk.ts
================================================
/**
* @file Ukrainian (uk)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: [
['січень', 'лютий', 'березень', 'квітень', 'травень', 'червень', 'липень', 'серпень', 'вересень', 'жовтень', 'листопад', 'грудень'],
['січня', 'лютого', 'березня', 'квітня', 'травня', 'червня', 'липня', 'серпня', 'вересня', 'жовтня', 'листопада', 'грудня']
],
MMM: ['січ.', 'лют.', 'бер.', 'квіт.', 'трав.', 'черв.', 'лип.', 'серп.', 'вер.', 'жовт.', 'лист.', 'груд.'],
dddd: ['неділя', 'понеділок', 'вівторок', 'середа', 'четвер', 'пʼятниця', 'субота'],
ddd: ['нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
dd: ['нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
A: ['дп', 'пп'],
AA: ['дп', 'пп'],
a: ['дп', 'пп'],
aa: ['дп', 'пп']
};
export default new class implements Locale {
getLocale () {
return 'uk';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM[options.compiledObj.findIndex(token => /^D+$/.test(token)) < 0 ? 0 : 1]
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/uz-Cyrl.ts
================================================
/**
* @file Uzbek (uz-Cyrl)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['январ', 'феврал', 'март', 'апрел', 'май', 'июн', 'июл', 'август', 'сентябр', 'октябр', 'ноябр', 'декабр'],
MMM: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'],
dddd: ['якшанба', 'душанба', 'сешанба', 'чоршанба', 'пайшанба', 'жума', 'шанба'],
ddd: ['якш', 'душ', 'сеш', 'чор', 'пай', 'жум', 'шан'],
dd: ['Як', 'Ду', 'Се', 'Чо', 'Па', 'Жу', 'Ша'],
A: ['ТО', 'ТК'],
AA: ['ТО', 'ТК'],
a: ['ТО', 'ТК'],
aa: ['ТО', 'ТК']
};
export default new class implements Locale {
getLocale () {
return 'uz-Cyrl';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/uz-Latn.ts
================================================
/**
* @file Uzbek (uz-Latn)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['yanvar', 'fevral', 'mart', 'aprel', 'may', 'iyun', 'iyul', 'avgust', 'sentabr', 'oktabr', 'noyabr', 'dekabr'],
MMM: ['yan', 'fev', 'mar', 'apr', 'may', 'iyn', 'iyl', 'avg', 'sen', 'okt', 'noy', 'dek'],
dddd: ['yakshanba', 'dushanba', 'seshanba', 'chorshanba', 'payshanba', 'juma', 'shanba'],
ddd: ['Yak', 'Dush', 'Sesh', 'Chor', 'Pay', 'Jum', 'Shan'],
dd: ['Yak', 'Dush', 'Sesh', 'Chor', 'Pay', 'Jum', 'Shan'],
A: ['TO', 'TK'],
AA: ['TO', 'TK'],
a: ['TO', 'TK'],
aa: ['TO', 'TK']
};
export default new class implements Locale {
getLocale () {
return 'uz-Latn';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/vi.ts
================================================
/**
* @file Vietnamese (vi)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['tháng 1', 'tháng 2', 'tháng 3', 'tháng 4', 'tháng 5', 'tháng 6', 'tháng 7', 'tháng 8', 'tháng 9', 'tháng 10', 'tháng 11', 'tháng 12'],
MMM: ['thg 1', 'thg 2', 'thg 3', 'thg 4', 'thg 5', 'thg 6', 'thg 7', 'thg 8', 'thg 9', 'thg 10', 'thg 11', 'thg 12'],
dddd: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'],
ddd: ['CN', 'Th 2', 'Th 3', 'Th 4', 'Th 5', 'Th 6', 'Th 7'],
dd: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
A: ['SA', 'CH'],
AA: ['SA', 'CH'],
a: ['SA', 'CH'],
aa: ['SA', 'CH']
};
export default new class implements Locale {
getLocale () {
return 'vi';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/zh-Hans.ts
================================================
/**
* @file Chinese (zh-Hans)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
ddd: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
dd: ['日', '一', '二', '三', '四', '五', '六'],
A: ['上午', '下午'],
AA: ['上午', '下午'],
a: ['上午', '下午'],
aa: ['上午', '下午']
};
export default new class implements Locale {
getLocale () {
return 'zh-Hans';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/locales/zh-Hant.ts
================================================
/**
* @file Chinese (zh-Hant)
*/
import type { Locale, LocaleOptions } from '@/locale.ts';
const list = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
ddd: ['週日', '週一', '週二', '週三', '週四', '週五', '週六'],
dd: ['日', '一', '二', '三', '四', '五', '六'],
A: ['上午', '下午'],
AA: ['上午', '下午'],
a: ['上午', '下午'],
aa: ['上午', '下午']
};
export default new class implements Locale {
getLocale () {
return 'zh-Hant';
}
getMonthList (options: LocaleOptions) {
return options.style === 'long'
? list.MMMM
: list.MMM;
}
getDayOfWeekList (options: LocaleOptions) {
return options.style === 'long'
? list.dddd
: options.style === 'short'
? list.ddd
: list.dd;
}
getMeridiemList (options: LocaleOptions) {
return options.style === 'long'
? options.case === 'lowercase'
? list.aa
: list.AA
: options.case === 'lowercase'
? list.a
: list.A;
}
}();
================================================
FILE: src/numeral.ts
================================================
export interface Numeral {
encode: (str: string) => string;
decode: (str: string) => string;
}
================================================
FILE: src/numerals/arab.ts
================================================
const numeral = '٠١٢٣٤٥٦٧٨٩';
const array = numeral.split('');
const map = Object.fromEntries(array.map((char, index) => [char, String(index)]));
export default {
encode: (str: string) => str.replace(/\d/g, char => array[+char]),
decode: (str: string) => str.replace(new RegExp(`[${numeral}]`, 'g'), char => map[char])
};
================================================
FILE: src/numerals/arabext.ts
================================================
const numeral = '۰۱۲۳۴۵۶۷۸۹';
const array = numeral.split('');
const map = Object.fromEntries(array.map((char, index) => [char, String(index)]));
export default {
encode: (str: string) => str.replace(/\d/g, char => array[+char]),
decode: (str: string) => str.replace(new RegExp(`[${numeral}]`, 'g'), char => map[char])
};
================================================
FILE: src/numerals/beng.ts
================================================
const numeral = '০১২৩৪৫৬৭৮৯';
const array = numeral.split('');
const map = Object.fromEntries(array.map((char, index) => [char, String(index)]));
export default {
encode: (str: string) => str.replace(/\d/g, char => array[+char]),
decode: (str: string) => str.replace(new RegExp(`[${numeral}]`, 'g'), char => map[char])
};
================================================
FILE: src/numerals/latn.ts
================================================
export default {
encode: (str: string) => str,
decode: (str: string) => str
};
================================================
FILE: src/numerals/mymr.ts
================================================
const numeral = '၀၁၂၃၄၅၆၇၈၉';
const array = numeral.split('');
const map = Object.fromEntries(array.map((char, index) => [char, String(index)]));
export default {
encode: (str: string) => str.replace(/\d/g, char => array[+char]),
decode: (str: string) => str.replace(new RegExp(`[${numeral}]`, 'g'), char => map[char])
};
================================================
FILE: src/parse.ts
================================================
import { createTimezoneDate, TimeZone } from './zone.ts';
import { isUTC } from './datetime.ts';
import { preparse } from './preparse.ts';
import { toGregorianYear, getDefaultDate, validatePreparseResult } from './isValid.ts';
import type { CompiledObject } from './compile.ts';
import type { ParserOptions } from './parser.ts';
const convert = (Y: number, M: number, D: number, H: number, m: number, s: number, S: number, timeZone?: string | TimeZone) => {
// If a specific time zone is provided in the options, use it to create the date.
if (timeZone) {
const naiveUTC = Date.UTC(Y, M - 1, D, H, m, s, S);
// If the specified time zone is UTC, create the date directly in UTC. Otherwise, create the date using the specified time zone.
return isUTC(timeZone) ? new Date(naiveUTC) : createTimezoneDate(naiveUTC, timeZone);
}
// If no time zone is provided, create the date in the local time zone.
return new Date(Y, M - 1, D, H, m, s, S);
};
/**
* Parses a date string according to the specified format.
* @param dateString - The date string to parse
* @param arg - The format string or compiled object to match against the date string
* @param [options] - Optional parser options for customization
* @returns The parsed Date object, or an invalid date if parsing fails
*/
export function parse(dateString: string, arg: string | CompiledObject, options?: ParserOptions) {
const pr = preparse(dateString, arg, options);
if (!validatePreparseResult(pr, options)) {
return new Date(NaN);
}
const base = getDefaultDate(options?.defaultDate);
const year = toGregorianYear(pr.Y, options) ?? base.Y;
// When a Z offset exists (from the parsed string or defaultDate.Z), it takes precedence over options.timeZone.
const offset = pr.Z ?? base.Z;
return convert(
year,
(pr.M ?? base.M) - (year < 100 ? 1900 * 12 : 0),
pr.D ?? base.D,
((pr.H ?? base.H ?? 0) % 24) || ((pr.A ?? base.A ?? 0) * 12 + (pr.h ?? base.h ?? 0) % 12),
(pr.m ?? base.m) + (offset ?? 0),
pr.s ?? base.s,
pr.S ?? base.S,
typeof offset === 'number' ? 'UTC' : options?.timeZone
);
}
================================================
FILE: src/parser.ts
================================================
import type { CompiledObject } from './compile.ts';
import type { Locale } from './locale.ts';
import type { Numeral } from './numeral.ts';
import type { TimeZone } from './zone.ts';
type ParserToken = 'Y' | 'M' | 'D' | 'H' | 'A' | 'h' | 'm' | 's' | 'S' | 'Z';
export interface ParsedComponents {
/**
* Year component
*/
Y?: number;
/**
* Month component (1-12)
*/
M?: number;
/**
* Day component
*/
D?: number;
/**
* Hour in 24-hour format
*/
H?: number;
/**
* Meridiem indicator (0:AM / 1:PM)
*/
A?: number;
/**
* Hour in 12-hour format
*/
h?: number;
/**
* Minute component
*/
m?: number;
/**
* Second component
*/
s?: number;
/**
* Millisecond component
*/
S?: number;
/**
* Timezone offset in minutes
*/
Z?: number;
}
export interface ParserPluginOptions {
/**
* The hour format to use for parsing.
* This is used when the hour is in 12-hour format.
* It can be 'h11' for 11-hour format or 'h12' for 12-hour format.
*/
hour12: 'h11' | 'h12';
/**
* The hour format to use for parsing.
* This is used when the hour is in 24-hour format.
* It can be 'h23' for 23-hour format or 'h24' for 24-hour format.
*/
hour24: 'h23' | 'h24';
/**
* The numeral system to use for parsing numbers.
* This is an object that provides methods to encode and decode numbers in the specified numeral system.
*/
numeral: Numeral;
/**
* The calendar system to use for parsing dates.
* This can be 'buddhist' for Buddhist calendar or 'gregory' for Gregorian calendar.
*/
calendar: 'buddhist' | 'gregory';
/**
* Whether to ignore case when matching strings.
* This is useful for matching month names, day names, and meridiems in a case-insensitive manner.
* If true, the parser will convert both the input string and the strings in the locale to lowercase before matching.
*/
ignoreCase: boolean;
/**
* The time zone to use for parsing dates and times.
* This can be a specific time zone object, an IANA time zone name, or 'UTC' to use Coordinated Universal Time.
* If not specified, it defaults to undefined, which means the local time zone will be used.
*/
timeZone: TimeZone | string | undefined;
/**
* The locale to use for parsing dates and times.
* This is an object that provides methods to get localized month names, day names, and meridiems.
*/
locale: Locale;
/**
* Default date components to use when certain components are missing from the input string.
* This allows the parser to fill in missing components with default values, which can be useful for parsing partial date strings.
* For example, if the input string only contains a month and day, the parser can use the default year from this object.
*/
defaultDate: ParsedComponents;
}
export interface ParseResult {
value: number;
length: number;
token?: ParserToken;
}
export abstract class ParserPlugin {
[key: string]: ((str: string, options: ParserPluginOptions, compiledObj: CompiledObject) => ParseResult) | undefined;
}
export interface ParserOptions extends Partial {
plugins?: ParserPlugin[];
}
/**
* Executes a regular expression against a string and returns parsed result.
* @param re - The regular expression to execute
* @param str - The string to execute the regex against
* @param [token] - Optional parser token to associate with the result
* @returns ParseResult containing the numeric value, length, and token
*/
export const exec = (re: RegExp, str: string, token?: ParserToken) => {
const result = re.exec(str)?.[0] ?? '';
return { value: +result, length: result.length, token };
};
/**
* Finds the best matching string from an array based on length and string position.
* @param array - Array of strings to search through
* @param str - The string to match against
* @param options - Parser plugin options
* @param [token] - Optional parser token to associate with the result
* @returns ParseResult with the index of the longest matching string at the start position
*/
export const find = (array: string[], str: string, options: ParserPluginOptions, token?: ParserToken): ParseResult => {
const [array2, str2] = options.ignoreCase ? (() => {
const locale = options.locale.getLocale();
return [array.map(s => s.toLocaleLowerCase(locale)), str.toLocaleLowerCase(locale)];
})() : [array, str];
return array2.reduce((result, item, value) => item.length > result.length && !str2.indexOf(item)
? { value, length: item.length, token }
: result,
{ value: -1, length: 0, token });
};
const VALID_TOKENS = new Set(['Y', 'M', 'D', 'H', 'A', 'h', 'm', 's', 'S', 'Z']);
/**
* Validates if a token is a recognized parser token.
* @param token - The token string to validate
* @returns True if the token is valid, false otherwise
*/
export const validateToken = (token: ParserToken) => VALID_TOKENS.has(token);
class DefaultParser extends ParserPlugin {
YYYY (str: string) {
return exec(/^\d{4}/, str, 'Y');
}
Y (str: string) {
return exec(/^\d{1,4}/, str, 'Y');
}
MMMM (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMonthList({ style: 'long', compiledObj });
const result = find(array, str, options, 'M');
result.value++;
return result;
}
MMM (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMonthList({ style: 'short', compiledObj });
const result = find(array, str, options, 'M');
result.value++;
return result;
}
MM (str: string) {
return exec(/^\d\d/, str, 'M');
}
M (str: string) {
return exec(/^\d\d?/, str, 'M');
}
DD (str: string) {
return exec(/^\d\d/, str, 'D');
}
D (str: string) {
return exec(/^\d\d?/, str, 'D');
}
HH (str: string) {
return exec(/^\d\d/, str, 'H');
}
H (str: string) {
return exec(/^\d\d?/, str, 'H');
}
AA (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMeridiemList({ style: 'long', compiledObj, case: 'uppercase' });
return find(array, str, options, 'A');
}
A (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMeridiemList({ style: 'short', compiledObj, case: 'uppercase' });
return find(array, str, options, 'A');
}
aa (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMeridiemList({ style: 'long', compiledObj, case: 'lowercase' });
return find(array, str, options, 'A');
}
a (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getMeridiemList({ style: 'short', compiledObj, case: 'lowercase' });
return find(array, str, options, 'A');
}
hh (str: string) {
return exec(/^\d\d/, str, 'h');
}
h (str: string) {
return exec(/^\d\d?/, str, 'h');
}
mm (str: string) {
return exec(/^\d\d/, str, 'm');
}
m (str: string) {
return exec(/^\d\d?/, str, 'm');
}
ss (str: string) {
return exec(/^\d\d/, str, 's');
}
s (str: string) {
return exec(/^\d\d?/, str, 's');
}
SSS (str: string) {
return exec(/^\d{1,3}/, str, 'S');
}
SS (str: string) {
const result = exec(/^\d\d?/, str, 'S');
result.value *= 10;
return result;
}
S (str: string) {
const result = exec(/^\d/, str, 'S');
result.value *= 100;
return result;
}
Z (str: string) {
const result = exec(/^[+-][01]\d[0-5]\d/, str, 'Z');
result.value = (result.value / 100 | 0) * -60 - result.value % 100;
return result;
}
ZZ (str: string) {
const results = /^([+-][01]\d):([0-5]\d)/.exec(str) ?? ['', '', ''];
const value = +(results[1] + results[2]);
return { value: (value / 100 | 0) * -60 - value % 100, length: results[0].length, token: 'Z' } satisfies ParseResult;
}
}
export const parser = new DefaultParser();
================================================
FILE: src/plugin.ts
================================================
export { FormatterPlugin } from './formatter.ts';
export { ParserPlugin, exec, find } from './parser.ts';
export type { FormatterPluginOptions } from './formatter.ts';
export type { ParserPluginOptions, ParseResult } from './parser.ts';
export type { CompiledObject } from './compile.ts';
export type { DateLike } from './datetime.ts';
export type { Locale } from './locale.ts';
export type { Numeral } from './numeral.ts';
export type { TimeZone } from './zone.ts';
================================================
FILE: src/plugins/day-of-week.ts
================================================
import { ParserPlugin, ParserPluginOptions, CompiledObject, find } from '@/plugin.ts';
class Parser extends ParserPlugin {
dddd (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getDayOfWeekList({ style: 'long', compiledObj });
return find(array, str, options);
}
ddd (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getDayOfWeekList({ style: 'short', compiledObj });
return find(array, str, options);
}
dd (str: string, options: ParserPluginOptions, compiledObj: CompiledObject) {
const array = options.locale.getDayOfWeekList({ style: 'narrow', compiledObj });
return find(array, str, options);
}
}
export const parser = new Parser();
================================================
FILE: src/plugins/microsecond.ts
================================================
import { ParserPlugin, exec } from '@/plugin.ts';
class Parser extends ParserPlugin {
SSSS (str: string) {
const result = exec(/^\d{1,4}/, str, 'S');
result.value = Math.trunc(result.value / 10);
return result;
}
SSSSS (str: string) {
const result = exec(/^\d{1,5}/, str, 'S');
result.value = Math.trunc(result.value / 100);
return result;
}
SSSSSS (str: string) {
const result = exec(/^\d{1,6}/, str, 'S');
result.value = Math.trunc(result.value / 1000);
return result;
}
f (str: string) {
return exec(/^\d/, str);
}
ff (str: string) {
return exec(/^\d\d?/, str);
}
fff (str: string) {
return exec(/^\d{1,3}/, str);
}
}
export const parser = new Parser();
================================================
FILE: src/plugins/nanosecond.ts
================================================
import { ParserPlugin, exec } from '@/plugin.ts';
class Parser extends ParserPlugin {
SSSSSSS (str: string) {
const result = exec(/^\d{1,7}/, str, 'S');
result.value = Math.trunc(result.value / 10000);
return result;
}
SSSSSSSS (str: string) {
const result = exec(/^\d{1,8}/, str, 'S');
result.value = Math.trunc(result.value / 100000);
return result;
}
SSSSSSSSS (str: string) {
const result = exec(/^\d{1,9}/, str, 'S');
result.value = Math.trunc(result.value / 1000000);
return result;
}
F (str: string) {
return exec(/^\d/, str);
}
FF (str: string) {
return exec(/^\d\d?/, str);
}
FFF (str: string) {
return exec(/^\d{1,3}/, str);
}
}
export const parser = new Parser();
================================================
FILE: src/plugins/ordinal.ts
================================================
import { FormatterPlugin, ParserPlugin, ParserPluginOptions, exec } from '@/plugin.ts';
import type { DateLike } from '@/plugin.ts';
class Formatter extends FormatterPlugin {
DDD (d: DateLike) {
const day = String(d.getDate());
switch (day) {
case '1':
case '21':
case '31':
return `${day}st`;
case '2':
case '22':
return `${day}nd`;
case '3':
case '23':
return `${day}rd`;
default:
return `${day}th`;
}
}
}
class Parser extends ParserPlugin {
DDD (str: string, options: ParserPluginOptions) {
const result = exec(/^\d\d?(?=st|nd|rd|th)/, options.ignoreCase ? str.toLowerCase() : str, 'D');
if (result.length > 0) {
result.length += 2;
}
return result;
}
}
export const formatter = new Formatter();
export const parser = new Parser();
================================================
FILE: src/plugins/quarter.ts
================================================
import { FormatterPlugin } from '@/plugin.ts';
import type { DateLike } from '@/plugin.ts';
class Formatter extends FormatterPlugin {
Q (d: DateLike) {
return String((d.getMonth() / 3 | 0) + 1);
}
}
export const formatter = new Formatter();
================================================
FILE: src/plugins/timestamp.ts
================================================
import { FormatterPlugin } from '@/plugin.ts';
import type { DateLike } from '@/plugin.ts';
class Formatter extends FormatterPlugin {
t (d: DateLike) {
return String(Math.floor(d.getTime() / 1000));
}
T (d: DateLike) {
return String(d.getTime());
}
}
export const formatter = new Formatter();
================================================
FILE: src/plugins/two-digit-year.ts
================================================
import { ParserPlugin, exec } from '@/plugin.ts';
import type { ParserPluginOptions } from '@/plugin.ts';
class Parser extends ParserPlugin {
YY (str: string, options: ParserPluginOptions) {
const result = exec(/^\d\d/, str, 'Y');
switch (options.calendar) {
case 'buddhist':
result.value += result.value < 13 ? 2600 : 2500;
break;
default:
result.value += result.value < 70 ? 2000 : 1900;
}
return result;
}
}
export const parser = new Parser();
================================================
FILE: src/plugins/week.ts
================================================
import { FormatterPlugin } from '@/plugin.ts';
import { getISOWeekYear, getISOWeek } from '@/utils.ts';
import type { DateLike } from '@/plugin.ts';
const _getISOWeekYear = (d: DateLike) => getISOWeekYear(d.getFullYear(), d.getMonth() + 1, d.getDate());
const _getISOWeek = (d: DateLike) => getISOWeek(d.getFullYear(), d.getMonth() + 1, d.getDate());
class Formatter extends FormatterPlugin {
W (d: DateLike) {
return String(_getISOWeek(d));
}
WW (d: DateLike) {
return `0${String(_getISOWeek(d))}`.slice(-2);
}
GGGG (d: DateLike) {
return `000${String(_getISOWeekYear(d))}`.slice(-4);
}
GG (d: DateLike) {
return `0${String(_getISOWeekYear(d))}`.slice(-2);
}
G (d: DateLike) {
return String(_getISOWeekYear(d));
}
}
export const formatter = new Formatter();
================================================
FILE: src/plugins/zonename.ts
================================================
import timeZoneNames from '@/zonenames.ts';
import { FormatterPlugin } from '@/plugin.ts';
import { isTimeZone } from '@/zone.ts';
import type { FormatterPluginOptions, DateLike } from '@/plugin.ts';
const getLongTimezoneName = (time: number, zoneName?: string) => {
const parts = new Intl.DateTimeFormat('en-US', {
timeZone: zoneName ?? undefined, timeZoneName: 'long'
}).formatToParts(time);
return parts.find(part => part.type === 'timeZoneName')?.value.replace(/^GMT[+-].+$/, '') ?? '';
};
const getShortTimezoneName = (time: number, zoneName?: string) => {
return timeZoneNames[getLongTimezoneName(time, zoneName) as keyof typeof timeZoneNames] || '';
};
class Formatter extends FormatterPlugin {
z (d: DateLike, options: FormatterPluginOptions) {
const zoneName = isTimeZone(options.timeZone) ? options.timeZone.zone_name : options.timeZone;
return getShortTimezoneName(d.getTime(), zoneName);
}
zz (d: DateLike, options: FormatterPluginOptions) {
const zoneName = isTimeZone(options.timeZone) ? options.timeZone.zone_name : options.timeZone;
return getLongTimezoneName(d.getTime(), zoneName);
}
}
export const formatter = new Formatter();
================================================
FILE: src/preparse.ts
================================================
import { compile } from './compile.ts';
import { isTimeZone } from './zone.ts';
import { parser as defaultParser, validateToken } from './parser.ts';
import en from './locales/en.ts';
import latn from './numerals/latn.ts';
import type { CompiledObject } from './compile.ts';
import type { ParsedComponents, ParserOptions } from './parser.ts';
export interface PreparseResult extends ParsedComponents {
/**
* Current parsing position
*/
_index: number;
/**
* Total length of date string
*/
_length: number;
/**
* Number of matched tokens
*/
_match: number;
}
const wildcard = ' ';
const comment = /^\[(.*)\]$/;
const ellipsis = '...';
/**
* Preparses a date string according to the specified pattern.
* @param dateString - The date string to preparse
* @param arg - The pattern string or compiled object to match against the date string
* @param [options] - Optional parser options
* @returns PreparseResult containing parsed date components and metadata
*/
export function preparse(dateString: string, arg: string | CompiledObject, options?: ParserOptions) {
const pattern = (typeof arg === 'string' ? compile(arg) : arg).slice(1);
const parserOptions = {
hour12: options?.hour12 ?? 'h12',
hour24: options?.hour24 ?? 'h23',
numeral: options?.numeral ?? latn,
calendar: options?.calendar ?? 'gregory',
ignoreCase: options?.ignoreCase ?? false,
timeZone: isTimeZone(options?.timeZone) || typeof options?.timeZone === 'string'
? options.timeZone || undefined
: undefined,
locale: options?.locale ?? en,
defaultDate: options?.defaultDate ?? {}
};
const pr: PreparseResult = {
_index: 0,
_length: 0,
_match: 0
};
const parsers = [...options?.plugins ?? [], defaultParser];
const resolveToken = (token: string, str: string) => {
for (const parser of parsers) {
if (parser[token]) {
return parser[token](str, parserOptions, pattern);
}
}
return undefined;
};
dateString = parserOptions.numeral.decode(dateString);
for (const token of pattern) {
const str = dateString.substring(pr._index);
const result = resolveToken(token, str);
if (result) {
if (!result.length) {
break;
}
if (result.token && validateToken(result.token)) {
pr[result.token] = result.value + 0;
}
pr._index += result.length;
pr._match++;
} else if (token === str[0] || token === wildcard) {
pr._index++;
} else if (comment.test(token) && !str.indexOf(token.replace(comment, '$1'))) {
pr._index += token.length - 2;
} else if (token === ellipsis) {
pr._index = dateString.length;
break;
} else {
break;
}
}
pr._length = dateString.length;
// Breaking change: 12-hour to 24-hour conversion is no longer performed here; values are preserved as read.
return pr;
}
================================================
FILE: src/subtract.ts
================================================
import { Duration } from './duration.ts';
/**
* Calculates the difference between two dates.
* @param from - The first Date object
* @param to - The second Date object
* @returns A Duration instance with methods to get the difference in various units
*/
export const subtract = (from: Date, to: Date) => {
return new Duration(to.getTime() - from.getTime());
};
================================================
FILE: src/timezone.ts
================================================
import { TimeZone } from '@/zone.ts';
export const Abidjan: TimeZone = {
zone_name: 'Africa/Abidjan',
gmt_offset: [0, -968]
};
export const Accra: TimeZone = {
zone_name: 'Africa/Accra',
gmt_offset: [1800, 1200, 0, -52]
};
export const Adak: TimeZone = {
zone_name: 'America/Adak',
gmt_offset: [44002, -32400, -36000, -39600, -42398]
};
export const Addis_Ababa: TimeZone = {
zone_name: 'Africa/Addis_Ababa',
gmt_offset: [10800, 9320, 9288]
};
export const Adelaide: TimeZone = {
zone_name: 'Australia/Adelaide',
gmt_offset: [37800, 34200, 33260, 32400]
};
export const Aden: TimeZone = {
zone_name: 'Asia/Aden',
gmt_offset: [10800, 10794]
};
export const Algiers: TimeZone = {
zone_name: 'Africa/Algiers',
gmt_offset: [7200, 3600, 732, 561, 0]
};
export const Almaty: TimeZone = {
zone_name: 'Asia/Almaty',
gmt_offset: [25200, 21600, 18468, 18000]
};
export const Amman: TimeZone = {
zone_name: 'Asia/Amman',
gmt_offset: [10800, 8624, 7200]
};
export const Amsterdam: TimeZone = {
zone_name: 'Europe/Amsterdam',
gmt_offset: [7200, 4800, 4772, 3600, 1200, 1172]
};
export const Anadyr: TimeZone = {
zone_name: 'Asia/Anadyr',
gmt_offset: [50400, 46800, 43200, 42596, 39600]
};
export const Anchorage: TimeZone = {
zone_name: 'America/Anchorage',
gmt_offset: [50424, -28800, -32400, -35976, -36000]
};
export const Andorra: TimeZone = {
zone_name: 'Europe/Andorra',
gmt_offset: [7200, 3600, 364, 0]
};
export const Anguilla: TimeZone = {
zone_name: 'America/Anguilla',
gmt_offset: [-14400, -15136]
};
export const Antananarivo: TimeZone = {
zone_name: 'Indian/Antananarivo',
gmt_offset: [14400, 11404, 10800]
};
export const Antigua: TimeZone = {
zone_name: 'America/Antigua',
gmt_offset: [-14400, -14832, -18000]
};
export const Apia: TimeZone = {
zone_name: 'Pacific/Apia',
gmt_offset: [50400, 46800, 45184, -36000, -39600, -41216, -41400]
};
export const Aqtau: TimeZone = {
zone_name: 'Asia/Aqtau',
gmt_offset: [21600, 18000, 14400, 12064]
};
export const Aqtobe: TimeZone = {
zone_name: 'Asia/Aqtobe',
gmt_offset: [21600, 18000, 14400, 13720]
};
export const Araguaina: TimeZone = {
zone_name: 'America/Araguaina',
gmt_offset: [-7200, -10800, -11568]
};
export const Aruba: TimeZone = {
zone_name: 'America/Aruba',
gmt_offset: [-14400, -16200, -16824]
};
export const Ashgabat: TimeZone = {
zone_name: 'Asia/Ashgabat',
gmt_offset: [21600, 18000, 14400, 14012]
};
export const Asmara: TimeZone = {
zone_name: 'Africa/Asmara',
gmt_offset: [10800, 9332, 9320]
};
export const Astrakhan: TimeZone = {
zone_name: 'Europe/Astrakhan',
gmt_offset: [18000, 14400, 11532, 10800]
};
export const Asuncion: TimeZone = {
zone_name: 'America/Asuncion',
gmt_offset: [-10800, -13840, -14400]
};
export const Athens: TimeZone = {
zone_name: 'Europe/Athens',
gmt_offset: [10800, 7200, 5692, 3600]
};
export const Atikokan: TimeZone = {
zone_name: 'America/Atikokan',
gmt_offset: [-18000, -21600, -21988]
};
export const Atyrau: TimeZone = {
zone_name: 'Asia/Atyrau',
gmt_offset: [21600, 18000, 14400, 12464, 10800]
};
export const Auckland: TimeZone = {
zone_name: 'Pacific/Auckland',
gmt_offset: [46800, 45000, 43200, 41944, 41400]
};
export const Azores: TimeZone = {
zone_name: 'Atlantic/Azores',
gmt_offset: [3600, 0, -3600, -6160, -6872, -7200]
};
export const Baghdad: TimeZone = {
zone_name: 'Asia/Baghdad',
gmt_offset: [14400, 10800, 10660, 10656]
};
export const Bahia: TimeZone = {
zone_name: 'America/Bahia',
gmt_offset: [-7200, -9244, -10800]
};
export const Bahia_Banderas: TimeZone = {
zone_name: 'America/Bahia_Banderas',
gmt_offset: [-18000, -21600, -25200, -25260]
};
export const Bahrain: TimeZone = {
zone_name: 'Asia/Bahrain',
gmt_offset: [14400, 12600, 12140, 10800]
};
export const Baku: TimeZone = {
zone_name: 'Asia/Baku',
gmt_offset: [18000, 14400, 11964, 10800]
};
export const Bamako: TimeZone = {
zone_name: 'Africa/Bamako',
gmt_offset: [0, -1920, -3600]
};
export const Bangkok: TimeZone = {
zone_name: 'Asia/Bangkok',
gmt_offset: [25200, 24124]
};
export const Bangui: TimeZone = {
zone_name: 'Africa/Bangui',
gmt_offset: [4460, 3600]
};
export const Banjul: TimeZone = {
zone_name: 'Africa/Banjul',
gmt_offset: [0, -3600, -3996]
};
export const Barbados: TimeZone = {
zone_name: 'America/Barbados',
gmt_offset: [-10800, -12600, -14309, -14400]
};
export const Barnaul: TimeZone = {
zone_name: 'Asia/Barnaul',
gmt_offset: [28800, 25200, 21600, 20100]
};
export const Beirut: TimeZone = {
zone_name: 'Asia/Beirut',
gmt_offset: [10800, 8520, 7200]
};
export const Belem: TimeZone = {
zone_name: 'America/Belem',
gmt_offset: [-7200, -10800, -11636]
};
export const Belgrade: TimeZone = {
zone_name: 'Europe/Belgrade',
gmt_offset: [7200, 4920, 3600]
};
export const Belize: TimeZone = {
zone_name: 'America/Belize',
gmt_offset: [-18000, -19800, -21168, -21600]
};
export const Berlin: TimeZone = {
zone_name: 'Europe/Berlin',
gmt_offset: [10800, 7200, 3600, 3208]
};
export const Bermuda: TimeZone = {
zone_name: 'Atlantic/Bermuda',
gmt_offset: [-10800, -11958, -14400, -15558]
};
export const Beulah: TimeZone = {
zone_name: 'America/North_Dakota/Beulah',
gmt_offset: [-18000, -21600, -24427, -25200]
};
export const Bishkek: TimeZone = {
zone_name: 'Asia/Bishkek',
gmt_offset: [25200, 21600, 18000, 17904]
};
export const Bissau: TimeZone = {
zone_name: 'Africa/Bissau',
gmt_offset: [0, -3600, -3740]
};
export const Blanc_Sablon: TimeZone = {
zone_name: 'America/Blanc-Sablon',
gmt_offset: [-10800, -13708, -14400]
};
export const Blantyre: TimeZone = {
zone_name: 'Africa/Blantyre',
gmt_offset: [8470, 8460, 8400, 7200]
};
export const Boa_Vista: TimeZone = {
zone_name: 'America/Boa_Vista',
gmt_offset: [-10800, -14400, -14560]
};
export const Bogota: TimeZone = {
zone_name: 'America/Bogota',
gmt_offset: [-14400, -17776, -18000]
};
export const Boise: TimeZone = {
zone_name: 'America/Boise',
gmt_offset: [-21600, -25200, -27889, -28800]
};
export const Bougainville: TimeZone = {
zone_name: 'Pacific/Bougainville',
gmt_offset: [39600, 37336, 36000, 35312, 32400]
};
export const Bratislava: TimeZone = {
zone_name: 'Europe/Bratislava',
gmt_offset: [7200, 3600, 3464, 0]
};
export const Brazzaville: TimeZone = {
zone_name: 'Africa/Brazzaville',
gmt_offset: [3668, 3600]
};
export const Brisbane: TimeZone = {
zone_name: 'Australia/Brisbane',
gmt_offset: [39600, 36728, 36000]
};
export const Broken_Hill: TimeZone = {
zone_name: 'Australia/Broken_Hill',
gmt_offset: [37800, 36000, 34200, 33948, 32400]
};
export const Brunei: TimeZone = {
zone_name: 'Asia/Brunei',
gmt_offset: [28800, 27580, 27000]
};
export const Brussels: TimeZone = {
zone_name: 'Europe/Brussels',
gmt_offset: [7200, 3600, 1050, 0]
};
export const Bucharest: TimeZone = {
zone_name: 'Europe/Bucharest',
gmt_offset: [10800, 7200, 6264]
};
export const Budapest: TimeZone = {
zone_name: 'Europe/Budapest',
gmt_offset: [7200, 4580, 3600]
};
export const Buenos_Aires: TimeZone = {
zone_name: 'America/Argentina/Buenos_Aires',
gmt_offset: [-7200, -10800, -14028, -14400, -15408]
};
export const Bujumbura: TimeZone = {
zone_name: 'Africa/Bujumbura',
gmt_offset: [7200, 7048]
};
export const Busingen: TimeZone = {
zone_name: 'Europe/Busingen',
gmt_offset: [7200, 3600, 2048, 1786]
};
export const Cairo: TimeZone = {
zone_name: 'Africa/Cairo',
gmt_offset: [10800, 7509, 7200]
};
export const Cambridge_Bay: TimeZone = {
zone_name: 'America/Cambridge_Bay',
gmt_offset: [0, -18000, -21600, -25200]
};
export const Campo_Grande: TimeZone = {
zone_name: 'America/Campo_Grande',
gmt_offset: [-10800, -13108, -14400]
};
export const Canary: TimeZone = {
zone_name: 'Atlantic/Canary',
gmt_offset: [3600, 0, -3600, -3696]
};
export const Cancun: TimeZone = {
zone_name: 'America/Cancun',
gmt_offset: [-14400, -18000, -20824, -21600]
};
export const Cape_Verde: TimeZone = {
zone_name: 'Atlantic/Cape_Verde',
gmt_offset: [-3600, -5644, -7200]
};
export const Caracas: TimeZone = {
zone_name: 'America/Caracas',
gmt_offset: [-14400, -16060, -16064, -16200]
};
export const Casablanca: TimeZone = {
zone_name: 'Africa/Casablanca',
gmt_offset: [3600, 0, -1820]
};
export const Casey: TimeZone = {
zone_name: 'Antarctica/Casey',
gmt_offset: [39600, 28800, 0]
};
export const Catamarca: TimeZone = {
zone_name: 'America/Argentina/Catamarca',
gmt_offset: [-7200, -10800, -14400, -15408, -15788]
};
export const Cayenne: TimeZone = {
zone_name: 'America/Cayenne',
gmt_offset: [-10800, -12560, -14400]
};
export const Cayman: TimeZone = {
zone_name: 'America/Cayman',
gmt_offset: [-18000, -18430, -19532]
};
export const Center: TimeZone = {
zone_name: 'America/North_Dakota/Center',
gmt_offset: [-18000, -21600, -24312, -25200]
};
export const Ceuta: TimeZone = {
zone_name: 'Africa/Ceuta',
gmt_offset: [7200, 3600, 0, -1276]
};
export const Chagos: TimeZone = {
zone_name: 'Indian/Chagos',
gmt_offset: [21600, 18000, 17380]
};
export const Chatham: TimeZone = {
zone_name: 'Pacific/Chatham',
gmt_offset: [49500, 45900, 44100, 44028]
};
export const Chicago: TimeZone = {
zone_name: 'America/Chicago',
gmt_offset: [-18000, -21036, -21600]
};
export const Chihuahua: TimeZone = {
zone_name: 'America/Chihuahua',
gmt_offset: [-18000, -21600, -25200, -25460]
};
export const Chisinau: TimeZone = {
zone_name: 'Europe/Chisinau',
gmt_offset: [14400, 10800, 7200, 6920, 6900, 6264, 3600]
};
export const Chita: TimeZone = {
zone_name: 'Asia/Chita',
gmt_offset: [36000, 32400, 28800, 27232]
};
export const Christmas: TimeZone = {
zone_name: 'Indian/Christmas',
gmt_offset: [25372, 25200]
};
export const Chuuk: TimeZone = {
zone_name: 'Pacific/Chuuk',
gmt_offset: [36428, 36000, 32400, -49972]
};
export const Ciudad_Juarez: TimeZone = {
zone_name: 'America/Ciudad_Juarez',
gmt_offset: [-18000, -21600, -25200, -25556]
};
export const Cocos: TimeZone = {
zone_name: 'Indian/Cocos',
gmt_offset: [23400, 23260]
};
export const Colombo: TimeZone = {
zone_name: 'Asia/Colombo',
gmt_offset: [23400, 21600, 19800, 19172, 19164]
};
export const Comoro: TimeZone = {
zone_name: 'Indian/Comoro',
gmt_offset: [10800, 10384]
};
export const Conakry: TimeZone = {
zone_name: 'Africa/Conakry',
gmt_offset: [0, -3292, -3600]
};
export const Copenhagen: TimeZone = {
zone_name: 'Europe/Copenhagen',
gmt_offset: [7200, 3600, 3020]
};
export const Cordoba: TimeZone = {
zone_name: 'America/Argentina/Cordoba',
gmt_offset: [-7200, -10800, -14400, -15408]
};
export const Costa_Rica: TimeZone = {
zone_name: 'America/Costa_Rica',
gmt_offset: [-18000, -20173, -21600]
};
export const Coyhaique: TimeZone = {
zone_name: 'America/Coyhaique',
gmt_offset: [-10800, -14400, -16965, -17296, -18000]
};
export const Creston: TimeZone = {
zone_name: 'America/Creston',
gmt_offset: [-25200, -27964, -28800]
};
export const Cuiaba: TimeZone = {
zone_name: 'America/Cuiaba',
gmt_offset: [-10800, -13460, -14400]
};
export const Curacao: TimeZone = {
zone_name: 'America/Curacao',
gmt_offset: [-14400, -16200, -16547]
};
export const Dakar: TimeZone = {
zone_name: 'Africa/Dakar',
gmt_offset: [0, -3600, -4184]
};
export const Damascus: TimeZone = {
zone_name: 'Asia/Damascus',
gmt_offset: [10800, 8712, 7200]
};
export const Danmarkshavn: TimeZone = {
zone_name: 'America/Danmarkshavn',
gmt_offset: [0, -4480, -7200, -10800]
};
export const Dar_es_Salaam: TimeZone = {
zone_name: 'Africa/Dar_es_Salaam',
gmt_offset: [10800, 9900, 9428]
};
export const Darwin: TimeZone = {
zone_name: 'Australia/Darwin',
gmt_offset: [37800, 34200, 32400, 31400]
};
export const Davis: TimeZone = {
zone_name: 'Antarctica/Davis',
gmt_offset: [25200, 18000, 0]
};
export const Dawson: TimeZone = {
zone_name: 'America/Dawson',
gmt_offset: [-25200, -28800, -32400, -33460]
};
export const Dawson_Creek: TimeZone = {
zone_name: 'America/Dawson_Creek',
gmt_offset: [-25200, -28800, -28856]
};
export const Denver: TimeZone = {
zone_name: 'America/Denver',
gmt_offset: [-21600, -25196, -25200]
};
export const Detroit: TimeZone = {
zone_name: 'America/Detroit',
gmt_offset: [-14400, -18000, -19931, -21600]
};
export const Dhaka: TimeZone = {
zone_name: 'Asia/Dhaka',
gmt_offset: [25200, 23400, 21700, 21600, 21200, 19800]
};
export const Dili: TimeZone = {
zone_name: 'Asia/Dili',
gmt_offset: [32400, 30140, 28800]
};
export const Djibouti: TimeZone = {
zone_name: 'Africa/Djibouti',
gmt_offset: [10800, 10356]
};
export const Dominica: TimeZone = {
zone_name: 'America/Dominica',
gmt_offset: [-14400, -14736]
};
export const Douala: TimeZone = {
zone_name: 'Africa/Douala',
gmt_offset: [3600, 2328]
};
export const Dubai: TimeZone = {
zone_name: 'Asia/Dubai',
gmt_offset: [14400, 13272]
};
export const Dublin: TimeZone = {
zone_name: 'Europe/Dublin',
gmt_offset: [3600, 2079, 0, -1521]
};
export const DumontDUrville: TimeZone = {
zone_name: 'Antarctica/DumontDUrville',
gmt_offset: [36000, 0]
};
export const Dushanbe: TimeZone = {
zone_name: 'Asia/Dushanbe',
gmt_offset: [25200, 21600, 18000, 16512]
};
export const Easter: TimeZone = {
zone_name: 'Pacific/Easter',
gmt_offset: [-18000, -21600, -25200, -26248]
};
export const Edmonton: TimeZone = {
zone_name: 'America/Edmonton',
gmt_offset: [-21600, -25200, -27232]
};
export const Efate: TimeZone = {
zone_name: 'Pacific/Efate',
gmt_offset: [43200, 40396, 39600]
};
export const Eirunepe: TimeZone = {
zone_name: 'America/Eirunepe',
gmt_offset: [-14400, -16768, -18000]
};
export const El_Aaiun: TimeZone = {
zone_name: 'Africa/El_Aaiun',
gmt_offset: [3600, 0, -3168, -3600]
};
export const El_Salvador: TimeZone = {
zone_name: 'America/El_Salvador',
gmt_offset: [-18000, -21408, -21600]
};
export const Eucla: TimeZone = {
zone_name: 'Australia/Eucla',
gmt_offset: [35100, 31500, 30928]
};
export const Fakaofo: TimeZone = {
zone_name: 'Pacific/Fakaofo',
gmt_offset: [46800, -39600, -41096]
};
export const Famagusta: TimeZone = {
zone_name: 'Asia/Famagusta',
gmt_offset: [10800, 8148, 7200]
};
export const Faroe: TimeZone = {
zone_name: 'Atlantic/Faroe',
gmt_offset: [3600, 0, -1624]
};
export const Fiji: TimeZone = {
zone_name: 'Pacific/Fiji',
gmt_offset: [46800, 43200, 42944]
};
export const Fort_Nelson: TimeZone = {
zone_name: 'America/Fort_Nelson',
gmt_offset: [-25200, -28800, -29447]
};
export const Fortaleza: TimeZone = {
zone_name: 'America/Fortaleza',
gmt_offset: [-7200, -9240, -10800]
};
export const Freetown: TimeZone = {
zone_name: 'Africa/Freetown',
gmt_offset: [0, -2400, -3180, -3600]
};
export const Funafuti: TimeZone = {
zone_name: 'Pacific/Funafuti',
gmt_offset: [43200, 43012]
};
export const Gaborone: TimeZone = {
zone_name: 'Africa/Gaborone',
gmt_offset: [10800, 7200, 6220, 5400]
};
export const Galapagos: TimeZone = {
zone_name: 'Pacific/Galapagos',
gmt_offset: [-18000, -21504, -21600]
};
export const Gambier: TimeZone = {
zone_name: 'Pacific/Gambier',
gmt_offset: [-32388, -32400]
};
export const Gaza: TimeZone = {
zone_name: 'Asia/Gaza',
gmt_offset: [10800, 8272, 7200]
};
export const Gibraltar: TimeZone = {
zone_name: 'Europe/Gibraltar',
gmt_offset: [7200, 3600, 0, -1284]
};
export const Glace_Bay: TimeZone = {
zone_name: 'America/Glace_Bay',
gmt_offset: [-10800, -14388, -14400]
};
export const Goose_Bay: TimeZone = {
zone_name: 'America/Goose_Bay',
gmt_offset: [-7200, -9000, -9052, -10800, -12600, -12652, -14400, -14500]
};
export const Grand_Turk: TimeZone = {
zone_name: 'America/Grand_Turk',
gmt_offset: [-14400, -17072, -18000, -18430]
};
export const Grenada: TimeZone = {
zone_name: 'America/Grenada',
gmt_offset: [-14400, -14820]
};
export const Guadalcanal: TimeZone = {
zone_name: 'Pacific/Guadalcanal',
gmt_offset: [39600, 38388]
};
export const Guadeloupe: TimeZone = {
zone_name: 'America/Guadeloupe',
gmt_offset: [-14400, -14768]
};
export const Guam: TimeZone = {
zone_name: 'Pacific/Guam',
gmt_offset: [39600, 36000, 34740, 32400, -51660]
};
export const Guatemala: TimeZone = {
zone_name: 'America/Guatemala',
gmt_offset: [-18000, -21600, -21724]
};
export const Guayaquil: TimeZone = {
zone_name: 'America/Guayaquil',
gmt_offset: [-14400, -18000, -18840, -19160]
};
export const Guernsey: TimeZone = {
zone_name: 'Europe/Guernsey',
gmt_offset: [7200, 3600, 0, -609]
};
export const Guyana: TimeZone = {
zone_name: 'America/Guyana',
gmt_offset: [-10800, -13500, -13959, -14400]
};
export const Halifax: TimeZone = {
zone_name: 'America/Halifax',
gmt_offset: [-10800, -14400, -15264]
};
export const Harare: TimeZone = {
zone_name: 'Africa/Harare',
gmt_offset: [7452, 7200]
};
export const Havana: TimeZone = {
zone_name: 'America/Havana',
gmt_offset: [-14400, -18000, -19768, -19776]
};
export const Hebron: TimeZone = {
zone_name: 'Asia/Hebron',
gmt_offset: [10800, 8423, 7200]
};
export const Helsinki: TimeZone = {
zone_name: 'Europe/Helsinki',
gmt_offset: [10800, 7200, 5989]
};
export const Hermosillo: TimeZone = {
zone_name: 'America/Hermosillo',
gmt_offset: [-21600, -25200, -26632]
};
export const Ho_Chi_Minh: TimeZone = {
zone_name: 'Asia/Ho_Chi_Minh',
gmt_offset: [32400, 28800, 25590, 25200]
};
export const Hobart: TimeZone = {
zone_name: 'Australia/Hobart',
gmt_offset: [39600, 36000, 35356]
};
export const Hong_Kong: TimeZone = {
zone_name: 'Asia/Hong_Kong',
gmt_offset: [32400, 30600, 28800, 27402]
};
export const Honolulu: TimeZone = {
zone_name: 'Pacific/Honolulu',
gmt_offset: [-34200, -36000, -37800, -37886]
};
export const Hovd: TimeZone = {
zone_name: 'Asia/Hovd',
gmt_offset: [28800, 25200, 21996, 21600]
};
export const Indianapolis: TimeZone = {
zone_name: 'America/Indiana/Indianapolis',
gmt_offset: [-14400, -18000, -20678, -21600]
};
export const Inuvik: TimeZone = {
zone_name: 'America/Inuvik',
gmt_offset: [0, -21600, -25200, -28800]
};
export const Iqaluit: TimeZone = {
zone_name: 'America/Iqaluit',
gmt_offset: [0, -14400, -18000, -21600]
};
export const Irkutsk: TimeZone = {
zone_name: 'Asia/Irkutsk',
gmt_offset: [32400, 28800, 25200, 25025]
};
export const Isle_of_Man: TimeZone = {
zone_name: 'Europe/Isle_of_Man',
gmt_offset: [7200, 3600, 0, -1075]
};
export const Istanbul: TimeZone = {
zone_name: 'Europe/Istanbul',
gmt_offset: [14400, 10800, 7200, 7016, 6952]
};
export const Jakarta: TimeZone = {
zone_name: 'Asia/Jakarta',
gmt_offset: [32400, 28800, 27000, 26400, 25632, 25200]
};
export const Jamaica: TimeZone = {
zone_name: 'America/Jamaica',
gmt_offset: [-14400, -18000, -18430]
};
export const Jayapura: TimeZone = {
zone_name: 'Asia/Jayapura',
gmt_offset: [34200, 33768, 32400]
};
export const Jersey: TimeZone = {
zone_name: 'Europe/Jersey',
gmt_offset: [7200, 3600, 0, -506]
};
export const Jerusalem: TimeZone = {
zone_name: 'Asia/Jerusalem',
gmt_offset: [14400, 10800, 8454, 8440, 7200]
};
export const Johannesburg: TimeZone = {
zone_name: 'Africa/Johannesburg',
gmt_offset: [10800, 7200, 6720, 5400]
};
export const Juba: TimeZone = {
zone_name: 'Africa/Juba',
gmt_offset: [10800, 7588, 7200]
};
export const Jujuy: TimeZone = {
zone_name: 'America/Argentina/Jujuy',
gmt_offset: [-7200, -10800, -14400, -15408, -15672]
};
export const Juneau: TimeZone = {
zone_name: 'America/Juneau',
gmt_offset: [54139, -25200, -28800, -32261, -32400]
};
export const Kabul: TimeZone = {
zone_name: 'Asia/Kabul',
gmt_offset: [16608, 16200, 14400]
};
export const Kaliningrad: TimeZone = {
zone_name: 'Europe/Kaliningrad',
gmt_offset: [14400, 10800, 7200, 4920, 3600]
};
export const Kamchatka: TimeZone = {
zone_name: 'Asia/Kamchatka',
gmt_offset: [46800, 43200, 39600, 38076]
};
export const Kampala: TimeZone = {
zone_name: 'Africa/Kampala',
gmt_offset: [10800, 9900, 9000, 7780]
};
export const Kanton: TimeZone = {
zone_name: 'Pacific/Kanton',
gmt_offset: [46800, 0, -39600, -43200]
};
export const Karachi: TimeZone = {
zone_name: 'Asia/Karachi',
gmt_offset: [23400, 21600, 19800, 18000, 16092]
};
export const Kathmandu: TimeZone = {
zone_name: 'Asia/Kathmandu',
gmt_offset: [20700, 20476, 19800]
};
export const Kerguelen: TimeZone = {
zone_name: 'Indian/Kerguelen',
gmt_offset: [18000, 0]
};
export const Khandyga: TimeZone = {
zone_name: 'Asia/Khandyga',
gmt_offset: [39600, 36000, 32533, 32400, 28800]
};
export const Khartoum: TimeZone = {
zone_name: 'Africa/Khartoum',
gmt_offset: [10800, 7808, 7200]
};
export const Kigali: TimeZone = {
zone_name: 'Africa/Kigali',
gmt_offset: [7216, 7200]
};
export const Kinshasa: TimeZone = {
zone_name: 'Africa/Kinshasa',
gmt_offset: [3672, 3600]
};
export const Kiritimati: TimeZone = {
zone_name: 'Pacific/Kiritimati',
gmt_offset: [50400, -36000, -37760, -38400]
};
export const Kirov: TimeZone = {
zone_name: 'Europe/Kirov',
gmt_offset: [18000, 14400, 11928, 10800]
};
export const Knox: TimeZone = {
zone_name: 'America/Indiana/Knox',
gmt_offset: [-18000, -20790, -21600]
};
export const Kolkata: TimeZone = {
zone_name: 'Asia/Kolkata',
gmt_offset: [23400, 21208, 21200, 19800, 19270]
};
export const Kosrae: TimeZone = {
zone_name: 'Pacific/Kosrae',
gmt_offset: [43200, 39600, 39116, 36000, 32400, -47284]
};
export const Kralendijk: TimeZone = {
zone_name: 'America/Kralendijk',
gmt_offset: [-10800, -14400, -15865]
};
export const Krasnoyarsk: TimeZone = {
zone_name: 'Asia/Krasnoyarsk',
gmt_offset: [28800, 25200, 22286, 21600]
};
export const Kuala_Lumpur: TimeZone = {
zone_name: 'Asia/Kuala_Lumpur',
gmt_offset: [32400, 28800, 27000, 26400, 25200, 24925, 24406]
};
export const Kuching: TimeZone = {
zone_name: 'Asia/Kuching',
gmt_offset: [32400, 30000, 28800, 27000, 26480]
};
export const Kuwait: TimeZone = {
zone_name: 'Asia/Kuwait',
gmt_offset: [11516, 10800]
};
export const Kwajalein: TimeZone = {
zone_name: 'Pacific/Kwajalein',
gmt_offset: [43200, 40160, 39600, 36000, 32400, -43200]
};
export const Kyiv: TimeZone = {
zone_name: 'Europe/Kyiv',
gmt_offset: [14400, 10800, 7324, 7200, 3600]
};
export const La_Paz: TimeZone = {
zone_name: 'America/La_Paz',
gmt_offset: [-12756, -14400, -16356]
};
export const La_Rioja: TimeZone = {
zone_name: 'America/Argentina/La_Rioja',
gmt_offset: [-7200, -10800, -14400, -15408, -16044]
};
export const Lagos: TimeZone = {
zone_name: 'Africa/Lagos',
gmt_offset: [3600, 1800, 815, 0]
};
export const Libreville: TimeZone = {
zone_name: 'Africa/Libreville',
gmt_offset: [3600, 2268]
};
export const Lima: TimeZone = {
zone_name: 'America/Lima',
gmt_offset: [-14400, -18000, -18492, -18516]
};
export const Lindeman: TimeZone = {
zone_name: 'Australia/Lindeman',
gmt_offset: [39600, 36000, 35756]
};
export const Lisbon: TimeZone = {
zone_name: 'Europe/Lisbon',
gmt_offset: [7200, 3600, 0, -2205]
};
export const Ljubljana: TimeZone = {
zone_name: 'Europe/Ljubljana',
gmt_offset: [7200, 3600, 3484]
};
export const Lome: TimeZone = {
zone_name: 'Africa/Lome',
gmt_offset: [292, 0]
};
export const London: TimeZone = {
zone_name: 'Europe/London',
gmt_offset: [7200, 3600, 0, -75]
};
export const Longyearbyen: TimeZone = {
zone_name: 'Arctic/Longyearbyen',
gmt_offset: [10800, 7200, 3600, 3208]
};
export const Lord_Howe: TimeZone = {
zone_name: 'Australia/Lord_Howe',
gmt_offset: [41400, 39600, 38180, 37800, 36000]
};
export const Los_Angeles: TimeZone = {
zone_name: 'America/Los_Angeles',
gmt_offset: [-25200, -28378, -28800]
};
export const Louisville: TimeZone = {
zone_name: 'America/Kentucky/Louisville',
gmt_offset: [-14400, -18000, -20582, -21600]
};
export const Lower_Princes: TimeZone = {
zone_name: 'America/Lower_Princes',
gmt_offset: [-10800, -14400, -15865]
};
export const Luanda: TimeZone = {
zone_name: 'Africa/Luanda',
gmt_offset: [3600, 3176, 3124]
};
export const Lubumbashi: TimeZone = {
zone_name: 'Africa/Lubumbashi',
gmt_offset: [7200, 6592, 3600]
};
export const Lusaka: TimeZone = {
zone_name: 'Africa/Lusaka',
gmt_offset: [7200, 6788]
};
export const Luxembourg: TimeZone = {
zone_name: 'Europe/Luxembourg',
gmt_offset: [7200, 3600, 1476, 0]
};
export const Macau: TimeZone = {
zone_name: 'Asia/Macau',
gmt_offset: [36000, 32400, 28800, 27250]
};
export const Maceio: TimeZone = {
zone_name: 'America/Maceio',
gmt_offset: [-7200, -8572, -10800]
};
export const Macquarie: TimeZone = {
zone_name: 'Antarctica/Macquarie',
gmt_offset: [39600, 36000, 0]
};
export const Madeira: TimeZone = {
zone_name: 'Atlantic/Madeira',
gmt_offset: [3600, 0, -3600, -4056]
};
export const Madrid: TimeZone = {
zone_name: 'Europe/Madrid',
gmt_offset: [7200, 3600, 0, -884]
};
export const Magadan: TimeZone = {
zone_name: 'Asia/Magadan',
gmt_offset: [43200, 39600, 36192, 36000]
};
export const Mahe: TimeZone = {
zone_name: 'Indian/Mahe',
gmt_offset: [14400, 13308]
};
export const Majuro: TimeZone = {
zone_name: 'Pacific/Majuro',
gmt_offset: [43200, 41088, 39600, 36000, 32400]
};
export const Makassar: TimeZone = {
zone_name: 'Asia/Makassar',
gmt_offset: [32400, 28800, 28656]
};
export const Malabo: TimeZone = {
zone_name: 'Africa/Malabo',
gmt_offset: [3600, 2108, 0]
};
export const Maldives: TimeZone = {
zone_name: 'Indian/Maldives',
gmt_offset: [18000, 17640]
};
export const Malta: TimeZone = {
zone_name: 'Europe/Malta',
gmt_offset: [7200, 3600, 3484]
};
export const Managua: TimeZone = {
zone_name: 'America/Managua',
gmt_offset: [-18000, -20708, -20712, -21600]
};
export const Manaus: TimeZone = {
zone_name: 'America/Manaus',
gmt_offset: [-10800, -14400, -14404]
};
export const Manila: TimeZone = {
zone_name: 'Asia/Manila',
gmt_offset: [32400, 29032, 28800, -57368]
};
export const Maputo: TimeZone = {
zone_name: 'Africa/Maputo',
gmt_offset: [7818, 7200]
};
export const Marengo: TimeZone = {
zone_name: 'America/Indiana/Marengo',
gmt_offset: [-14400, -18000, -20723, -21600]
};
export const Mariehamn: TimeZone = {
zone_name: 'Europe/Mariehamn',
gmt_offset: [10800, 7200, 5989]
};
export const Marigot: TimeZone = {
zone_name: 'America/Marigot',
gmt_offset: [-10800, -14400, -15865]
};
export const Marquesas: TimeZone = {
zone_name: 'Pacific/Marquesas',
gmt_offset: [-33480, -34200]
};
export const Martinique: TimeZone = {
zone_name: 'America/Martinique',
gmt_offset: [-10800, -14400, -14660]
};
export const Maseru: TimeZone = {
zone_name: 'Africa/Maseru',
gmt_offset: [10800, 7200, 6600]
};
export const Matamoros: TimeZone = {
zone_name: 'America/Matamoros',
gmt_offset: [-18000, -21600, -23400]
};
export const Mauritius: TimeZone = {
zone_name: 'Indian/Mauritius',
gmt_offset: [18000, 14400, 13800]
};
export const Mawson: TimeZone = {
zone_name: 'Antarctica/Mawson',
gmt_offset: [21600, 18000, 0]
};
export const Mayotte: TimeZone = {
zone_name: 'Indian/Mayotte',
gmt_offset: [10856, 10800]
};
export const Mazatlan: TimeZone = {
zone_name: 'America/Mazatlan',
gmt_offset: [-21600, -25200, -25540]
};
export const Mbabane: TimeZone = {
zone_name: 'Africa/Mbabane',
gmt_offset: [7464, 7200]
};
export const McMurdo: TimeZone = {
zone_name: 'Antarctica/McMurdo',
gmt_offset: [46800, 43200]
};
export const Melbourne: TimeZone = {
zone_name: 'Australia/Melbourne',
gmt_offset: [39600, 36000, 34792]
};
export const Mendoza: TimeZone = {
zone_name: 'America/Argentina/Mendoza',
gmt_offset: [-7200, -10800, -14400, -15408, -16516]
};
export const Menominee: TimeZone = {
zone_name: 'America/Menominee',
gmt_offset: [-18000, -21027, -21600]
};
export const Merida: TimeZone = {
zone_name: 'America/Merida',
gmt_offset: [-18000, -21508, -21600]
};
export const Metlakatla: TimeZone = {
zone_name: 'America/Metlakatla',
gmt_offset: [54822, -25200, -28800, -31578, -32400]
};
export const Mexico_City: TimeZone = {
zone_name: 'America/Mexico_City',
gmt_offset: [-18000, -21600, -23796, -25200]
};
export const Midway: TimeZone = {
zone_name: 'Pacific/Midway',
gmt_offset: [-36000, -39600, -42568]
};
export const Minsk: TimeZone = {
zone_name: 'Europe/Minsk',
gmt_offset: [14400, 10800, 7200, 6616, 6600, 3600]
};
export const Miquelon: TimeZone = {
zone_name: 'America/Miquelon',
gmt_offset: [-7200, -10800, -13480, -14400]
};
export const Mogadishu: TimeZone = {
zone_name: 'Africa/Mogadishu',
gmt_offset: [10888, 10800, 9000]
};
export const Monaco: TimeZone = {
zone_name: 'Europe/Monaco',
gmt_offset: [7200, 3600, 1772, 561, 0]
};
export const Moncton: TimeZone = {
zone_name: 'America/Moncton',
gmt_offset: [-10800, -14400, -15548, -18000]
};
export const Monrovia: TimeZone = {
zone_name: 'Africa/Monrovia',
gmt_offset: [0, -2588, -2670]
};
export const Monterrey: TimeZone = {
zone_name: 'America/Monterrey',
gmt_offset: [-18000, -21600, -24076, -25200]
};
export const Montevideo: TimeZone = {
zone_name: 'America/Montevideo',
gmt_offset: [-5400, -7200, -9000, -10800, -12600, -13491, -14400]
};
export const Monticello: TimeZone = {
zone_name: 'America/Kentucky/Monticello',
gmt_offset: [-14400, -18000, -20364, -21600]
};
export const Montserrat: TimeZone = {
zone_name: 'America/Montserrat',
gmt_offset: [-14400, -14932]
};
export const Moscow: TimeZone = {
zone_name: 'Europe/Moscow',
gmt_offset: [18000, 16279, 14400, 12679, 10800, 9079, 9017, 7200]
};
export const Muscat: TimeZone = {
zone_name: 'Asia/Muscat',
gmt_offset: [14400, 14064]
};
export const Nairobi: TimeZone = {
zone_name: 'Africa/Nairobi',
gmt_offset: [10800, 9900, 9000, 8836]
};
export const Nassau: TimeZone = {
zone_name: 'America/Nassau',
gmt_offset: [-14400, -18000, -18570]
};
export const Nauru: TimeZone = {
zone_name: 'Pacific/Nauru',
gmt_offset: [43200, 41400, 40060, 32400]
};
export const Ndjamena: TimeZone = {
zone_name: 'Africa/Ndjamena',
gmt_offset: [7200, 3612, 3600]
};
export const New_Salem: TimeZone = {
zone_name: 'America/North_Dakota/New_Salem',
gmt_offset: [-18000, -21600, -24339, -25200]
};
export const New_York: TimeZone = {
zone_name: 'America/New_York',
gmt_offset: [-14400, -17762, -18000]
};
export const Niamey: TimeZone = {
zone_name: 'Africa/Niamey',
gmt_offset: [3600, 508, 0, -3600]
};
export const Nicosia: TimeZone = {
zone_name: 'Asia/Nicosia',
gmt_offset: [10800, 8008, 7200]
};
export const Niue: TimeZone = {
zone_name: 'Pacific/Niue',
gmt_offset: [-39600, -40780, -40800]
};
export const Nome: TimeZone = {
zone_name: 'America/Nome',
gmt_offset: [46702, -28800, -32400, -36000, -39600, -39698]
};
export const Norfolk: TimeZone = {
zone_name: 'Pacific/Norfolk',
gmt_offset: [45000, 43200, 41400, 40320, 40312, 39600]
};
export const Noronha: TimeZone = {
zone_name: 'America/Noronha',
gmt_offset: [-3600, -7200, -7780]
};
export const Nouakchott: TimeZone = {
zone_name: 'Africa/Nouakchott',
gmt_offset: [0, -3600, -3828]
};
export const Noumea: TimeZone = {
zone_name: 'Pacific/Noumea',
gmt_offset: [43200, 39948, 39600]
};
export const Novokuznetsk: TimeZone = {
zone_name: 'Asia/Novokuznetsk',
gmt_offset: [28800, 25200, 21600, 20928]
};
export const Novosibirsk: TimeZone = {
zone_name: 'Asia/Novosibirsk',
gmt_offset: [28800, 25200, 21600, 19900]
};
export const Nuuk: TimeZone = {
zone_name: 'America/Nuuk',
gmt_offset: [-3600, -7200, -10800, -12416]
};
export const Ojinaga: TimeZone = {
zone_name: 'America/Ojinaga',
gmt_offset: [-18000, -21600, -25060, -25200]
};
export const Omsk: TimeZone = {
zone_name: 'Asia/Omsk',
gmt_offset: [25200, 21600, 18000, 17610]
};
export const Oral: TimeZone = {
zone_name: 'Asia/Oral',
gmt_offset: [21600, 18000, 14400, 12324, 10800]
};
export const Oslo: TimeZone = {
zone_name: 'Europe/Oslo',
gmt_offset: [7200, 3600, 2580]
};
export const Ouagadougou: TimeZone = {
zone_name: 'Africa/Ouagadougou',
gmt_offset: [0, -364]
};
export const Pago_Pago: TimeZone = {
zone_name: 'Pacific/Pago_Pago',
gmt_offset: [45432, -39600, -40968]
};
export const Palau: TimeZone = {
zone_name: 'Pacific/Palau',
gmt_offset: [32400, 32276, -54124]
};
export const Palmer: TimeZone = {
zone_name: 'Antarctica/Palmer',
gmt_offset: [0, -7200, -10800, -14400]
};
export const Panama: TimeZone = {
zone_name: 'America/Panama',
gmt_offset: [-18000, -19088, -19176]
};
export const Paramaribo: TimeZone = {
zone_name: 'America/Paramaribo',
gmt_offset: [-10800, -12600, -13236, -13240, -13252]
};
export const Paris: TimeZone = {
zone_name: 'Europe/Paris',
gmt_offset: [7200, 3600, 561, 0]
};
export const Perth: TimeZone = {
zone_name: 'Australia/Perth',
gmt_offset: [32400, 28800, 27804]
};
export const Petersburg: TimeZone = {
zone_name: 'America/Indiana/Petersburg',
gmt_offset: [-14400, -18000, -20947, -21600]
};
export const Phnom_Penh: TimeZone = {
zone_name: 'Asia/Phnom_Penh',
gmt_offset: [32400, 28800, 25590, 25200, 25180]
};
export const Phoenix: TimeZone = {
zone_name: 'America/Phoenix',
gmt_offset: [-21600, -25200, -26898]
};
export const Pitcairn: TimeZone = {
zone_name: 'Pacific/Pitcairn',
gmt_offset: [-28800, -30600, -31220]
};
export const Podgorica: TimeZone = {
zone_name: 'Europe/Podgorica',
gmt_offset: [7200, 4920, 3600]
};
export const Pohnpei: TimeZone = {
zone_name: 'Pacific/Pohnpei',
gmt_offset: [39600, 37972, 36000, 32400, -48428]
};
export const Pontianak: TimeZone = {
zone_name: 'Asia/Pontianak',
gmt_offset: [32400, 28800, 27000, 26240, 25200]
};
export const Port_Moresby: TimeZone = {
zone_name: 'Pacific/Port_Moresby',
gmt_offset: [36000, 35320, 35312]
};
export const Port_of_Spain: TimeZone = {
zone_name: 'America/Port_of_Spain',
gmt_offset: [-14400, -14764]
};
export const Port_au_Prince: TimeZone = {
zone_name: 'America/Port-au-Prince',
gmt_offset: [-14400, -17340, -17360, -18000]
};
export const Porto_Velho: TimeZone = {
zone_name: 'America/Porto_Velho',
gmt_offset: [-10800, -14400, -15336]
};
export const Porto_Novo: TimeZone = {
zone_name: 'Africa/Porto-Novo',
gmt_offset: [3600, 628, 0]
};
export const Prague: TimeZone = {
zone_name: 'Europe/Prague',
gmt_offset: [7200, 3600, 3464, 0]
};
export const Puerto_Rico: TimeZone = {
zone_name: 'America/Puerto_Rico',
gmt_offset: [-10800, -14400, -15865]
};
export const Punta_Arenas: TimeZone = {
zone_name: 'America/Punta_Arenas',
gmt_offset: [-10800, -14400, -16965, -17020, -18000]
};
export const Pyongyang: TimeZone = {
zone_name: 'Asia/Pyongyang',
gmt_offset: [32400, 30600, 30180]
};
export const Qatar: TimeZone = {
zone_name: 'Asia/Qatar',
gmt_offset: [14400, 12368, 10800]
};
export const Qostanay: TimeZone = {
zone_name: 'Asia/Qostanay',
gmt_offset: [21600, 18000, 15268, 14400]
};
export const Qyzylorda: TimeZone = {
zone_name: 'Asia/Qyzylorda',
gmt_offset: [21600, 18000, 15712, 14400]
};
export const Rankin_Inlet: TimeZone = {
zone_name: 'America/Rankin_Inlet',
gmt_offset: [0, -18000, -21600]
};
export const Rarotonga: TimeZone = {
zone_name: 'Pacific/Rarotonga',
gmt_offset: [48056, -34200, -36000, -37800, -38344]
};
export const Recife: TimeZone = {
zone_name: 'America/Recife',
gmt_offset: [-7200, -8376, -10800]
};
export const Regina: TimeZone = {
zone_name: 'America/Regina',
gmt_offset: [-21600, -25116, -25200]
};
export const Resolute: TimeZone = {
zone_name: 'America/Resolute',
gmt_offset: [0, -18000, -21600]
};
export const Reunion: TimeZone = {
zone_name: 'Indian/Reunion',
gmt_offset: [14400, 13312]
};
export const Reykjavik: TimeZone = {
zone_name: 'Atlantic/Reykjavik',
gmt_offset: [0, -3600, -5280]
};
export const Riga: TimeZone = {
zone_name: 'Europe/Riga',
gmt_offset: [14400, 10800, 9394, 7200, 5794, 3600]
};
export const Rio_Branco: TimeZone = {
zone_name: 'America/Rio_Branco',
gmt_offset: [-14400, -16272, -18000]
};
export const Rio_Gallegos: TimeZone = {
zone_name: 'America/Argentina/Rio_Gallegos',
gmt_offset: [-7200, -10800, -14400, -15408, -16612]
};
export const Riyadh: TimeZone = {
zone_name: 'Asia/Riyadh',
gmt_offset: [11212, 10800]
};
export const Rome: TimeZone = {
zone_name: 'Europe/Rome',
gmt_offset: [7200, 3600, 2996]
};
export const Rothera: TimeZone = {
zone_name: 'Antarctica/Rothera',
gmt_offset: [0, -10800]
};
export const Saipan: TimeZone = {
zone_name: 'Pacific/Saipan',
gmt_offset: [39600, 36000, 34980, 32400, -51420]
};
export const Sakhalin: TimeZone = {
zone_name: 'Asia/Sakhalin',
gmt_offset: [43200, 39600, 36000, 34248, 32400]
};
export const Salta: TimeZone = {
zone_name: 'America/Argentina/Salta',
gmt_offset: [-7200, -10800, -14400, -15408, -15700]
};
export const Samara: TimeZone = {
zone_name: 'Europe/Samara',
gmt_offset: [18000, 14400, 12020, 10800]
};
export const Samarkand: TimeZone = {
zone_name: 'Asia/Samarkand',
gmt_offset: [21600, 18000, 16073, 14400]
};
export const San_Juan: TimeZone = {
zone_name: 'America/Argentina/San_Juan',
gmt_offset: [-7200, -10800, -14400, -15408, -16444]
};
export const San_Luis: TimeZone = {
zone_name: 'America/Argentina/San_Luis',
gmt_offset: [-7200, -10800, -14400, -15408, -15924]
};
export const San_Marino: TimeZone = {
zone_name: 'Europe/San_Marino',
gmt_offset: [7200, 3600, 2996]
};
export const Santarem: TimeZone = {
zone_name: 'America/Santarem',
gmt_offset: [-10800, -13128, -14400]
};
export const Santiago: TimeZone = {
zone_name: 'America/Santiago',
gmt_offset: [-10800, -14400, -16965, -18000]
};
export const Santo_Domingo: TimeZone = {
zone_name: 'America/Santo_Domingo',
gmt_offset: [-14400, -16200, -16776, -16800, -18000]
};
export const Sao_Paulo: TimeZone = {
zone_name: 'America/Sao_Paulo',
gmt_offset: [-7200, -10800, -11188]
};
export const Sao_Tome: TimeZone = {
zone_name: 'Africa/Sao_Tome',
gmt_offset: [3600, 1616, 0, -2205]
};
export const Sarajevo: TimeZone = {
zone_name: 'Europe/Sarajevo',
gmt_offset: [7200, 4420, 3600]
};
export const Saratov: TimeZone = {
zone_name: 'Europe/Saratov',
gmt_offset: [18000, 14400, 11058, 10800]
};
export const Scoresbysund: TimeZone = {
zone_name: 'America/Scoresbysund',
gmt_offset: [0, -3600, -5272, -7200]
};
export const Seoul: TimeZone = {
zone_name: 'Asia/Seoul',
gmt_offset: [36000, 34200, 32400, 30600, 30472]
};
export const Shanghai: TimeZone = {
zone_name: 'Asia/Shanghai',
gmt_offset: [32400, 29143, 28800]
};
export const Simferopol: TimeZone = {
zone_name: 'Europe/Simferopol',
gmt_offset: [14400, 10800, 8184, 8160, 7200, 3600]
};
export const Singapore: TimeZone = {
zone_name: 'Asia/Singapore',
gmt_offset: [32400, 28800, 27000, 26400, 25200, 24925]
};
export const Sitka: TimeZone = {
zone_name: 'America/Sitka',
gmt_offset: [53927, -25200, -28800, -32400, -32473]
};
export const Skopje: TimeZone = {
zone_name: 'Europe/Skopje',
gmt_offset: [7200, 5144, 3600]
};
export const Sofia: TimeZone = {
zone_name: 'Europe/Sofia',
gmt_offset: [10800, 7200, 7016, 5596, 3600]
};
export const South_Georgia: TimeZone = {
zone_name: 'Atlantic/South_Georgia',
gmt_offset: [-7200, -8768]
};
export const Srednekolymsk: TimeZone = {
zone_name: 'Asia/Srednekolymsk',
gmt_offset: [43200, 39600, 36892, 36000]
};
export const St_Barthelemy: TimeZone = {
zone_name: 'America/St_Barthelemy',
gmt_offset: [-10800, -14400, -15865]
};
export const St_Helena: TimeZone = {
zone_name: 'Atlantic/St_Helena',
gmt_offset: [0, -1368]
};
export const St_Johns: TimeZone = {
zone_name: 'America/St_Johns',
gmt_offset: [-5400, -9000, -9052, -12600, -12652]
};
export const St_Kitts: TimeZone = {
zone_name: 'America/St_Kitts',
gmt_offset: [-14400, -15052]
};
export const St_Lucia: TimeZone = {
zone_name: 'America/St_Lucia',
gmt_offset: [-14400, -14640]
};
export const St_Thomas: TimeZone = {
zone_name: 'America/St_Thomas',
gmt_offset: [-14400, -15584]
};
export const St_Vincent: TimeZone = {
zone_name: 'America/St_Vincent',
gmt_offset: [-14400, -14696]
};
export const Stanley: TimeZone = {
zone_name: 'Atlantic/Stanley',
gmt_offset: [-7200, -10800, -13884, -14400]
};
export const Stockholm: TimeZone = {
zone_name: 'Europe/Stockholm',
gmt_offset: [7200, 4332, 3614, 3600]
};
export const Swift_Current: TimeZone = {
zone_name: 'America/Swift_Current',
gmt_offset: [-21600, -25200, -25880]
};
export const Sydney: TimeZone = {
zone_name: 'Australia/Sydney',
gmt_offset: [39600, 36292, 36000]
};
export const Syowa: TimeZone = {
zone_name: 'Antarctica/Syowa',
gmt_offset: [10800, 0]
};
export const Tahiti: TimeZone = {
zone_name: 'Pacific/Tahiti',
gmt_offset: [-35896, -36000]
};
export const Taipei: TimeZone = {
zone_name: 'Asia/Taipei',
gmt_offset: [32400, 29160, 28800]
};
export const Tallinn: TimeZone = {
zone_name: 'Europe/Tallinn',
gmt_offset: [14400, 10800, 7200, 5940, 3600]
};
export const Tarawa: TimeZone = {
zone_name: 'Pacific/Tarawa',
gmt_offset: [43200, 41524]
};
export const Tashkent: TimeZone = {
zone_name: 'Asia/Tashkent',
gmt_offset: [25200, 21600, 18000, 16631]
};
export const Tbilisi: TimeZone = {
zone_name: 'Asia/Tbilisi',
gmt_offset: [18000, 14400, 10800, 10751]
};
export const Tegucigalpa: TimeZone = {
zone_name: 'America/Tegucigalpa',
gmt_offset: [-18000, -20932, -21600]
};
export const Tehran: TimeZone = {
zone_name: 'Asia/Tehran',
gmt_offset: [18000, 16200, 14400, 12600, 12344]
};
export const Tell_City: TimeZone = {
zone_name: 'America/Indiana/Tell_City',
gmt_offset: [-14400, -18000, -20823, -21600]
};
export const Thimphu: TimeZone = {
zone_name: 'Asia/Thimphu',
gmt_offset: [21600, 21516, 19800]
};
export const Thule: TimeZone = {
zone_name: 'America/Thule',
gmt_offset: [-10800, -14400, -16508]
};
export const Tijuana: TimeZone = {
zone_name: 'America/Tijuana',
gmt_offset: [-25200, -28084, -28800]
};
export const Tirane: TimeZone = {
zone_name: 'Europe/Tirane',
gmt_offset: [7200, 4760, 3600]
};
export const Tokyo: TimeZone = {
zone_name: 'Asia/Tokyo',
gmt_offset: [36000, 33539, 32400]
};
export const Tomsk: TimeZone = {
zone_name: 'Asia/Tomsk',
gmt_offset: [28800, 25200, 21600, 20391]
};
export const Tongatapu: TimeZone = {
zone_name: 'Pacific/Tongatapu',
gmt_offset: [50400, 46800, 44400, 44352]
};
export const Toronto: TimeZone = {
zone_name: 'America/Toronto',
gmt_offset: [-14400, -18000, -19052]
};
export const Tortola: TimeZone = {
zone_name: 'America/Tortola',
gmt_offset: [-14400, -15508]
};
export const Tripoli: TimeZone = {
zone_name: 'Africa/Tripoli',
gmt_offset: [7200, 3600, 3164]
};
export const Troll: TimeZone = {
zone_name: 'Antarctica/Troll',
gmt_offset: [7200, 0]
};
export const Tucuman: TimeZone = {
zone_name: 'America/Argentina/Tucuman',
gmt_offset: [-7200, -10800, -14400, -15408, -15652]
};
export const Tunis: TimeZone = {
zone_name: 'Africa/Tunis',
gmt_offset: [7200, 3600, 2444, 561]
};
export const Ulaanbaatar: TimeZone = {
zone_name: 'Asia/Ulaanbaatar',
gmt_offset: [32400, 28800, 25652, 25200]
};
export const Ulyanovsk: TimeZone = {
zone_name: 'Europe/Ulyanovsk',
gmt_offset: [18000, 14400, 11616, 10800, 7200]
};
export const Urumqi: TimeZone = {
zone_name: 'Asia/Urumqi',
gmt_offset: [21600, 21020]
};
export const Ushuaia: TimeZone = {
zone_name: 'America/Argentina/Ushuaia',
gmt_offset: [-7200, -10800, -14400, -15408, -16392]
};
export const Ust_Nera: TimeZone = {
zone_name: 'Asia/Ust-Nera',
gmt_offset: [43200, 39600, 36000, 34374, 32400, 28800]
};
export const Vaduz: TimeZone = {
zone_name: 'Europe/Vaduz',
gmt_offset: [7200, 3600, 2284]
};
export const Vancouver: TimeZone = {
zone_name: 'America/Vancouver',
gmt_offset: [-25200, -28800, -29548]
};
export const Vatican: TimeZone = {
zone_name: 'Europe/Vatican',
gmt_offset: [7200, 3600, 2996]
};
export const Vevay: TimeZone = {
zone_name: 'America/Indiana/Vevay',
gmt_offset: [-14400, -18000, -20416, -21600]
};
export const Vienna: TimeZone = {
zone_name: 'Europe/Vienna',
gmt_offset: [7200, 3921, 3600]
};
export const Vientiane: TimeZone = {
zone_name: 'Asia/Vientiane',
gmt_offset: [32400, 28800, 25590, 25200, 24624]
};
export const Vilnius: TimeZone = {
zone_name: 'Europe/Vilnius',
gmt_offset: [14400, 10800, 7200, 6076, 5736, 5040, 3600]
};
export const Vincennes: TimeZone = {
zone_name: 'America/Indiana/Vincennes',
gmt_offset: [-14400, -18000, -21007, -21600]
};
export const Vladivostok: TimeZone = {
zone_name: 'Asia/Vladivostok',
gmt_offset: [39600, 36000, 32400, 31651]
};
export const Volgograd: TimeZone = {
zone_name: 'Europe/Volgograd',
gmt_offset: [18000, 14400, 10800, 10660]
};
export const Vostok: TimeZone = {
zone_name: 'Antarctica/Vostok',
gmt_offset: [25200, 18000, 0]
};
export const Wake: TimeZone = {
zone_name: 'Pacific/Wake',
gmt_offset: [43200, 39988]
};
export const Wallis: TimeZone = {
zone_name: 'Pacific/Wallis',
gmt_offset: [44120, 43200]
};
export const Warsaw: TimeZone = {
zone_name: 'Europe/Warsaw',
gmt_offset: [10800, 7200, 5040, 3600]
};
export const Whitehorse: TimeZone = {
zone_name: 'America/Whitehorse',
gmt_offset: [-25200, -28800, -32400, -32412]
};
export const Winamac: TimeZone = {
zone_name: 'America/Indiana/Winamac',
gmt_offset: [-14400, -18000, -20785, -21600]
};
export const Windhoek: TimeZone = {
zone_name: 'Africa/Windhoek',
gmt_offset: [10800, 7200, 5400, 4104, 3600]
};
export const Winnipeg: TimeZone = {
zone_name: 'America/Winnipeg',
gmt_offset: [-18000, -21600, -23316]
};
export const Yakutat: TimeZone = {
zone_name: 'America/Yakutat',
gmt_offset: [52865, -28800, -32400, -33535]
};
export const Yakutsk: TimeZone = {
zone_name: 'Asia/Yakutsk',
gmt_offset: [36000, 32400, 31138, 28800]
};
export const Yangon: TimeZone = {
zone_name: 'Asia/Yangon',
gmt_offset: [32400, 23400, 23087]
};
export const Yekaterinburg: TimeZone = {
zone_name: 'Asia/Yekaterinburg',
gmt_offset: [21600, 18000, 14553, 14400, 13505]
};
export const Yerevan: TimeZone = {
zone_name: 'Asia/Yerevan',
gmt_offset: [18000, 14400, 10800, 10680]
};
export const Zagreb: TimeZone = {
zone_name: 'Europe/Zagreb',
gmt_offset: [7200, 3832, 3600]
};
export const Zurich: TimeZone = {
zone_name: 'Europe/Zurich',
gmt_offset: [7200, 3600, 2048, 1786]
};
================================================
FILE: src/timezones/Africa/Abidjan.ts
================================================
export default {
zone_name: 'Africa/Abidjan',
gmt_offset: [0, -968]
};
================================================
FILE: src/timezones/Africa/Accra.ts
================================================
export default {
zone_name: 'Africa/Accra',
gmt_offset: [1800, 1200, 0, -52]
};
================================================
FILE: src/timezones/Africa/Addis_Ababa.ts
================================================
export default {
zone_name: 'Africa/Addis_Ababa',
gmt_offset: [10800, 9320, 9288]
};
================================================
FILE: src/timezones/Africa/Algiers.ts
================================================
export default {
zone_name: 'Africa/Algiers',
gmt_offset: [7200, 3600, 732, 561, 0]
};
================================================
FILE: src/timezones/Africa/Asmara.ts
================================================
export default {
zone_name: 'Africa/Asmara',
gmt_offset: [10800, 9332, 9320]
};
================================================
FILE: src/timezones/Africa/Bamako.ts
================================================
export default {
zone_name: 'Africa/Bamako',
gmt_offset: [0, -1920, -3600]
};
================================================
FILE: src/timezones/Africa/Bangui.ts
================================================
export default {
zone_name: 'Africa/Bangui',
gmt_offset: [4460, 3600]
};
================================================
FILE: src/timezones/Africa/Banjul.ts
================================================
export default {
zone_name: 'Africa/Banjul',
gmt_offset: [0, -3600, -3996]
};
================================================
FILE: src/timezones/Africa/Bissau.ts
================================================
export default {
zone_name: 'Africa/Bissau',
gmt_offset: [0, -3600, -3740]
};
================================================
FILE: src/timezones/Africa/Blantyre.ts
================================================
export default {
zone_name: 'Africa/Blantyre',
gmt_offset: [8470, 8460, 8400, 7200]
};
================================================
FILE: src/timezones/Africa/Brazzaville.ts
================================================
export default {
zone_name: 'Africa/Brazzaville',
gmt_offset: [3668, 3600]
};
================================================
FILE: src/timezones/Africa/Bujumbura.ts
================================================
export default {
zone_name: 'Africa/Bujumbura',
gmt_offset: [7200, 7048]
};
================================================
FILE: src/timezones/Africa/Cairo.ts
================================================
export default {
zone_name: 'Africa/Cairo',
gmt_offset: [10800, 7509, 7200]
};
================================================
FILE: src/timezones/Africa/Casablanca.ts
================================================
export default {
zone_name: 'Africa/Casablanca',
gmt_offset: [3600, 0, -1820]
};
================================================
FILE: src/timezones/Africa/Ceuta.ts
================================================
export default {
zone_name: 'Africa/Ceuta',
gmt_offset: [7200, 3600, 0, -1276]
};
================================================
FILE: src/timezones/Africa/Conakry.ts
================================================
export default {
zone_name: 'Africa/Conakry',
gmt_offset: [0, -3292, -3600]
};
================================================
FILE: src/timezones/Africa/Dakar.ts
================================================
export default {
zone_name: 'Africa/Dakar',
gmt_offset: [0, -3600, -4184]
};
================================================
FILE: src/timezones/Africa/Dar_es_Salaam.ts
================================================
export default {
zone_name: 'Africa/Dar_es_Salaam',
gmt_offset: [10800, 9900, 9428]
};
================================================
FILE: src/timezones/Africa/Djibouti.ts
================================================
export default {
zone_name: 'Africa/Djibouti',
gmt_offset: [10800, 10356]
};
================================================
FILE: src/timezones/Africa/Douala.ts
================================================
export default {
zone_name: 'Africa/Douala',
gmt_offset: [3600, 2328]
};
================================================
FILE: src/timezones/Africa/El_Aaiun.ts
================================================
export default {
zone_name: 'Africa/El_Aaiun',
gmt_offset: [3600, 0, -3168, -3600]
};
================================================
FILE: src/timezones/Africa/Freetown.ts
================================================
export default {
zone_name: 'Africa/Freetown',
gmt_offset: [0, -2400, -3180, -3600]
};
================================================
FILE: src/timezones/Africa/Gaborone.ts
================================================
export default {
zone_name: 'Africa/Gaborone',
gmt_offset: [10800, 7200, 6220, 5400]
};
================================================
FILE: src/timezones/Africa/Harare.ts
================================================
export default {
zone_name: 'Africa/Harare',
gmt_offset: [7452, 7200]
};
================================================
FILE: src/timezones/Africa/Johannesburg.ts
================================================
export default {
zone_name: 'Africa/Johannesburg',
gmt_offset: [10800, 7200, 6720, 5400]
};
================================================
FILE: src/timezones/Africa/Juba.ts
================================================
export default {
zone_name: 'Africa/Juba',
gmt_offset: [10800, 7588, 7200]
};
================================================
FILE: src/timezones/Africa/Kampala.ts
================================================
export default {
zone_name: 'Africa/Kampala',
gmt_offset: [10800, 9900, 9000, 7780]
};
================================================
FILE: src/timezones/Africa/Khartoum.ts
================================================
export default {
zone_name: 'Africa/Khartoum',
gmt_offset: [10800, 7808, 7200]
};
================================================
FILE: src/timezones/Africa/Kigali.ts
================================================
export default {
zone_name: 'Africa/Kigali',
gmt_offset: [7216, 7200]
};
================================================
FILE: src/timezones/Africa/Kinshasa.ts
================================================
export default {
zone_name: 'Africa/Kinshasa',
gmt_offset: [3672, 3600]
};
================================================
FILE: src/timezones/Africa/Lagos.ts
================================================
export default {
zone_name: 'Africa/Lagos',
gmt_offset: [3600, 1800, 815, 0]
};
================================================
FILE: src/timezones/Africa/Libreville.ts
================================================
export default {
zone_name: 'Africa/Libreville',
gmt_offset: [3600, 2268]
};
================================================
FILE: src/timezones/Africa/Lome.ts
================================================
export default {
zone_name: 'Africa/Lome',
gmt_offset: [292, 0]
};
================================================
FILE: src/timezones/Africa/Luanda.ts
================================================
export default {
zone_name: 'Africa/Luanda',
gmt_offset: [3600, 3176, 3124]
};
================================================
FILE: src/timezones/Africa/Lubumbashi.ts
================================================
export default {
zone_name: 'Africa/Lubumbashi',
gmt_offset: [7200, 6592, 3600]
};
================================================
FILE: src/timezones/Africa/Lusaka.ts
================================================
export default {
zone_name: 'Africa/Lusaka',
gmt_offset: [7200, 6788]
};
================================================
FILE: src/timezones/Africa/Malabo.ts
================================================
export default {
zone_name: 'Africa/Malabo',
gmt_offset: [3600, 2108, 0]
};
================================================
FILE: src/timezones/Africa/Maputo.ts
================================================
export default {
zone_name: 'Africa/Maputo',
gmt_offset: [7818, 7200]
};
================================================
FILE: src/timezones/Africa/Maseru.ts
================================================
export default {
zone_name: 'Africa/Maseru',
gmt_offset: [10800, 7200, 6600]
};
================================================
FILE: src/timezones/Africa/Mbabane.ts
================================================
export default {
zone_name: 'Africa/Mbabane',
gmt_offset: [7464, 7200]
};
================================================
FILE: src/timezones/Africa/Mogadishu.ts
================================================
export default {
zone_name: 'Africa/Mogadishu',
gmt_offset: [10888, 10800, 9000]
};
================================================
FILE: src/timezones/Africa/Monrovia.ts
================================================
export default {
zone_name: 'Africa/Monrovia',
gmt_offset: [0, -2588, -2670]
};
================================================
FILE: src/timezones/Africa/Nairobi.ts
================================================
export default {
zone_name: 'Africa/Nairobi',
gmt_offset: [10800, 9900, 9000, 8836]
};
================================================
FILE: src/timezones/Africa/Ndjamena.ts
================================================
export default {
zone_name: 'Africa/Ndjamena',
gmt_offset: [7200, 3612, 3600]
};
================================================
FILE: src/timezones/Africa/Niamey.ts
================================================
export default {
zone_name: 'Africa/Niamey',
gmt_offset: [3600, 508, 0, -3600]
};
================================================
FILE: src/timezones/Africa/Nouakchott.ts
================================================
export default {
zone_name: 'Africa/Nouakchott',
gmt_offset: [0, -3600, -3828]
};
================================================
FILE: src/timezones/Africa/Ouagadougou.ts
================================================
export default {
zone_name: 'Africa/Ouagadougou',
gmt_offset: [0, -364]
};
================================================
FILE: src/timezones/Africa/Porto-Novo.ts
================================================
export default {
zone_name: 'Africa/Porto-Novo',
gmt_offset: [3600, 628, 0]
};
================================================
FILE: src/timezones/Africa/Sao_Tome.ts
================================================
export default {
zone_name: 'Africa/Sao_Tome',
gmt_offset: [3600, 1616, 0, -2205]
};
================================================
FILE: src/timezones/Africa/Tripoli.ts
================================================
export default {
zone_name: 'Africa/Tripoli',
gmt_offset: [7200, 3600, 3164]
};
================================================
FILE: src/timezones/Africa/Tunis.ts
================================================
export default {
zone_name: 'Africa/Tunis',
gmt_offset: [7200, 3600, 2444, 561]
};
================================================
FILE: src/timezones/Africa/Windhoek.ts
================================================
export default {
zone_name: 'Africa/Windhoek',
gmt_offset: [10800, 7200, 5400, 4104, 3600]
};
================================================
FILE: src/timezones/America/Adak.ts
================================================
export default {
zone_name: 'America/Adak',
gmt_offset: [44002, -32400, -36000, -39600, -42398]
};
================================================
FILE: src/timezones/America/Anchorage.ts
================================================
export default {
zone_name: 'America/Anchorage',
gmt_offset: [50424, -28800, -32400, -35976, -36000]
};
================================================
FILE: src/timezones/America/Anguilla.ts
================================================
export default {
zone_name: 'America/Anguilla',
gmt_offset: [-14400, -15136]
};
================================================
FILE: src/timezones/America/Antigua.ts
================================================
export default {
zone_name: 'America/Antigua',
gmt_offset: [-14400, -14832, -18000]
};
================================================
FILE: src/timezones/America/Araguaina.ts
================================================
export default {
zone_name: 'America/Araguaina',
gmt_offset: [-7200, -10800, -11568]
};
================================================
FILE: src/timezones/America/Argentina/Buenos_Aires.ts
================================================
export default {
zone_name: 'America/Argentina/Buenos_Aires',
gmt_offset: [-7200, -10800, -14028, -14400, -15408]
};
================================================
FILE: src/timezones/America/Argentina/Catamarca.ts
================================================
export default {
zone_name: 'America/Argentina/Catamarca',
gmt_offset: [-7200, -10800, -14400, -15408, -15788]
};
================================================
FILE: src/timezones/America/Argentina/Cordoba.ts
================================================
export default {
zone_name: 'America/Argentina/Cordoba',
gmt_offset: [-7200, -10800, -14400, -15408]
};
================================================
FILE: src/timezones/America/Argentina/Jujuy.ts
================================================
export default {
zone_name: 'America/Argentina/Jujuy',
gmt_offset: [-7200, -10800, -14400, -15408, -15672]
};
================================================
FILE: src/timezones/America/Argentina/La_Rioja.ts
================================================
export default {
zone_name: 'America/Argentina/La_Rioja',
gmt_offset: [-7200, -10800, -14400, -15408, -16044]
};
================================================
FILE: src/timezones/America/Argentina/Mendoza.ts
================================================
export default {
zone_name: 'America/Argentina/Mendoza',
gmt_offset: [-7200, -10800, -14400, -15408, -16516]
};
================================================
FILE: src/timezones/America/Argentina/Rio_Gallegos.ts
================================================
export default {
zone_name: 'America/Argentina/Rio_Gallegos',
gmt_offset: [-7200, -10800, -14400, -15408, -16612]
};
================================================
FILE: src/timezones/America/Argentina/Salta.ts
================================================
export default {
zone_name: 'America/Argentina/Salta',
gmt_offset: [-7200, -10800, -14400, -15408, -15700]
};
================================================
FILE: src/timezones/America/Argentina/San_Juan.ts
================================================
export default {
zone_name: 'America/Argentina/San_Juan',
gmt_offset: [-7200, -10800, -14400, -15408, -16444]
};
================================================
FILE: src/timezones/America/Argentina/San_Luis.ts
================================================
export default {
zone_name: 'America/Argentina/San_Luis',
gmt_offset: [-7200, -10800, -14400, -15408, -15924]
};
================================================
FILE: src/timezones/America/Argentina/Tucuman.ts
================================================
export default {
zone_name: 'America/Argentina/Tucuman',
gmt_offset: [-7200, -10800, -14400, -15408, -15652]
};
================================================
FILE: src/timezones/America/Argentina/Ushuaia.ts
================================================
export default {
zone_name: 'America/Argentina/Ushuaia',
gmt_offset: [-7200, -10800, -14400, -15408, -16392]
};
================================================
FILE: src/timezones/America/Aruba.ts
================================================
export default {
zone_name: 'America/Aruba',
gmt_offset: [-14400, -16200, -16824]
};
================================================
FILE: src/timezones/America/Asuncion.ts
================================================
export default {
zone_name: 'America/Asuncion',
gmt_offset: [-10800, -13840, -14400]
};
================================================
FILE: src/timezones/America/Atikokan.ts
================================================
export default {
zone_name: 'America/Atikokan',
gmt_offset: [-18000, -21600, -21988]
};
================================================
FILE: src/timezones/America/Bahia.ts
================================================
export default {
zone_name: 'America/Bahia',
gmt_offset: [-7200, -9244, -10800]
};
================================================
FILE: src/timezones/America/Bahia_Banderas.ts
================================================
export default {
zone_name: 'America/Bahia_Banderas',
gmt_offset: [-18000, -21600, -25200, -25260]
};
================================================
FILE: src/timezones/America/Barbados.ts
================================================
export default {
zone_name: 'America/Barbados',
gmt_offset: [-10800, -12600, -14309, -14400]
};
================================================
FILE: src/timezones/America/Belem.ts
================================================
export default {
zone_name: 'America/Belem',
gmt_offset: [-7200, -10800, -11636]
};
================================================
FILE: src/timezones/America/Belize.ts
================================================
export default {
zone_name: 'America/Belize',
gmt_offset: [-18000, -19800, -21168, -21600]
};
================================================
FILE: src/timezones/America/Blanc-Sablon.ts
================================================
export default {
zone_name: 'America/Blanc-Sablon',
gmt_offset: [-10800, -13708, -14400]
};
================================================
FILE: src/timezones/America/Boa_Vista.ts
================================================
export default {
zone_name: 'America/Boa_Vista',
gmt_offset: [-10800, -14400, -14560]
};
================================================
FILE: src/timezones/America/Bogota.ts
================================================
export default {
zone_name: 'America/Bogota',
gmt_offset: [-14400, -17776, -18000]
};
================================================
FILE: src/timezones/America/Boise.ts
================================================
export default {
zone_name: 'America/Boise',
gmt_offset: [-21600, -25200, -27889, -28800]
};
================================================
FILE: src/timezones/America/Cambridge_Bay.ts
================================================
export default {
zone_name: 'America/Cambridge_Bay',
gmt_offset: [0, -18000, -21600, -25200]
};
================================================
FILE: src/timezones/America/Campo_Grande.ts
================================================
export default {
zone_name: 'America/Campo_Grande',
gmt_offset: [-10800, -13108, -14400]
};
================================================
FILE: src/timezones/America/Cancun.ts
================================================
export default {
zone_name: 'America/Cancun',
gmt_offset: [-14400, -18000, -20824, -21600]
};
================================================
FILE: src/timezones/America/Caracas.ts
================================================
export default {
zone_name: 'America/Caracas',
gmt_offset: [-14400, -16060, -16064, -16200]
};
================================================
FILE: src/timezones/America/Cayenne.ts
================================================
export default {
zone_name: 'America/Cayenne',
gmt_offset: [-10800, -12560, -14400]
};
================================================
FILE: src/timezones/America/Cayman.ts
================================================
export default {
zone_name: 'America/Cayman',
gmt_offset: [-18000, -18430, -19532]
};
================================================
FILE: src/timezones/America/Chicago.ts
================================================
export default {
zone_name: 'America/Chicago',
gmt_offset: [-18000, -21036, -21600]
};
================================================
FILE: src/timezones/America/Chihuahua.ts
================================================
export default {
zone_name: 'America/Chihuahua',
gmt_offset: [-18000, -21600, -25200, -25460]
};
================================================
FILE: src/timezones/America/Ciudad_Juarez.ts
================================================
export default {
zone_name: 'America/Ciudad_Juarez',
gmt_offset: [-18000, -21600, -25200, -25556]
};
================================================
FILE: src/timezones/America/Costa_Rica.ts
================================================
export default {
zone_name: 'America/Costa_Rica',
gmt_offset: [-18000, -20173, -21600]
};
================================================
FILE: src/timezones/America/Coyhaique.ts
================================================
export default {
zone_name: 'America/Coyhaique',
gmt_offset: [-10800, -14400, -16965, -17296, -18000]
};
================================================
FILE: src/timezones/America/Creston.ts
================================================
export default {
zone_name: 'America/Creston',
gmt_offset: [-25200, -27964, -28800]
};
================================================
FILE: src/timezones/America/Cuiaba.ts
================================================
export default {
zone_name: 'America/Cuiaba',
gmt_offset: [-10800, -13460, -14400]
};
================================================
FILE: src/timezones/America/Curacao.ts
================================================
export default {
zone_name: 'America/Curacao',
gmt_offset: [-14400, -16200, -16547]
};
================================================
FILE: src/timezones/America/Danmarkshavn.ts
================================================
export default {
zone_name: 'America/Danmarkshavn',
gmt_offset: [0, -4480, -7200, -10800]
};
================================================
FILE: src/timezones/America/Dawson.ts
================================================
export default {
zone_name: 'America/Dawson',
gmt_offset: [-25200, -28800, -32400, -33460]
};
================================================
FILE: src/timezones/America/Dawson_Creek.ts
================================================
export default {
zone_name: 'America/Dawson_Creek',
gmt_offset: [-25200, -28800, -28856]
};
================================================
FILE: src/timezones/America/Denver.ts
================================================
export default {
zone_name: 'America/Denver',
gmt_offset: [-21600, -25196, -25200]
};
================================================
FILE: src/timezones/America/Detroit.ts
================================================
export default {
zone_name: 'America/Detroit',
gmt_offset: [-14400, -18000, -19931, -21600]
};
================================================
FILE: src/timezones/America/Dominica.ts
================================================
export default {
zone_name: 'America/Dominica',
gmt_offset: [-14400, -14736]
};
================================================
FILE: src/timezones/America/Edmonton.ts
================================================
export default {
zone_name: 'America/Edmonton',
gmt_offset: [-21600, -25200, -27232]
};
================================================
FILE: src/timezones/America/Eirunepe.ts
================================================
export default {
zone_name: 'America/Eirunepe',
gmt_offset: [-14400, -16768, -18000]
};
================================================
FILE: src/timezones/America/El_Salvador.ts
================================================
export default {
zone_name: 'America/El_Salvador',
gmt_offset: [-18000, -21408, -21600]
};
================================================
FILE: src/timezones/America/Fort_Nelson.ts
================================================
export default {
zone_name: 'America/Fort_Nelson',
gmt_offset: [-25200, -28800, -29447]
};
================================================
FILE: src/timezones/America/Fortaleza.ts
================================================
export default {
zone_name: 'America/Fortaleza',
gmt_offset: [-7200, -9240, -10800]
};
================================================
FILE: src/timezones/America/Glace_Bay.ts
================================================
export default {
zone_name: 'America/Glace_Bay',
gmt_offset: [-10800, -14388, -14400]
};
================================================
FILE: src/timezones/America/Goose_Bay.ts
================================================
export default {
zone_name: 'America/Goose_Bay',
gmt_offset: [-7200, -9000, -9052, -10800, -12600, -12652, -14400, -14500]
};
================================================
FILE: src/timezones/America/Grand_Turk.ts
================================================
export default {
zone_name: 'America/Grand_Turk',
gmt_offset: [-14400, -17072, -18000, -18430]
};
================================================
FILE: src/timezones/America/Grenada.ts
================================================
export default {
zone_name: 'America/Grenada',
gmt_offset: [-14400, -14820]
};
================================================
FILE: src/timezones/America/Guadeloupe.ts
================================================
export default {
zone_name: 'America/Guadeloupe',
gmt_offset: [-14400, -14768]
};
================================================
FILE: src/timezones/America/Guatemala.ts
================================================
export default {
zone_name: 'America/Guatemala',
gmt_offset: [-18000, -21600, -21724]
};
================================================
FILE: src/timezones/America/Guayaquil.ts
================================================
export default {
zone_name: 'America/Guayaquil',
gmt_offset: [-14400, -18000, -18840, -19160]
};
================================================
FILE: src/timezones/America/Guyana.ts
================================================
export default {
zone_name: 'America/Guyana',
gmt_offset: [-10800, -13500, -13959, -14400]
};
================================================
FILE: src/timezones/America/Halifax.ts
================================================
export default {
zone_name: 'America/Halifax',
gmt_offset: [-10800, -14400, -15264]
};
================================================
FILE: src/timezones/America/Havana.ts
================================================
export default {
zone_name: 'America/Havana',
gmt_offset: [-14400, -18000, -19768, -19776]
};
================================================
FILE: src/timezones/America/Hermosillo.ts
================================================
export default {
zone_name: 'America/Hermosillo',
gmt_offset: [-21600, -25200, -26632]
};
================================================
FILE: src/timezones/America/Indiana/Indianapolis.ts
================================================
export default {
zone_name: 'America/Indiana/Indianapolis',
gmt_offset: [-14400, -18000, -20678, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Knox.ts
================================================
export default {
zone_name: 'America/Indiana/Knox',
gmt_offset: [-18000, -20790, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Marengo.ts
================================================
export default {
zone_name: 'America/Indiana/Marengo',
gmt_offset: [-14400, -18000, -20723, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Petersburg.ts
================================================
export default {
zone_name: 'America/Indiana/Petersburg',
gmt_offset: [-14400, -18000, -20947, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Tell_City.ts
================================================
export default {
zone_name: 'America/Indiana/Tell_City',
gmt_offset: [-14400, -18000, -20823, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Vevay.ts
================================================
export default {
zone_name: 'America/Indiana/Vevay',
gmt_offset: [-14400, -18000, -20416, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Vincennes.ts
================================================
export default {
zone_name: 'America/Indiana/Vincennes',
gmt_offset: [-14400, -18000, -21007, -21600]
};
================================================
FILE: src/timezones/America/Indiana/Winamac.ts
================================================
export default {
zone_name: 'America/Indiana/Winamac',
gmt_offset: [-14400, -18000, -20785, -21600]
};
================================================
FILE: src/timezones/America/Inuvik.ts
================================================
export default {
zone_name: 'America/Inuvik',
gmt_offset: [0, -21600, -25200, -28800]
};
================================================
FILE: src/timezones/America/Iqaluit.ts
================================================
export default {
zone_name: 'America/Iqaluit',
gmt_offset: [0, -14400, -18000, -21600]
};
================================================
FILE: src/timezones/America/Jamaica.ts
================================================
export default {
zone_name: 'America/Jamaica',
gmt_offset: [-14400, -18000, -18430]
};
================================================
FILE: src/timezones/America/Juneau.ts
================================================
export default {
zone_name: 'America/Juneau',
gmt_offset: [54139, -25200, -28800, -32261, -32400]
};
================================================
FILE: src/timezones/America/Kentucky/Louisville.ts
================================================
export default {
zone_name: 'America/Kentucky/Louisville',
gmt_offset: [-14400, -18000, -20582, -21600]
};
================================================
FILE: src/timezones/America/Kentucky/Monticello.ts
================================================
export default {
zone_name: 'America/Kentucky/Monticello',
gmt_offset: [-14400, -18000, -20364, -21600]
};
================================================
FILE: src/timezones/America/Kralendijk.ts
================================================
export default {
zone_name: 'America/Kralendijk',
gmt_offset: [-10800, -14400, -15865]
};
================================================
FILE: src/timezones/America/La_Paz.ts
================================================
export default {
zone_name: 'America/La_Paz',
gmt_offset: [-12756, -14400, -16356]
};
================================================
FILE: src/timezones/America/Lima.ts
================================================
export default {
zone_name: 'America/Lima',
gmt_offset: [-14400, -18000, -18492, -18516]
};
================================================
FILE: src/timezones/America/Los_Angeles.ts
================================================
export default {
zone_name: 'America/Los_Angeles',
gmt_offset: [-25200, -28378, -28800]
};
================================================
FILE: src/timezones/America/Lower_Princes.ts
================================================
export default {
zone_name: 'America/Lower_Princes',
gmt_offset: [-10800, -14400, -15865]
};
================================================
FILE: src/timezones/America/Maceio.ts
================================================
export default {
zone_name: 'America/Maceio',
gmt_offset: [-7200, -8572, -10800]
};
================================================
FILE: src/timezones/America/Managua.ts
================================================
export default {
zone_name: 'America/Managua',
gmt_offset: [-18000, -20708, -20712, -21600]
};
================================================
FILE: src/timezones/America/Manaus.ts
================================================
export default {
zone_name: 'America/Manaus',
gmt_offset: [-10800, -14400, -14404]
};
================================================
FILE: src/timezones/America/Marigot.ts
================================================
export default {
zone_name: 'America/Marigot',
gmt_offset: [-10800, -14400, -15865]
};
================================================
FILE: src/timezones/America/Martinique.ts
================================================
export default {
zone_name: 'America/Martinique',
gmt_offset: [-10800, -14400, -14660]
};
================================================
FILE: src/timezones/America/Matamoros.ts
================================================
export default {
zone_name: 'America/Matamoros',
gmt_offset: [-18000, -21600, -23400]
};
================================================
FILE: src/timezones/America/Mazatlan.ts
================================================
export default {
zone_name: 'America/Mazatlan',
gmt_offset: [-21600, -25200, -25540]
};
================================================
FILE: src/timezones/America/Menominee.ts
================================================
export default {
zone_name: 'America/Menominee',
gmt_offset: [-18000, -21027, -21600]
};
================================================
FILE: src/timezones/America/Merida.ts
================================================
export default {
zone_name: 'America/Merida',
gmt_offset: [-18000, -21508, -21600]
};
================================================
FILE: src/timezones/America/Metlakatla.ts
================================================
export default {
zone_name: 'America/Metlakatla',
gmt_offset: [54822, -25200, -28800, -31578, -32400]
};
================================================
FILE: src/timezones/America/Mexico_City.ts
================================================
export default {
zone_name: 'America/Mexico_City',
gmt_offset: [-18000, -21600, -23796, -25200]
};
================================================
FILE: src/timezones/America/Miquelon.ts
================================================
export default {
zone_name: 'America/Miquelon',
gmt_offset: [-7200, -10800, -13480, -14400]
};
================================================
FILE: src/timezones/America/Moncton.ts
================================================
export default {
zone_name: 'America/Moncton',
gmt_offset: [-10800, -14400, -15548, -18000]
};
================================================
FILE: src/timezones/America/Monterrey.ts
================================================
export default {
zone_name: 'America/Monterrey',
gmt_offset: [-18000, -21600, -24076, -25200]
};
================================================
FILE: src/timezones/America/Montevideo.ts
================================================
export default {
zone_name: 'America/Montevideo',
gmt_offset: [-5400, -7200, -9000, -10800, -12600, -13491, -14400]
};
================================================
FILE: src/timezones/America/Montserrat.ts
================================================
export default {
zone_name: 'America/Montserrat',
gmt_offset: [-14400, -14932]
};
================================================
FILE: src/timezones/America/Nassau.ts
================================================
export default {
zone_name: 'America/Nassau',
gmt_offset: [-14400, -18000, -18570]
};
================================================
FILE: src/timezones/America/New_York.ts
================================================
export default {
zone_name: 'America/New_York',
gmt_offset: [-14400, -17762, -18000]
};
================================================
FILE: src/timezones/America/Nome.ts
================================================
export default {
zone_name: 'America/Nome',
gmt_offset: [46702, -28800, -32400, -36000, -39600, -39698]
};
================================================
FILE: src/timezones/America/Noronha.ts
================================================
export default {
zone_name: 'America/Noronha',
gmt_offset: [-3600, -7200, -7780]
};
================================================
FILE: src/timezones/America/North_Dakota/Beulah.ts
================================================
export default {
zone_name: 'America/North_Dakota/Beulah',
gmt_offset: [-18000, -21600, -24427, -25200]
};
================================================
FILE: src/timezones/America/North_Dakota/Center.ts
================================================
export default {
zone_name: 'America/North_Dakota/Center',
gmt_offset: [-18000, -21600, -24312, -25200]
};
================================================
FILE: src/timezones/America/North_Dakota/New_Salem.ts
================================================
export default {
zone_name: 'America/North_Dakota/New_Salem',
gmt_offset: [-18000, -21600, -24339, -25200]
};
================================================
FILE: src/timezones/America/Nuuk.ts
================================================
export default {
zone_name: 'America/Nuuk',
gmt_offset: [-3600, -7200, -10800, -12416]
};
================================================
FILE: src/timezones/America/Ojinaga.ts
================================================
export default {
zone_name: 'America/Ojinaga',
gmt_offset: [-18000, -21600, -25060, -25200]
};
================================================
FILE: src/timezones/America/Panama.ts
================================================
export default {
zone_name: 'America/Panama',
gmt_offset: [-18000, -19088, -19176]
};
================================================
FILE: src/timezones/America/Paramaribo.ts
================================================
export default {
zone_name: 'America/Paramaribo',
gmt_offset: [-10800, -12600, -13236, -13240, -13252]
};
================================================
FILE: src/timezones/America/Phoenix.ts
================================================
export default {
zone_name: 'America/Phoenix',
gmt_offset: [-21600, -25200, -26898]
};
================================================
FILE: src/timezones/America/Port-au-Prince.ts
================================================
export default {
zone_name: 'America/Port-au-Prince',
gmt_offset: [-14400, -17340, -17360, -18000]
};
================================================
FILE: src/timezones/America/Port_of_Spain.ts
================================================
export default {
zone_name: 'America/Port_of_Spain',
gmt_offset: [-14400, -14764]
};
================================================
FILE: src/timezones/America/Porto_Velho.ts
================================================
export default {
zone_name: 'America/Porto_Velho',
gmt_offset: [-10800, -14400, -15336]
};
================================================
FILE: src/timezones/America/Puerto_Rico.ts
================================================
export default {
zone_name: 'America/Puerto_Rico',
gmt_offset: [-10800, -14400, -15865]
};
================================================
FILE: src/timezones/America/Punta_Arenas.ts
================================================
export default {
zone_name: 'America/Punta_Arenas',
gmt_offset: [-10800, -14400, -16965, -17020, -18000]
};
================================================
FILE: src/timezones/America/Rankin_Inlet.ts
================================================
export default {
zone_name: 'America/Rankin_Inlet',
gmt_offset: [0, -18000, -21600]
};
================================================
FILE: src/timezones/America/Recife.ts
================================================
export default {
zone_name: 'America/Recife',
gmt_offset: [-7200, -8376, -10800]
};
================================================
FILE: src/timezones/America/Regina.ts
================================================
export default {
zone_name: 'America/Regina',
gmt_offset: [-21600, -25116, -25200]
};
================================================
FILE: src/timezones/America/Resolute.ts
================================================
export default {
zone_name: 'America/Resolute',
gmt_offset: [0, -18000, -21600]
};
================================================
FILE: src/timezones/America/Rio_Branco.ts
================================================
export default {
zone_name: 'America/Rio_Branco',
gmt_offset: [-14400, -16272, -18000]
};
================================================
FILE: src/timezones/America/Santarem.ts
================================================
export default {
zone_name: 'America/Santarem',
gmt_offset: [-10800, -13128, -14400]
};
================================================
FILE: src/timezones/America/Santiago.ts
================================================
export default {
zone_name: 'America/Santiago',
gmt_offset: [-10800, -14400, -16965, -18000]
};
================================================
FILE: src/timezones/America/Santo_Domingo.ts
================================================
export default {
zone_name: 'America/Santo_Domingo',
gmt_offset: [-14400, -16200, -16776, -16800, -18000]
};
================================================
FILE: src/timezones/America/Sao_Paulo.ts
================================================
export default {
zone_name: 'America/Sao_Paulo',
gmt_offset: [-7200, -10800, -11188]
};
================================================
FILE: src/timezones/America/Scoresbysund.ts
================================================
export default {
zone_name: 'America/Scoresbysund',
gmt_offset: [0, -3600, -5272, -7200]
};
================================================
FILE: src/timezones/America/Sitka.ts
================================================
export default {
zone_name: 'America/Sitka',
gmt_offset: [53927, -25200, -28800, -32400, -32473]
};
================================================
FILE: src/timezones/America/St_Barthelemy.ts
================================================
export default {
zone_name: 'America/St_Barthelemy',
gmt_offset: [-10800, -14400, -15865]
};
================================================
FILE: src/timezones/America/St_Johns.ts
================================================
export default {
zone_name: 'America/St_Johns',
gmt_offset: [-5400, -9000, -9052, -12600, -12652]
};
================================================
FILE: src/timezones/America/St_Kitts.ts
================================================
export default {
zone_name: 'America/St_Kitts',
gmt_offset: [-14400, -15052]
};
================================================
FILE: src/timezones/America/St_Lucia.ts
================================================
export default {
zone_name: 'America/St_Lucia',
gmt_offset: [-14400, -14640]
};
================================================
FILE: src/timezones/America/St_Thomas.ts
================================================
export default {
zone_name: 'America/St_Thomas',
gmt_offset: [-14400, -15584]
};
================================================
FILE: src/timezones/America/St_Vincent.ts
================================================
export default {
zone_name: 'America/St_Vincent',
gmt_offset: [-14400, -14696]
};
================================================
FILE: src/timezones/America/Swift_Current.ts
================================================
export default {
zone_name: 'America/Swift_Current',
gmt_offset: [-21600, -25200, -25880]
};
================================================
FILE: src/timezones/America/Tegucigalpa.ts
================================================
export default {
zone_name: 'America/Tegucigalpa',
gmt_offset: [-18000, -20932, -21600]
};
================================================
FILE: src/timezones/America/Thule.ts
================================================
export default {
zone_name: 'America/Thule',
gmt_offset: [-10800, -14400, -16508]
};
================================================
FILE: src/timezones/America/Tijuana.ts
================================================
export default {
zone_name: 'America/Tijuana',
gmt_offset: [-25200, -28084, -28800]
};
================================================
FILE: src/timezones/America/Toronto.ts
================================================
export default {
zone_name: 'America/Toronto',
gmt_offset: [-14400, -18000, -19052]
};
================================================
FILE: src/timezones/America/Tortola.ts
================================================
export default {
zone_name: 'America/Tortola',
gmt_offset: [-14400, -15508]
};
================================================
FILE: src/timezones/America/Vancouver.ts
================================================
export default {
zone_name: 'America/Vancouver',
gmt_offset: [-25200, -28800, -29548]
};
================================================
FILE: src/timezones/America/Whitehorse.ts
================================================
export default {
zone_name: 'America/Whitehorse',
gmt_offset: [-25200, -28800, -32400, -32412]
};
================================================
FILE: src/timezones/America/Winnipeg.ts
================================================
export default {
zone_name: 'America/Winnipeg',
gmt_offset: [-18000, -21600, -23316]
};
================================================
FILE: src/timezones/America/Yakutat.ts
================================================
export default {
zone_name: 'America/Yakutat',
gmt_offset: [52865, -28800, -32400, -33535]
};
================================================
FILE: src/timezones/Antarctica/Casey.ts
================================================
export default {
zone_name: 'Antarctica/Casey',
gmt_offset: [39600, 28800, 0]
};
================================================
FILE: src/timezones/Antarctica/Davis.ts
================================================
export default {
zone_name: 'Antarctica/Davis',
gmt_offset: [25200, 18000, 0]
};
================================================
FILE: src/timezones/Antarctica/DumontDUrville.ts
================================================
export default {
zone_name: 'Antarctica/DumontDUrville',
gmt_offset: [36000, 0]
};
================================================
FILE: src/timezones/Antarctica/Macquarie.ts
================================================
export default {
zone_name: 'Antarctica/Macquarie',
gmt_offset: [39600, 36000, 0]
};
================================================
FILE: src/timezones/Antarctica/Mawson.ts
================================================
export default {
zone_name: 'Antarctica/Mawson',
gmt_offset: [21600, 18000, 0]
};
================================================
FILE: src/timezones/Antarctica/McMurdo.ts
================================================
export default {
zone_name: 'Antarctica/McMurdo',
gmt_offset: [46800, 43200]
};
================================================
FILE: src/timezones/Antarctica/Palmer.ts
================================================
export default {
zone_name: 'Antarctica/Palmer',
gmt_offset: [0, -7200, -10800, -14400]
};
================================================
FILE: src/timezones/Antarctica/Rothera.ts
================================================
export default {
zone_name: 'Antarctica/Rothera',
gmt_offset: [0, -10800]
};
================================================
FILE: src/timezones/Antarctica/Syowa.ts
================================================
export default {
zone_name: 'Antarctica/Syowa',
gmt_offset: [10800, 0]
};
================================================
FILE: src/timezones/Antarctica/Troll.ts
================================================
export default {
zone_name: 'Antarctica/Troll',
gmt_offset: [7200, 0]
};
================================================
FILE: src/timezones/Antarctica/Vostok.ts
================================================
export default {
zone_name: 'Antarctica/Vostok',
gmt_offset: [25200, 18000, 0]
};
================================================
FILE: src/timezones/Arctic/Longyearbyen.ts
================================================
export default {
zone_name: 'Arctic/Longyearbyen',
gmt_offset: [10800, 7200, 3600, 3208]
};
================================================
FILE: src/timezones/Asia/Aden.ts
================================================
export default {
zone_name: 'Asia/Aden',
gmt_offset: [10800, 10794]
};
================================================
FILE: src/timezones/Asia/Almaty.ts
================================================
export default {
zone_name: 'Asia/Almaty',
gmt_offset: [25200, 21600, 18468, 18000]
};
================================================
FILE: src/timezones/Asia/Amman.ts
================================================
export default {
zone_name: 'Asia/Amman',
gmt_offset: [10800, 8624, 7200]
};
================================================
FILE: src/timezones/Asia/Anadyr.ts
================================================
export default {
zone_name: 'Asia/Anadyr',
gmt_offset: [50400, 46800, 43200, 42596, 39600]
};
================================================
FILE: src/timezones/Asia/Aqtau.ts
================================================
export default {
zone_name: 'Asia/Aqtau',
gmt_offset: [21600, 18000, 14400, 12064]
};
================================================
FILE: src/timezones/Asia/Aqtobe.ts
================================================
export default {
zone_name: 'Asia/Aqtobe',
gmt_offset: [21600, 18000, 14400, 13720]
};
================================================
FILE: src/timezones/Asia/Ashgabat.ts
================================================
export default {
zone_name: 'Asia/Ashgabat',
gmt_offset: [21600, 18000, 14400, 14012]
};
================================================
FILE: src/timezones/Asia/Atyrau.ts
================================================
export default {
zone_name: 'Asia/Atyrau',
gmt_offset: [21600, 18000, 14400, 12464, 10800]
};
================================================
FILE: src/timezones/Asia/Baghdad.ts
================================================
export default {
zone_name: 'Asia/Baghdad',
gmt_offset: [14400, 10800, 10660, 10656]
};
================================================
FILE: src/timezones/Asia/Bahrain.ts
================================================
export default {
zone_name: 'Asia/Bahrain',
gmt_offset: [14400, 12600, 12140, 10800]
};
================================================
FILE: src/timezones/Asia/Baku.ts
================================================
export default {
zone_name: 'Asia/Baku',
gmt_offset: [18000, 14400, 11964, 10800]
};
================================================
FILE: src/timezones/Asia/Bangkok.ts
================================================
export default {
zone_name: 'Asia/Bangkok',
gmt_offset: [25200, 24124]
};
================================================
FILE: src/timezones/Asia/Barnaul.ts
================================================
export default {
zone_name: 'Asia/Barnaul',
gmt_offset: [28800, 25200, 21600, 20100]
};
================================================
FILE: src/timezones/Asia/Beirut.ts
================================================
export default {
zone_name: 'Asia/Beirut',
gmt_offset: [10800, 8520, 7200]
};
================================================
FILE: src/timezones/Asia/Bishkek.ts
================================================
export default {
zone_name: 'Asia/Bishkek',
gmt_offset: [25200, 21600, 18000, 17904]
};
================================================
FILE: src/timezones/Asia/Brunei.ts
================================================
export default {
zone_name: 'Asia/Brunei',
gmt_offset: [28800, 27580, 27000]
};
================================================
FILE: src/timezones/Asia/Chita.ts
================================================
export default {
zone_name: 'Asia/Chita',
gmt_offset: [36000, 32400, 28800, 27232]
};
================================================
FILE: src/timezones/Asia/Colombo.ts
================================================
export default {
zone_name: 'Asia/Colombo',
gmt_offset: [23400, 21600, 19800, 19172, 19164]
};
================================================
FILE: src/timezones/Asia/Damascus.ts
================================================
export default {
zone_name: 'Asia/Damascus',
gmt_offset: [10800, 8712, 7200]
};
================================================
FILE: src/timezones/Asia/Dhaka.ts
================================================
export default {
zone_name: 'Asia/Dhaka',
gmt_offset: [25200, 23400, 21700, 21600, 21200, 19800]
};
================================================
FILE: src/timezones/Asia/Dili.ts
================================================
export default {
zone_name: 'Asia/Dili',
gmt_offset: [32400, 30140, 28800]
};
================================================
FILE: src/timezones/Asia/Dubai.ts
================================================
export default {
zone_name: 'Asia/Dubai',
gmt_offset: [14400, 13272]
};
================================================
FILE: src/timezones/Asia/Dushanbe.ts
================================================
export default {
zone_name: 'Asia/Dushanbe',
gmt_offset: [25200, 21600, 18000, 16512]
};
================================================
FILE: src/timezones/Asia/Famagusta.ts
================================================
export default {
zone_name: 'Asia/Famagusta',
gmt_offset: [10800, 8148, 7200]
};
================================================
FILE: src/timezones/Asia/Gaza.ts
================================================
export default {
zone_name: 'Asia/Gaza',
gmt_offset: [10800, 8272, 7200]
};
================================================
FILE: src/timezones/Asia/Hebron.ts
================================================
export default {
zone_name: 'Asia/Hebron',
gmt_offset: [10800, 8423, 7200]
};
================================================
FILE: src/timezones/Asia/Ho_Chi_Minh.ts
================================================
export default {
zone_name: 'Asia/Ho_Chi_Minh',
gmt_offset: [32400, 28800, 25590, 25200]
};
================================================
FILE: src/timezones/Asia/Hong_Kong.ts
================================================
export default {
zone_name: 'Asia/Hong_Kong',
gmt_offset: [32400, 30600, 28800, 27402]
};
================================================
FILE: src/timezones/Asia/Hovd.ts
================================================
export default {
zone_name: 'Asia/Hovd',
gmt_offset: [28800, 25200, 21996, 21600]
};
================================================
FILE: src/timezones/Asia/Irkutsk.ts
================================================
export default {
zone_name: 'Asia/Irkutsk',
gmt_offset: [32400, 28800, 25200, 25025]
};
================================================
FILE: src/timezones/Asia/Jakarta.ts
================================================
export default {
zone_name: 'Asia/Jakarta',
gmt_offset: [32400, 28800, 27000, 26400, 25632, 25200]
};
================================================
FILE: src/timezones/Asia/Jayapura.ts
================================================
export default {
zone_name: 'Asia/Jayapura',
gmt_offset: [34200, 33768, 32400]
};
================================================
FILE: src/timezones/Asia/Jerusalem.ts
================================================
export default {
zone_name: 'Asia/Jerusalem',
gmt_offset: [14400, 10800, 8454, 8440, 7200]
};
================================================
FILE: src/timezones/Asia/Kabul.ts
================================================
export default {
zone_name: 'Asia/Kabul',
gmt_offset: [16608, 16200, 14400]
};
================================================
FILE: src/timezones/Asia/Kamchatka.ts
================================================
export default {
zone_name: 'Asia/Kamchatka',
gmt_offset: [46800, 43200, 39600, 38076]
};
================================================
FILE: src/timezones/Asia/Karachi.ts
================================================
export default {
zone_name: 'Asia/Karachi',
gmt_offset: [23400, 21600, 19800, 18000, 16092]
};
================================================
FILE: src/timezones/Asia/Kathmandu.ts
================================================
export default {
zone_name: 'Asia/Kathmandu',
gmt_offset: [20700, 20476, 19800]
};
================================================
FILE: src/timezones/Asia/Khandyga.ts
================================================
export default {
zone_name: 'Asia/Khandyga',
gmt_offset: [39600, 36000, 32533, 32400, 28800]
};
================================================
FILE: src/timezones/Asia/Kolkata.ts
================================================
export default {
zone_name: 'Asia/Kolkata',
gmt_offset: [23400, 21208, 21200, 19800, 19270]
};
================================================
FILE: src/timezones/Asia/Krasnoyarsk.ts
================================================
export default {
zone_name: 'Asia/Krasnoyarsk',
gmt_offset: [28800, 25200, 22286, 21600]
};
================================================
FILE: src/timezones/Asia/Kuala_Lumpur.ts
================================================
export default {
zone_name: 'Asia/Kuala_Lumpur',
gmt_offset: [32400, 28800, 27000, 26400, 25200, 24925, 24406]
};
================================================
FILE: src/timezones/Asia/Kuching.ts
================================================
export default {
zone_name: 'Asia/Kuching',
gmt_offset: [32400, 30000, 28800, 27000, 26480]
};
================================================
FILE: src/timezones/Asia/Kuwait.ts
================================================
export default {
zone_name: 'Asia/Kuwait',
gmt_offset: [11516, 10800]
};
================================================
FILE: src/timezones/Asia/Macau.ts
================================================
export default {
zone_name: 'Asia/Macau',
gmt_offset: [36000, 32400, 28800, 27250]
};
================================================
FILE: src/timezones/Asia/Magadan.ts
================================================
export default {
zone_name: 'Asia/Magadan',
gmt_offset: [43200, 39600, 36192, 36000]
};
================================================
FILE: src/timezones/Asia/Makassar.ts
================================================
export default {
zone_name: 'Asia/Makassar',
gmt_offset: [32400, 28800, 28656]
};
================================================
FILE: src/timezones/Asia/Manila.ts
================================================
export default {
zone_name: 'Asia/Manila',
gmt_offset: [32400, 29032, 28800, -57368]
};
================================================
FILE: src/timezones/Asia/Muscat.ts
================================================
export default {
zone_name: 'Asia/Muscat',
gmt_offset: [14400, 14064]
};
================================================
FILE: src/timezones/Asia/Nicosia.ts
================================================
export default {
zone_name: 'Asia/Nicosia',
gmt_offset: [10800, 8008, 7200]
};
================================================
FILE: src/timezones/Asia/Novokuznetsk.ts
================================================
export default {
zone_name: 'Asia/Novokuznetsk',
gmt_offset: [28800, 25200, 21600, 20928]
};
================================================
FILE: src/timezones/Asia/Novosibirsk.ts
================================================
export default {
zone_name: 'Asia/Novosibirsk',
gmt_offset: [28800, 25200, 21600, 19900]
};
================================================
FILE: src/timezones/Asia/Omsk.ts
================================================
export default {
zone_name: 'Asia/Omsk',
gmt_offset: [25200, 21600, 18000, 17610]
};
================================================
FILE: src/timezones/Asia/Oral.ts
================================================
export default {
zone_name: 'Asia/Oral',
gmt_offset: [21600, 18000, 14400, 12324, 10800]
};
================================================
FILE: src/timezones/Asia/Phnom_Penh.ts
================================================
export default {
zone_name: 'Asia/Phnom_Penh',
gmt_offset: [32400, 28800, 25590, 25200, 25180]
};
================================================
FILE: src/timezones/Asia/Pontianak.ts
================================================
export default {
zone_name: 'Asia/Pontianak',
gmt_offset: [32400, 28800, 27000, 26240, 25200]
};
================================================
FILE: src/timezones/Asia/Pyongyang.ts
================================================
export default {
zone_name: 'Asia/Pyongyang',
gmt_offset: [32400, 30600, 30180]
};
================================================
FILE: src/timezones/Asia/Qatar.ts
================================================
export default {
zone_name: 'Asia/Qatar',
gmt_offset: [14400, 12368, 10800]
};
================================================
FILE: src/timezones/Asia/Qostanay.ts
================================================
export default {
zone_name: 'Asia/Qostanay',
gmt_offset: [21600, 18000, 15268, 14400]
};
================================================
FILE: src/timezones/Asia/Qyzylorda.ts
================================================
export default {
zone_name: 'Asia/Qyzylorda',
gmt_offset: [21600, 18000, 15712, 14400]
};
================================================
FILE: src/timezones/Asia/Riyadh.ts
================================================
export default {
zone_name: 'Asia/Riyadh',
gmt_offset: [11212, 10800]
};
================================================
FILE: src/timezones/Asia/Sakhalin.ts
================================================
export default {
zone_name: 'Asia/Sakhalin',
gmt_offset: [43200, 39600, 36000, 34248, 32400]
};
================================================
FILE: src/timezones/Asia/Samarkand.ts
================================================
export default {
zone_name: 'Asia/Samarkand',
gmt_offset: [21600, 18000, 16073, 14400]
};
================================================
FILE: src/timezones/Asia/Seoul.ts
================================================
export default {
zone_name: 'Asia/Seoul',
gmt_offset: [36000, 34200, 32400, 30600, 30472]
};
================================================
FILE: src/timezones/Asia/Shanghai.ts
================================================
export default {
zone_name: 'Asia/Shanghai',
gmt_offset: [32400, 29143, 28800]
};
================================================
FILE: src/timezones/Asia/Singapore.ts
================================================
export default {
zone_name: 'Asia/Singapore',
gmt_offset: [32400, 28800, 27000, 26400, 25200, 24925]
};
================================================
FILE: src/timezones/Asia/Srednekolymsk.ts
================================================
export default {
zone_name: 'Asia/Srednekolymsk',
gmt_offset: [43200, 39600, 36892, 36000]
};
================================================
FILE: src/timezones/Asia/Taipei.ts
================================================
export default {
zone_name: 'Asia/Taipei',
gmt_offset: [32400, 29160, 28800]
};
================================================
FILE: src/timezones/Asia/Tashkent.ts
================================================
export default {
zone_name: 'Asia/Tashkent',
gmt_offset: [25200, 21600, 18000, 16631]
};
================================================
FILE: src/timezones/Asia/Tbilisi.ts
================================================
export default {
zone_name: 'Asia/Tbilisi',
gmt_offset: [18000, 14400, 10800, 10751]
};
================================================
FILE: src/timezones/Asia/Tehran.ts
================================================
export default {
zone_name: 'Asia/Tehran',
gmt_offset: [18000, 16200, 14400, 12600, 12344]
};
================================================
FILE: src/timezones/Asia/Thimphu.ts
================================================
export default {
zone_name: 'Asia/Thimphu',
gmt_offset: [21600, 21516, 19800]
};
================================================
FILE: src/timezones/Asia/Tokyo.ts
================================================
export default {
zone_name: 'Asia/Tokyo',
gmt_offset: [36000, 33539, 32400]
};
================================================
FILE: src/timezones/Asia/Tomsk.ts
================================================
export default {
zone_name: 'Asia/Tomsk',
gmt_offset: [28800, 25200, 21600, 20391]
};
================================================
FILE: src/timezones/Asia/Ulaanbaatar.ts
================================================
export default {
zone_name: 'Asia/Ulaanbaatar',
gmt_offset: [32400, 28800, 25652, 25200]
};
================================================
FILE: src/timezones/Asia/Urumqi.ts
================================================
export default {
zone_name: 'Asia/Urumqi',
gmt_offset: [21600, 21020]
};
================================================
FILE: src/timezones/Asia/Ust-Nera.ts
================================================
export default {
zone_name: 'Asia/Ust-Nera',
gmt_offset: [43200, 39600, 36000, 34374, 32400, 28800]
};
================================================
FILE: src/timezones/Asia/Vientiane.ts
================================================
export default {
zone_name: 'Asia/Vientiane',
gmt_offset: [32400, 28800, 25590, 25200, 24624]
};
================================================
FILE: src/timezones/Asia/Vladivostok.ts
================================================
export default {
zone_name: 'Asia/Vladivostok',
gmt_offset: [39600, 36000, 32400, 31651]
};
================================================
FILE: src/timezones/Asia/Yakutsk.ts
================================================
export default {
zone_name: 'Asia/Yakutsk',
gmt_offset: [36000, 32400, 31138, 28800]
};
================================================
FILE: src/timezones/Asia/Yangon.ts
================================================
export default {
zone_name: 'Asia/Yangon',
gmt_offset: [32400, 23400, 23087]
};
================================================
FILE: src/timezones/Asia/Yekaterinburg.ts
================================================
export default {
zone_name: 'Asia/Yekaterinburg',
gmt_offset: [21600, 18000, 14553, 14400, 13505]
};
================================================
FILE: src/timezones/Asia/Yerevan.ts
================================================
export default {
zone_name: 'Asia/Yerevan',
gmt_offset: [18000, 14400, 10800, 10680]
};
================================================
FILE: src/timezones/Atlantic/Azores.ts
================================================
export default {
zone_name: 'Atlantic/Azores',
gmt_offset: [3600, 0, -3600, -6160, -6872, -7200]
};
================================================
FILE: src/timezones/Atlantic/Bermuda.ts
================================================
export default {
zone_name: 'Atlantic/Bermuda',
gmt_offset: [-10800, -11958, -14400, -15558]
};
================================================
FILE: src/timezones/Atlantic/Canary.ts
================================================
export default {
zone_name: 'Atlantic/Canary',
gmt_offset: [3600, 0, -3600, -3696]
};
================================================
FILE: src/timezones/Atlantic/Cape_Verde.ts
================================================
export default {
zone_name: 'Atlantic/Cape_Verde',
gmt_offset: [-3600, -5644, -7200]
};
================================================
FILE: src/timezones/Atlantic/Faroe.ts
================================================
export default {
zone_name: 'Atlantic/Faroe',
gmt_offset: [3600, 0, -1624]
};
================================================
FILE: src/timezones/Atlantic/Madeira.ts
================================================
export default {
zone_name: 'Atlantic/Madeira',
gmt_offset: [3600, 0, -3600, -4056]
};
================================================
FILE: src/timezones/Atlantic/Reykjavik.ts
================================================
export default {
zone_name: 'Atlantic/Reykjavik',
gmt_offset: [0, -3600, -5280]
};
================================================
FILE: src/timezones/Atlantic/South_Georgia.ts
================================================
export default {
zone_name: 'Atlantic/South_Georgia',
gmt_offset: [-7200, -8768]
};
================================================
FILE: src/timezones/Atlantic/St_Helena.ts
================================================
export default {
zone_name: 'Atlantic/St_Helena',
gmt_offset: [0, -1368]
};
================================================
FILE: src/timezones/Atlantic/Stanley.ts
================================================
export default {
zone_name: 'Atlantic/Stanley',
gmt_offset: [-7200, -10800, -13884, -14400]
};
================================================
FILE: src/timezones/Australia/Adelaide.ts
================================================
export default {
zone_name: 'Australia/Adelaide',
gmt_offset: [37800, 34200, 33260, 32400]
};
================================================
FILE: src/timezones/Australia/Brisbane.ts
================================================
export default {
zone_name: 'Australia/Brisbane',
gmt_offset: [39600, 36728, 36000]
};
================================================
FILE: src/timezones/Australia/Broken_Hill.ts
================================================
export default {
zone_name: 'Australia/Broken_Hill',
gmt_offset: [37800, 36000, 34200, 33948, 32400]
};
================================================
FILE: src/timezones/Australia/Darwin.ts
================================================
export default {
zone_name: 'Australia/Darwin',
gmt_offset: [37800, 34200, 32400, 31400]
};
================================================
FILE: src/timezones/Australia/Eucla.ts
================================================
export default {
zone_name: 'Australia/Eucla',
gmt_offset: [35100, 31500, 30928]
};
================================================
FILE: src/timezones/Australia/Hobart.ts
================================================
export default {
zone_name: 'Australia/Hobart',
gmt_offset: [39600, 36000, 35356]
};
================================================
FILE: src/timezones/Australia/Lindeman.ts
================================================
export default {
zone_name: 'Australia/Lindeman',
gmt_offset: [39600, 36000, 35756]
};
================================================
FILE: src/timezones/Australia/Lord_Howe.ts
================================================
export default {
zone_name: 'Australia/Lord_Howe',
gmt_offset: [41400, 39600, 38180, 37800, 36000]
};
================================================
FILE: src/timezones/Australia/Melbourne.ts
================================================
export default {
zone_name: 'Australia/Melbourne',
gmt_offset: [39600, 36000, 34792]
};
================================================
FILE: src/timezones/Australia/Perth.ts
================================================
export default {
zone_name: 'Australia/Perth',
gmt_offset: [32400, 28800, 27804]
};
================================================
FILE: src/timezones/Australia/Sydney.ts
================================================
export default {
zone_name: 'Australia/Sydney',
gmt_offset: [39600, 36292, 36000]
};
================================================
FILE: src/timezones/Europe/Amsterdam.ts
================================================
export default {
zone_name: 'Europe/Amsterdam',
gmt_offset: [7200, 4800, 4772, 3600, 1200, 1172]
};
================================================
FILE: src/timezones/Europe/Andorra.ts
================================================
export default {
zone_name: 'Europe/Andorra',
gmt_offset: [7200, 3600, 364, 0]
};
================================================
FILE: src/timezones/Europe/Astrakhan.ts
================================================
export default {
zone_name: 'Europe/Astrakhan',
gmt_offset: [18000, 14400, 11532, 10800]
};
================================================
FILE: src/timezones/Europe/Athens.ts
================================================
export default {
zone_name: 'Europe/Athens',
gmt_offset: [10800, 7200, 5692, 3600]
};
================================================
FILE: src/timezones/Europe/Belgrade.ts
================================================
export default {
zone_name: 'Europe/Belgrade',
gmt_offset: [7200, 4920, 3600]
};
================================================
FILE: src/timezones/Europe/Berlin.ts
================================================
export default {
zone_name: 'Europe/Berlin',
gmt_offset: [10800, 7200, 3600, 3208]
};
================================================
FILE: src/timezones/Europe/Bratislava.ts
================================================
export default {
zone_name: 'Europe/Bratislava',
gmt_offset: [7200, 3600, 3464, 0]
};
================================================
FILE: src/timezones/Europe/Brussels.ts
================================================
export default {
zone_name: 'Europe/Brussels',
gmt_offset: [7200, 3600, 1050, 0]
};
================================================
FILE: src/timezones/Europe/Bucharest.ts
================================================
export default {
zone_name: 'Europe/Bucharest',
gmt_offset: [10800, 7200, 6264]
};
================================================
FILE: src/timezones/Europe/Budapest.ts
================================================
export default {
zone_name: 'Europe/Budapest',
gmt_offset: [7200, 4580, 3600]
};
================================================
FILE: src/timezones/Europe/Busingen.ts
================================================
export default {
zone_name: 'Europe/Busingen',
gmt_offset: [7200, 3600, 2048, 1786]
};
================================================
FILE: src/timezones/Europe/Chisinau.ts
================================================
export default {
zone_name: 'Europe/Chisinau',
gmt_offset: [14400, 10800, 7200, 6920, 6900, 6264, 3600]
};
================================================
FILE: src/timezones/Europe/Copenhagen.ts
================================================
export default {
zone_name: 'Europe/Copenhagen',
gmt_offset: [7200, 3600, 3020]
};
================================================
FILE: src/timezones/Europe/Dublin.ts
================================================
export default {
zone_name: 'Europe/Dublin',
gmt_offset: [3600, 2079, 0, -1521]
};
================================================
FILE: src/timezones/Europe/Gibraltar.ts
================================================
export default {
zone_name: 'Europe/Gibraltar',
gmt_offset: [7200, 3600, 0, -1284]
};
================================================
FILE: src/timezones/Europe/Guernsey.ts
================================================
export default {
zone_name: 'Europe/Guernsey',
gmt_offset: [7200, 3600, 0, -609]
};
================================================
FILE: src/timezones/Europe/Helsinki.ts
================================================
export default {
zone_name: 'Europe/Helsinki',
gmt_offset: [10800, 7200, 5989]
};
================================================
FILE: src/timezones/Europe/Isle_of_Man.ts
================================================
export default {
zone_name: 'Europe/Isle_of_Man',
gmt_offset: [7200, 3600, 0, -1075]
};
================================================
FILE: src/timezones/Europe/Istanbul.ts
================================================
export default {
zone_name: 'Europe/Istanbul',
gmt_offset: [14400, 10800, 7200, 7016, 6952]
};
================================================
FILE: src/timezones/Europe/Jersey.ts
================================================
export default {
zone_name: 'Europe/Jersey',
gmt_offset: [7200, 3600, 0, -506]
};
================================================
FILE: src/timezones/Europe/Kaliningrad.ts
================================================
export default {
zone_name: 'Europe/Kaliningrad',
gmt_offset: [14400, 10800, 7200, 4920, 3600]
};
================================================
FILE: src/timezones/Europe/Kirov.ts
================================================
export default {
zone_name: 'Europe/Kirov',
gmt_offset: [18000, 14400, 11928, 10800]
};
================================================
FILE: src/timezones/Europe/Kyiv.ts
================================================
export default {
zone_name: 'Europe/Kyiv',
gmt_offset: [14400, 10800, 7324, 7200, 3600]
};
================================================
FILE: src/timezones/Europe/Lisbon.ts
================================================
export default {
zone_name: 'Europe/Lisbon',
gmt_offset: [7200, 3600, 0, -2205]
};
================================================
FILE: src/timezones/Europe/Ljubljana.ts
================================================
export default {
zone_name: 'Europe/Ljubljana',
gmt_offset: [7200, 3600, 3484]
};
================================================
FILE: src/timezones/Europe/London.ts
================================================
export default {
zone_name: 'Europe/London',
gmt_offset: [7200, 3600, 0, -75]
};
================================================
FILE: src/timezones/Europe/Luxembourg.ts
================================================
export default {
zone_name: 'Europe/Luxembourg',
gmt_offset: [7200, 3600, 1476, 0]
};
================================================
FILE: src/timezones/Europe/Madrid.ts
================================================
export default {
zone_name: 'Europe/Madrid',
gmt_offset: [7200, 3600, 0, -884]
};
================================================
FILE: src/timezones/Europe/Malta.ts
================================================
export default {
zone_name: 'Europe/Malta',
gmt_offset: [7200, 3600, 3484]
};
================================================
FILE: src/timezones/Europe/Mariehamn.ts
================================================
export default {
zone_name: 'Europe/Mariehamn',
gmt_offset: [10800, 7200, 5989]
};
================================================
FILE: src/timezones/Europe/Minsk.ts
================================================
export default {
zone_name: 'Europe/Minsk',
gmt_offset: [14400, 10800, 7200, 6616, 6600, 3600]
};
================================================
FILE: src/timezones/Europe/Monaco.ts
================================================
export default {
zone_name: 'Europe/Monaco',
gmt_offset: [7200, 3600, 1772, 561, 0]
};
================================================
FILE: src/timezones/Europe/Moscow.ts
================================================
export default {
zone_name: 'Europe/Moscow',
gmt_offset: [18000, 16279, 14400, 12679, 10800, 9079, 9017, 7200]
};
================================================
FILE: src/timezones/Europe/Oslo.ts
================================================
export default {
zone_name: 'Europe/Oslo',
gmt_offset: [7200, 3600, 2580]
};
================================================
FILE: src/timezones/Europe/Paris.ts
================================================
export default {
zone_name: 'Europe/Paris',
gmt_offset: [7200, 3600, 561, 0]
};
================================================
FILE: src/timezones/Europe/Podgorica.ts
================================================
export default {
zone_name: 'Europe/Podgorica',
gmt_offset: [7200, 4920, 3600]
};
================================================
FILE: src/timezones/Europe/Prague.ts
================================================
export default {
zone_name: 'Europe/Prague',
gmt_offset: [7200, 3600, 3464, 0]
};
================================================
FILE: src/timezones/Europe/Riga.ts
================================================
export default {
zone_name: 'Europe/Riga',
gmt_offset: [14400, 10800, 9394, 7200, 5794, 3600]
};
================================================
FILE: src/timezones/Europe/Rome.ts
================================================
export default {
zone_name: 'Europe/Rome',
gmt_offset: [7200, 3600, 2996]
};
================================================
FILE: src/timezones/Europe/Samara.ts
================================================
export default {
zone_name: 'Europe/Samara',
gmt_offset: [18000, 14400, 12020, 10800]
};
================================================
FILE: src/timezones/Europe/San_Marino.ts
================================================
export default {
zone_name: 'Europe/San_Marino',
gmt_offset: [7200, 3600, 2996]
};
================================================
FILE: src/timezones/Europe/Sarajevo.ts
================================================
export default {
zone_name: 'Europe/Sarajevo',
gmt_offset: [7200, 4420, 3600]
};
================================================
FILE: src/timezones/Europe/Saratov.ts
================================================
export default {
zone_name: 'Europe/Saratov',
gmt_offset: [18000, 14400, 11058, 10800]
};
================================================
FILE: src/timezones/Europe/Simferopol.ts
================================================
export default {
zone_name: 'Europe/Simferopol',
gmt_offset: [14400, 10800, 8184, 8160, 7200, 3600]
};
================================================
FILE: src/timezones/Europe/Skopje.ts
================================================
export default {
zone_name: 'Europe/Skopje',
gmt_offset: [7200, 5144, 3600]
};
================================================
FILE: src/timezones/Europe/Sofia.ts
================================================
export default {
zone_name: 'Europe/Sofia',
gmt_offset: [10800, 7200, 7016, 5596, 3600]
};
================================================
FILE: src/timezones/Europe/Stockholm.ts
================================================
export default {
zone_name: 'Europe/Stockholm',
gmt_offset: [7200, 4332, 3614, 3600]
};
================================================
FILE: src/timezones/Europe/Tallinn.ts
================================================
export default {
zone_name: 'Europe/Tallinn',
gmt_offset: [14400, 10800, 7200, 5940, 3600]
};
================================================
FILE: src/timezones/Europe/Tirane.ts
================================================
export default {
zone_name: 'Europe/Tirane',
gmt_offset: [7200, 4760, 3600]
};
================================================
FILE: src/timezones/Europe/Ulyanovsk.ts
================================================
export default {
zone_name: 'Europe/Ulyanovsk',
gmt_offset: [18000, 14400, 11616, 10800, 7200]
};
================================================
FILE: src/timezones/Europe/Vaduz.ts
================================================
export default {
zone_name: 'Europe/Vaduz',
gmt_offset: [7200, 3600, 2284]
};
================================================
FILE: src/timezones/Europe/Vatican.ts
================================================
export default {
zone_name: 'Europe/Vatican',
gmt_offset: [7200, 3600, 2996]
};
================================================
FILE: src/timezones/Europe/Vienna.ts
================================================
export default {
zone_name: 'Europe/Vienna',
gmt_offset: [7200, 3921, 3600]
};
================================================
FILE: src/timezones/Europe/Vilnius.ts
================================================
export default {
zone_name: 'Europe/Vilnius',
gmt_offset: [14400, 10800, 7200, 6076, 5736, 5040, 3600]
};
================================================
FILE: src/timezones/Europe/Volgograd.ts
================================================
export default {
zone_name: 'Europe/Volgograd',
gmt_offset: [18000, 14400, 10800, 10660]
};
================================================
FILE: src/timezones/Europe/Warsaw.ts
================================================
export default {
zone_name: 'Europe/Warsaw',
gmt_offset: [10800, 7200, 5040, 3600]
};
================================================
FILE: src/timezones/Europe/Zagreb.ts
================================================
export default {
zone_name: 'Europe/Zagreb',
gmt_offset: [7200, 3832, 3600]
};
================================================
FILE: src/timezones/Europe/Zurich.ts
================================================
export default {
zone_name: 'Europe/Zurich',
gmt_offset: [7200, 3600, 2048, 1786]
};
================================================
FILE: src/timezones/Indian/Antananarivo.ts
================================================
export default {
zone_name: 'Indian/Antananarivo',
gmt_offset: [14400, 11404, 10800]
};
================================================
FILE: src/timezones/Indian/Chagos.ts
================================================
export default {
zone_name: 'Indian/Chagos',
gmt_offset: [21600, 18000, 17380]
};
================================================
FILE: src/timezones/Indian/Christmas.ts
================================================
export default {
zone_name: 'Indian/Christmas',
gmt_offset: [25372, 25200]
};
================================================
FILE: src/timezones/Indian/Cocos.ts
================================================
export default {
zone_name: 'Indian/Cocos',
gmt_offset: [23400, 23260]
};
================================================
FILE: src/timezones/Indian/Comoro.ts
================================================
export default {
zone_name: 'Indian/Comoro',
gmt_offset: [10800, 10384]
};
================================================
FILE: src/timezones/Indian/Kerguelen.ts
================================================
export default {
zone_name: 'Indian/Kerguelen',
gmt_offset: [18000, 0]
};
================================================
FILE: src/timezones/Indian/Mahe.ts
================================================
export default {
zone_name: 'Indian/Mahe',
gmt_offset: [14400, 13308]
};
================================================
FILE: src/timezones/Indian/Maldives.ts
================================================
export default {
zone_name: 'Indian/Maldives',
gmt_offset: [18000, 17640]
};
================================================
FILE: src/timezones/Indian/Mauritius.ts
================================================
export default {
zone_name: 'Indian/Mauritius',
gmt_offset: [18000, 14400, 13800]
};
================================================
FILE: src/timezones/Indian/Mayotte.ts
================================================
export default {
zone_name: 'Indian/Mayotte',
gmt_offset: [10856, 10800]
};
================================================
FILE: src/timezones/Indian/Reunion.ts
================================================
export default {
zone_name: 'Indian/Reunion',
gmt_offset: [14400, 13312]
};
================================================
FILE: src/timezones/Pacific/Apia.ts
================================================
export default {
zone_name: 'Pacific/Apia',
gmt_offset: [50400, 46800, 45184, -36000, -39600, -41216, -41400]
};
================================================
FILE: src/timezones/Pacific/Auckland.ts
================================================
export default {
zone_name: 'Pacific/Auckland',
gmt_offset: [46800, 45000, 43200, 41944, 41400]
};
================================================
FILE: src/timezones/Pacific/Bougainville.ts
================================================
export default {
zone_name: 'Pacific/Bougainville',
gmt_offset: [39600, 37336, 36000, 35312, 32400]
};
================================================
FILE: src/timezones/Pacific/Chatham.ts
================================================
export default {
zone_name: 'Pacific/Chatham',
gmt_offset: [49500, 45900, 44100, 44028]
};
================================================
FILE: src/timezones/Pacific/Chuuk.ts
================================================
export default {
zone_name: 'Pacific/Chuuk',
gmt_offset: [36428, 36000, 32400, -49972]
};
================================================
FILE: src/timezones/Pacific/Easter.ts
================================================
export default {
zone_name: 'Pacific/Easter',
gmt_offset: [-18000, -21600, -25200, -26248]
};
================================================
FILE: src/timezones/Pacific/Efate.ts
================================================
export default {
zone_name: 'Pacific/Efate',
gmt_offset: [43200, 40396, 39600]
};
================================================
FILE: src/timezones/Pacific/Fakaofo.ts
================================================
export default {
zone_name: 'Pacific/Fakaofo',
gmt_offset: [46800, -39600, -41096]
};
================================================
FILE: src/timezones/Pacific/Fiji.ts
================================================
export default {
zone_name: 'Pacific/Fiji',
gmt_offset: [46800, 43200, 42944]
};
================================================
FILE: src/timezones/Pacific/Funafuti.ts
================================================
export default {
zone_name: 'Pacific/Funafuti',
gmt_offset: [43200, 43012]
};
================================================
FILE: src/timezones/Pacific/Galapagos.ts
================================================
export default {
zone_name: 'Pacific/Galapagos',
gmt_offset: [-18000, -21504, -21600]
};
================================================
FILE: src/timezones/Pacific/Gambier.ts
================================================
export default {
zone_name: 'Pacific/Gambier',
gmt_offset: [-32388, -32400]
};
================================================
FILE: src/timezones/Pacific/Guadalcanal.ts
================================================
export default {
zone_name: 'Pacific/Guadalcanal',
gmt_offset: [39600, 38388]
};
================================================
FILE: src/timezones/Pacific/Guam.ts
================================================
export default {
zone_name: 'Pacific/Guam',
gmt_offset: [39600, 36000, 34740, 32400, -51660]
};
================================================
FILE: src/timezones/Pacific/Honolulu.ts
================================================
export default {
zone_name: 'Pacific/Honolulu',
gmt_offset: [-34200, -36000, -37800, -37886]
};
================================================
FILE: src/timezones/Pacific/Kanton.ts
================================================
export default {
zone_name: 'Pacific/Kanton',
gmt_offset: [46800, 0, -39600, -43200]
};
================================================
FILE: src/timezones/Pacific/Kiritimati.ts
================================================
export default {
zone_name: 'Pacific/Kiritimati',
gmt_offset: [50400, -36000, -37760, -38400]
};
================================================
FILE: src/timezones/Pacific/Kosrae.ts
================================================
export default {
zone_name: 'Pacific/Kosrae',
gmt_offset: [43200, 39600, 39116, 36000, 32400, -47284]
};
================================================
FILE: src/timezones/Pacific/Kwajalein.ts
================================================
export default {
zone_name: 'Pacific/Kwajalein',
gmt_offset: [43200, 40160, 39600, 36000, 32400, -43200]
};
================================================
FILE: src/timezones/Pacific/Majuro.ts
================================================
export default {
zone_name: 'Pacific/Majuro',
gmt_offset: [43200, 41088, 39600, 36000, 32400]
};
================================================
FILE: src/timezones/Pacific/Marquesas.ts
================================================
export default {
zone_name: 'Pacific/Marquesas',
gmt_offset: [-33480, -34200]
};
================================================
FILE: src/timezones/Pacific/Midway.ts
================================================
export default {
zone_name: 'Pacific/Midway',
gmt_offset: [-36000, -39600, -42568]
};
================================================
FILE: src/timezones/Pacific/Nauru.ts
================================================
export default {
zone_name: 'Pacific/Nauru',
gmt_offset: [43200, 41400, 40060, 32400]
};
================================================
FILE: src/timezones/Pacific/Niue.ts
================================================
export default {
zone_name: 'Pacific/Niue',
gmt_offset: [-39600, -40780, -40800]
};
================================================
FILE: src/timezones/Pacific/Norfolk.ts
================================================
export default {
zone_name: 'Pacific/Norfolk',
gmt_offset: [45000, 43200, 41400, 40320, 40312, 39600]
};
================================================
FILE: src/timezones/Pacific/Noumea.ts
================================================
export default {
zone_name: 'Pacific/Noumea',
gmt_offset: [43200, 39948, 39600]
};
================================================
FILE: src/timezones/Pacific/Pago_Pago.ts
================================================
export default {
zone_name: 'Pacific/Pago_Pago',
gmt_offset: [45432, -39600, -40968]
};
================================================
FILE: src/timezones/Pacific/Palau.ts
================================================
export default {
zone_name: 'Pacific/Palau',
gmt_offset: [32400, 32276, -54124]
};
================================================
FILE: src/timezones/Pacific/Pitcairn.ts
================================================
export default {
zone_name: 'Pacific/Pitcairn',
gmt_offset: [-28800, -30600, -31220]
};
================================================
FILE: src/timezones/Pacific/Pohnpei.ts
================================================
export default {
zone_name: 'Pacific/Pohnpei',
gmt_offset: [39600, 37972, 36000, 32400, -48428]
};
================================================
FILE: src/timezones/Pacific/Port_Moresby.ts
================================================
export default {
zone_name: 'Pacific/Port_Moresby',
gmt_offset: [36000, 35320, 35312]
};
================================================
FILE: src/timezones/Pacific/Rarotonga.ts
================================================
export default {
zone_name: 'Pacific/Rarotonga',
gmt_offset: [48056, -34200, -36000, -37800, -38344]
};
================================================
FILE: src/timezones/Pacific/Saipan.ts
================================================
export default {
zone_name: 'Pacific/Saipan',
gmt_offset: [39600, 36000, 34980, 32400, -51420]
};
================================================
FILE: src/timezones/Pacific/Tahiti.ts
================================================
export default {
zone_name: 'Pacific/Tahiti',
gmt_offset: [-35896, -36000]
};
================================================
FILE: src/timezones/Pacific/Tarawa.ts
================================================
export default {
zone_name: 'Pacific/Tarawa',
gmt_offset: [43200, 41524]
};
================================================
FILE: src/timezones/Pacific/Tongatapu.ts
================================================
export default {
zone_name: 'Pacific/Tongatapu',
gmt_offset: [50400, 46800, 44400, 44352]
};
================================================
FILE: src/timezones/Pacific/Wake.ts
================================================
export default {
zone_name: 'Pacific/Wake',
gmt_offset: [43200, 39988]
};
================================================
FILE: src/timezones/Pacific/Wallis.ts
================================================
export default {
zone_name: 'Pacific/Wallis',
gmt_offset: [44120, 43200]
};
================================================
FILE: src/transform.ts
================================================
import { parse } from './parse.ts';
import { format } from './format.ts';
import { CompiledObject } from './compile.ts';
import type { ParserOptions } from './parser.ts';
import type { FormatterOptions } from './formatter.ts';
/**
* Transforms a date string from one format to another.
* @param dateString - The date string to transform
* @param arg1 - The format string or compiled object for parsing
* @param arg2 - The format string or compiled object for formatting
* @param [options1] - Optional parser options
* @param [options2] - Optional formatter options
* @returns The transformed date string
*/
export function transform(dateString: string, arg1: string | CompiledObject, arg2: string | CompiledObject, options1?: ParserOptions, options2?: FormatterOptions) {
return format(parse(dateString, arg1, options1), arg2, options2);
}
================================================
FILE: src/utils.ts
================================================
/**
* Determines if the specified year is a leap year.
* @param year - The gregorian year to check for leap year status (1-9999)
* @returns True if the year is a leap year, false otherwise
*/
export const isLeapYear = (year: number) => {
return (!(year % 4) && !!(year % 100)) || !(year % 400);
};
/**
* Determines if two dates represent the same calendar day.
* @param date1 - The first date to compare
* @param date2 - The second date to compare
* @returns True if both dates are on the same day, false otherwise
*/
export const isSameDay = (date1: Date, date2: Date) => {
return date1.toDateString() === date2.toDateString();
};
// The toUTC function converts a given year, month, and day into a UTC timestamp.
// The `m` parameter is 0-indexed (0 = January, 11 = December), matching the convention of Date.UTC.
const toUTC = (y: number, m: number, d: number) => Date.UTC(y, m - (y < 100 ? 1900 * 12 : 0), d);
/**
* Returns the number of days in a given month of a specific year.
* @param date - The date to get the number of days for
* @returns The number of days in the month of the provided date
*/
export function getDaysInMonth (date: Date): number;
/**
* Returns the number of days in a given month of a specific year.
* @param year - The gregorian year (1-9999) to get the number of days for
* @param month - The month (1-12) to get the number of days for
* @returns The number of days in the month of the provided date
*/
export function getDaysInMonth (year: number, month: number): number;
export function getDaysInMonth (...args: [date: Date] | [year: number, month: number]) {
const [year, month] = (
() => args.length === 1
? [args[0].getFullYear(), args[0].getMonth() + 1]
: args
)();
// month is 1-indexed here; day 0 of next month = last day of current month
return new Date(toUTC(year, month, 0)).getUTCDate();
}
// The getThursdayOfWeek function calculates the Thursday of the week for a given time.
// This is used as an anchor point to determine the ISO week number and ISO week year,
// since the ISO week starts on Monday and ends on Sunday,
// and Thursday is always in the same ISO week as the given date.
const getThursdayOfWeek = (time: number) => {
const target = new Date(time);
// getUTCDay() returns 0 for Sunday, so we use (day || 7) to treat Sunday as the 7th day of the week
target.setUTCDate(target.getUTCDate() + (4 - (target.getUTCDay() || 7)));
return target;
};
/**
* Calculates the ISO week year for a given date.
* @param date - The date to calculate the ISO week year for
* @returns The ISO week year corresponding to the provided date
*/
export function getISOWeekYear (date: Date): number;
/**
* Calculates the ISO week year for a given year, month, and day.
* @param year - The gregorian year (1-9999) to calculate the ISO week year for
* @param month - The month (1-12) to calculate the ISO week year for
* @param day - The day (1-31) to calculate the ISO week year for
* @returns The ISO week year corresponding to the provided date
*/
export function getISOWeekYear (year: number, month: number, day: number): number;
export function getISOWeekYear (...args: [date: Date] | [year: number, month: number, day: number]) {
const [year, month, day] = (
() => args.length === 1
? [args[0].getFullYear(), args[0].getMonth() + 1, args[0].getDate()]
: args
)();
// The ISO week year is the year that contains the Thursday of the week
return getThursdayOfWeek(toUTC(year, month - 1, day)).getUTCFullYear();
}
/**
* Calculates the ISO week number for a given date.
* @param date - The date to calculate the ISO week number for
* @returns The ISO week number corresponding to the provided date
*/
export function getISOWeek (date: Date): number;
/**
* Calculates the ISO week number for a given year, month, and day.
* @param year - The gregorian year (1-9999) to calculate the ISO week number for
* @param month - The month (1-12) to calculate the ISO week number for
* @param day - The day (1-31) to calculate the ISO week number for
* @returns The ISO week number corresponding to the provided date
*/
export function getISOWeek (year: number, month: number, day: number): number;
export function getISOWeek (...args: [date: Date] | [year: number, month: number, day: number]) {
const [year, month, day] = (
() => args.length === 1
? [args[0].getFullYear(), args[0].getMonth() + 1, args[0].getDate()]
: args
)();
const target = getThursdayOfWeek(toUTC(year, month - 1, day));
// Calculate the ISO week number by finding the difference in weeks between the target date
// and the Thursday of the first week of the year (January 4th)
return Math.round((target.getTime() - getThursdayOfWeek(toUTC(target.getUTCFullYear(), 0, 4)).getTime()) / 86400000 / 7) + 1;
}
================================================
FILE: src/zone.ts
================================================
import { dtfToParts, fromParts } from './datetime.ts';
import { getDateTimeFormat } from './dtf.ts';
export interface TimeZone {
zone_name: string;
gmt_offset: number[];
}
export const isTimeZone = (timeZone: unknown): timeZone is TimeZone => {
return !!timeZone && typeof timeZone === 'object' && 'zone_name' in timeZone && 'gmt_offset' in timeZone;
};
const getTimezoneOffset = (naiveUTC: number, zoneName: string): number => {
const dtf = (() => {
try {
return getDateTimeFormat(zoneName);
} catch {
return undefined;
}
})();
const set = new Set();
if (dtf) {
// Try to find the correct offset by checking the current and previous days.
for (let d = 0; d < 2; d++) {
const time = naiveUTC - d * 86400 * 1000;
// Starting from a positive offset (≥ the maximum westward IANA offset, Metlakatla: UTC-15:13:42)
// ensures DST is preferred over standard time for ambiguous fall-back timestamps.
let offset = 54822 * 1000;
do {
const diff = fromParts(dtfToParts(dtf, time - offset)) - time;
if (diff === 0) {
return offset;
}
set.add(offset);
offset += diff;
} while (!set.has(offset));
set.clear();
}
}
return NaN;
};
export const createTimezoneDate = (naiveUTC: number, timeZone: TimeZone | string) => {
const zoneName = isTimeZone(timeZone) ? timeZone.zone_name : timeZone;
return new Date(naiveUTC - getTimezoneOffset(naiveUTC, zoneName));
};
================================================
FILE: src/zonenames.ts
================================================
/**
* @description
* This file was generated from the execution result of the `npm run zonename` command.
*/
export default {
'Acre Standard Time': 'ACT',
'Acre Summer Time': 'ACST',
'Afghanistan Time': 'AFT',
'Alaska Daylight Time': 'AKDT',
'Alaska Standard Time': 'AKST',
'Almaty Standard Time': 'ALMT',
'Almaty Summer Time': 'ALMST',
'Amazon Standard Time': 'AMT',
'Amazon Summer Time': 'AMST',
'American Samoa Standard Time': 'SST',
'Anadyr Standard Time': 'ANAT',
'Anadyr Summer Time': 'ANAST',
'Apia Daylight Time': 'WSDT',
'Apia Standard Time': 'WSST',
'Aqtau Standard Time': 'AQTT',
'Aqtau Summer Time': 'AQTST',
'Aqtobe Standard Time': 'AQTT',
'Aqtobe Summer Time': 'AQTST',
'Arabian Daylight Time': 'ADT',
'Arabian Standard Time': 'AST',
'Argentina Standard Time': 'ART',
'Argentina Summer Time': 'ARST',
'Armenia Standard Time': 'AMT',
'Armenia Summer Time': 'AMST',
'Atlantic Daylight Time': 'ADT',
'Atlantic Standard Time': 'AST',
'Australian Central Daylight Time': 'ACDT',
'Australian Central Standard Time': 'ACST',
'Australian Central Western Daylight Time': 'ACWDT',
'Australian Central Western Standard Time': 'ACWST',
'Australian Eastern Daylight Time': 'AEDT',
'Australian Eastern Standard Time': 'AEST',
'Australian Western Daylight Time': 'AWDT',
'Australian Western Standard Time': 'AWST',
'Azerbaijan Standard Time': 'AZT',
'Azerbaijan Summer Time': 'AZST',
'Azores Standard Time': 'AZOT',
'Azores Summer Time': 'AZOST',
'Bangladesh Standard Time': 'BST',
'Bangladesh Summer Time': 'BDST',
'Bhutan Time': 'BTT',
'Bolivia Time': 'BOT',
'Brasilia Standard Time': 'BRT',
'Brasilia Summer Time': 'BRST',
'British Summer Time': 'BST',
'Brunei Darussalam Time': 'BNT',
'Brunei Time': 'BNT',
'Cape Verde Standard Time': 'CVT',
'Casey Time': 'CAST',
'Central Africa Time': 'CAT',
'Central Daylight Time': 'CDT',
'Central European Standard Time': 'CET',
'Central European Summer Time': 'CEST',
'Central Indonesia Time': 'WITA',
'Central Standard Time': 'CST',
'Chamorro Standard Time': 'ChST',
'Chatham Daylight Time': 'CHADT',
'Chatham Standard Time': 'CHAST',
'Chile Standard Time': 'CLT',
'Chile Summer Time': 'CLST',
'China Daylight Time': 'CDT',
'China Standard Time': 'CST',
'Choibalsan Standard Time': 'CHOT',
'Choibalsan Summer Time': 'CHOST',
'Christmas Island Time': 'CXT',
'Chuuk Time': 'CHUT',
'Cocos Islands Time': 'CCT',
'Colombia Standard Time': 'COT',
'Colombia Summer Time': 'COST',
'Cook Islands Half Summer Time': 'CKHST',
'Cook Islands Standard Time': 'CKT',
'Cook Islands Summer Time': 'CKST',
'Coordinated Universal Time': 'UTC',
'Cuba Daylight Time': 'CDT',
'Cuba Standard Time': 'CST',
'Davis Time': 'DAVT',
'Dumont d’Urville Time': 'DDUT',
'Dumont-d’Urville Time': 'DDUT',
'East Africa Time': 'EAT',
'East Greenland Standard Time': 'EGT',
'East Greenland Summer Time': 'EGST',
'East Kazakhstan Time': 'ALMT',
'East Timor Time': 'TLT',
'Easter Island Standard Time': 'EAST',
'Easter Island Summer Time': 'EASST',
'Eastern Daylight Time': 'EDT',
'Eastern European Standard Time': 'EET',
'Eastern European Summer Time': 'EEST',
'Eastern Indonesia Time': 'WIT',
'Eastern Standard Time': 'EST',
'Ecuador Time': 'ECT',
'Falkland Islands Standard Time': 'FKT',
'Falkland Islands Summer Time': 'FKST',
'Fernando de Noronha Standard Time': 'FNT',
'Fernando de Noronha Summer Time': 'FNST',
'Fiji Standard Time': 'FJT',
'Fiji Summer Time': 'FJST',
'French Guiana Time': 'GFT',
'French Southern & Antarctic Time': 'TFT',
'Further-eastern European Time': 'FET',
'Galapagos Time': 'GALT',
'Gambier Time': 'GAMT',
'Georgia Standard Time': 'GET',
'Georgia Summer Time': 'GEST',
'Gilbert Islands Time': 'GILT',
'Greenland Standard Time': 'WGT',
'Greenland Summer Time': 'WGST',
'Greenwich Mean Time': 'GMT',
'Guam Standard Time': 'ChST',
'Gulf Standard Time': 'GST',
'Guyana Time': 'GYT',
'Hawaii-Aleutian Daylight Time': 'HDT',
'Hawaii-Aleutian Standard Time': 'HST',
'Hong Kong Standard Time': 'HKT',
'Hong Kong Summer Time': 'HKST',
'Hovd Standard Time': 'HOVT',
'Hovd Summer Time': 'HOVST',
'India Standard Time': 'IST',
'Indian Ocean Time': 'IOT',
'Indochina Time': 'ICT',
'Iran Daylight Time': 'IRDT',
'Iran Standard Time': 'IRST',
'Irish Standard Time': 'IST',
'Irkutsk Standard Time': 'IRKT',
'Irkutsk Summer Time': 'IRKST',
'Israel Daylight Time': 'IDT',
'Israel Standard Time': 'IST',
'Japan Standard Time': 'JST',
'Kamchatka Standard Time': 'PETT',
'Kamchatka Summer Time': 'PETST',
'Kazakhstan Time': 'KZT',
'Khovd Standard Time': 'HOVT',
'Khovd Summer Time': 'HOVST',
'Korean Daylight Time': 'KDT',
'Korean Standard Time': 'KST',
'Kosrae Time': 'KOST',
'Krasnoyarsk Standard Time': 'KRAT',
'Krasnoyarsk Summer Time': 'KRAST',
'Kyrgyzstan Time': 'KGT',
'Kyzylorda Standard Time': 'QYZT',
'Kyzylorda Summer Time': 'QYZST',
'Lanka Time': 'LKT',
'Line Islands Time': 'LINT',
'Lord Howe Daylight Time': 'LHDT',
'Lord Howe Standard Time': 'LHST',
'Macao Standard Time': 'CST',
'Macao Summer Time': 'CDT',
'Magadan Standard Time': 'MAGT',
'Magadan Summer Time': 'MAGST',
'Malaysia Time': 'MYT',
'Maldives Time': 'MVT',
'Marquesas Time': 'MART',
'Marshall Islands Time': 'MHT',
'Mauritius Standard Time': 'MUT',
'Mauritius Summer Time': 'MUST',
'Mawson Time': 'MAWT',
'Mexican Pacific Daylight Time': 'PDT',
'Mexican Pacific Standard Time': 'PST',
'Moscow Standard Time': 'MSK',
'Moscow Summer Time': 'MSD',
'Mountain Daylight Time': 'MDT',
'Mountain Standard Time': 'MST',
'Myanmar Time': 'MMT',
'Nauru Time': 'NRT',
'Nepal Time': 'NPT',
'New Caledonia Standard Time': 'NCT',
'New Caledonia Summer Time': 'NCST',
'New Zealand Daylight Time': 'NZDT',
'New Zealand Standard Time': 'NZST',
'Newfoundland Daylight Time': 'NDT',
'Newfoundland Standard Time': 'NST',
'Niue Time': 'NUT',
'Norfolk Island Daylight Time': 'NFDT',
'Norfolk Island Standard Time': 'NFT',
'North Korea Time': 'KST',
'North Mariana Islands Time': 'ChST',
'Northern Mariana Islands Time': 'ChST',
'Novosibirsk Standard Time': 'NOVT',
'Novosibirsk Summer Time': 'NOVST',
'Omsk Standard Time': 'OMST',
'Omsk Summer Time': 'OMSST',
'Pacific Daylight Time': 'PDT',
'Pacific Standard Time': 'PST',
'Pakistan Standard Time': 'PKT',
'Pakistan Summer Time': 'PKST',
'Palau Time': 'PWT',
'Papua New Guinea Time': 'PGT',
'Paraguay Standard Time': 'PYT',
'Paraguay Summer Time': 'PYST',
'Peru Standard Time': 'PET',
'Peru Summer Time': 'PEST',
'Petropavlovsk-Kamchatski Standard Time': 'PETT',
'Petropavlovsk-Kamchatski Summer Time': 'PETST',
'Philippine Standard Time': 'PHT',
'Philippine Summer Time': 'PHST',
'Phoenix Islands Time': 'PHOT',
'Pitcairn Time': 'PST',
'Pohnpei Time': 'PONT',
'Ponape Time': 'PONT',
'Pyongyang Time': 'KST',
'Qyzylorda Standard Time': 'QYZT',
'Qyzylorda Summer Time': 'QYZST',
'Réunion Time': 'RET',
'Rothera Time': 'ROTT',
'Sakhalin Standard Time': 'SAKT',
'Sakhalin Summer Time': 'SAKST',
'Samara Standard Time': 'SAMT',
'Samara Summer Time': 'SAMST',
'Samoa Daylight Time': 'SDT',
'Samoa Standard Time': 'SST',
'Seychelles Time': 'SCT',
'Singapore Standard Time': 'SGT',
'Solomon Islands Time': 'SBT',
'South Africa Standard Time': 'SAST',
'South Georgia Time': 'GST',
'St. Pierre & Miquelon Daylight Time': 'PMDT',
'St. Pierre & Miquelon Standard Time': 'PMST',
'Suriname Time': 'SRT',
'Syowa Time': 'SYOT',
'Tahiti Time': 'TAHT',
'Taipei Daylight Time': 'CDT',
'Taipei Standard Time': 'CST',
'Taiwan Daylight Time': 'CDT',
'Taiwan Standard Time': 'CST',
'Tajikistan Time': 'TJT',
'Timor-Leste Time': 'TLT',
'Tokelau Time': 'TKT',
'Tonga Standard Time': 'TOT',
'Tonga Summer Time': 'TOST',
'Türkiye Standard Time': 'TRT',
'Türkiye Summer Time': 'TRST',
'Turkmenistan Standard Time': 'TMT',
'Tuvalu Time': 'TVT',
'Ulaanbaatar Standard Time': 'ULAT',
'Ulaanbaatar Summer Time': 'ULAST',
'Uruguay Standard Time': 'UYT',
'Uruguay Summer Time': 'UYST',
'Uzbekistan Standard Time': 'UZT',
'Uzbekistan Summer Time': 'UZST',
'Vanuatu Standard Time': 'VUT',
'Vanuatu Summer Time': 'VUST',
'Venezuela Time': 'VET',
'Vladivostok Standard Time': 'VLAT',
'Vladivostok Summer Time': 'VLAST',
'Volgograd Standard Time': 'VOLT',
'Volgograd Summer Time': 'VOLST',
'Vostok Time': 'VOST',
'Wake Island Time': 'WAKT',
'Wallis & Futuna Time': 'WFT',
'West Africa Standard Time': 'WAT',
'West Africa Summer Time': 'WAST',
'West Africa Time': 'WAT',
'West Greenland Standard Time': 'WGT',
'West Greenland Summer Time': 'WGST',
'West Kazakhstan Time': 'AQTT',
'Western Argentina Standard Time': 'WART',
'Western Argentina Summer Time': 'WARST',
'Western European Standard Time': 'WET',
'Western European Summer Time': 'WEST',
'Western Indonesia Time': 'WIB',
'Yakutsk Standard Time': 'YAKT',
'Yakutsk Summer Time': 'YAKST',
'Yekaterinburg Standard Time': 'YEKT',
'Yekaterinburg Summer Time': 'YEKST',
'Yukon Time': 'YT'
};
================================================
FILE: tests/addDays.spec.ts
================================================
import { expect, test, describe, beforeAll } from 'vitest';
import { addDays } from '@/index.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
describe('Local Time', () => {
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One day after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 1, 10));
expect(addDays(date1, 1)).toEqual(date2);
});
test('Two days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 2, 10));
expect(addDays(date1, 2)).toEqual(date2);
});
test('Three days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 3, 10));
expect(addDays(date1, 3)).toEqual(date2);
});
test('One day after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 1, 11, 9));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 1, 11, 10));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 1, 11, 11));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 2, 8));
expect(addDays(date1, -1)).toEqual(date2);
});
test('One day before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 2, 9));
expect(addDays(date1, -1)).toEqual(date2);
});
test('One day before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 2, 10));
expect(addDays(date1, -1)).toEqual(date2);
});
test('One day after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 4, 9));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 4, 9));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 4, 10));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 9, 4, 8));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 9, 4, 9));
expect(addDays(date1, 1)).toEqual(date2);
});
test('One day after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 9, 4, 10));
expect(addDays(date1, 1)).toEqual(date2);
});
});
describe('UTC Time', () => {
beforeAll(() => (process.env.TZ = 'Asia/Tokyo'));
test('One day after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 1, 10));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('Two days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 2, 10));
expect(addDays(date1, 2, 'UTC')).toEqual(date2);
});
test('Three days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 3, 10));
expect(addDays(date1, 3, 'UTC')).toEqual(date2);
});
test('One day after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 1, 11, 9));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 1, 11, 10));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 1, 11, 11));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 2, 8));
expect(addDays(date1, -1, 'UTC')).toEqual(date2);
});
test('One day before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 2, 9));
expect(addDays(date1, -1, 'UTC')).toEqual(date2);
});
test('One day before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 2, 10));
expect(addDays(date1, -1, 'UTC')).toEqual(date2);
});
test('One day after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 4, 8));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 4, 9));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 4, 10));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 9, 4, 8));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 9, 4, 9));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
test('One day after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 9, 4, 10));
expect(addDays(date1, 1, 'UTC')).toEqual(date2);
});
});
describe('America/Los_Angeles', () => {
beforeAll(() => (process.env.TZ = 'Australia/Sydney'));
test('One day after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 1, 10));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('Two days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 2, 10));
expect(addDays(date1, 2, Los_Angeles)).toEqual(date2);
});
test('Three days after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 3, 10));
expect(addDays(date1, 3, Los_Angeles)).toEqual(date2);
});
test('One day after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 1, 11, 9));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 1, 11, 10));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 1, 11, 11));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 2, 8));
expect(addDays(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One day before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 2, 9));
expect(addDays(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One day before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 2, 10));
expect(addDays(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One day after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 4, 9));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 4, 9));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 4, 10));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 9, 4, 8));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 9, 4, 9));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One day after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 9, 4, 10));
expect(addDays(date1, 1, Los_Angeles)).toEqual(date2);
});
});
================================================
FILE: tests/addHours.spec.ts
================================================
import { expect, test, beforeAll } from 'vitest';
import { addHours } from '@/index.ts';
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One hour after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 0, 31, 11));
expect(addHours(date1, 1)).toEqual(date2);
});
test('Two hours after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 0, 31, 12));
expect(addHours(date1, 2)).toEqual(date2);
});
test('Three hours after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 0, 31, 13));
expect(addHours(date1, 3)).toEqual(date2);
});
test('One hour after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 1, 10, 10));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 1, 10, 11));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 1, 10, 12));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 3, 7));
expect(addHours(date1, -1)).toEqual(date2);
});
test('One hour before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 3, 8));
expect(addHours(date1, -1)).toEqual(date2);
});
test('One hour before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addHours(date1, -1)).toEqual(date2);
});
test('One hour after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 9));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 11));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 9, 3, 9));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 9, 3, 10));
expect(addHours(date1, 1)).toEqual(date2);
});
test('One hour after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 9, 3, 11));
expect(addHours(date1, 1)).toEqual(date2);
});
================================================
FILE: tests/addMilliseconds.spec.ts
================================================
import { expect, test, beforeAll } from 'vitest';
import { addMilliseconds } from '@/index.ts';
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One millisecond after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('Two milliseconds after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 2));
expect(addMilliseconds(date1, 2)).toEqual(date2);
});
test('Three milliseconds after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0, 3));
expect(addMilliseconds(date1, 3)).toEqual(date2);
});
test('One millisecond after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 9, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 7, 59, 59, 999));
expect(addMilliseconds(date1, -1)).toEqual(date2);
});
test('One millisecond before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 8, 59, 59, 999));
expect(addMilliseconds(date1, -1)).toEqual(date2);
});
test('One millisecond before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 9, 59, 59, 999));
expect(addMilliseconds(date1, -1)).toEqual(date2);
});
test('One millisecond after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 8, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 9, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 10, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 8, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 9, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
test('One millisecond after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10, 0, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 10, 0, 0, 1));
expect(addMilliseconds(date1, 1)).toEqual(date2);
});
================================================
FILE: tests/addMinutes.spec.ts
================================================
import { expect, test, beforeAll } from 'vitest';
import { addMinutes } from '@/index.ts';
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One minute after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('Two minutes after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 2));
expect(addMinutes(date1, 2)).toEqual(date2);
});
test('Three minutes after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 3));
expect(addMinutes(date1, 3)).toEqual(date2);
});
test('One minute after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 9, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 7, 59));
expect(addMinutes(date1, -1)).toEqual(date2);
});
test('One minute before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 8, 59));
expect(addMinutes(date1, -1)).toEqual(date2);
});
test('One minute before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 9, 59));
expect(addMinutes(date1, -1)).toEqual(date2);
});
test('One minute after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 8, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 9, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 10, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 8, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 9, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
test('One minute after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 10, 1));
expect(addMinutes(date1, 1)).toEqual(date2);
});
================================================
FILE: tests/addMonths.spec.ts
================================================
import { expect, test, describe, beforeAll } from 'vitest';
import { addMonths } from '@/index.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
describe('Local Time', () => {
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One month after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 29, 10));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('Two months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 2, 31, 9));
expect(addMonths(date1, 2)).toEqual(date2);
});
test('Three months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 3, 30, 9));
expect(addMonths(date1, 3)).toEqual(date2);
});
test('One month after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 2, 10, 9));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 2, 10, 10));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 2, 10, 10));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 7));
expect(addMonths(date1, -1)).toEqual(date2);
});
test('One month before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, -1)).toEqual(date2);
});
test('One month before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, -1)).toEqual(date2);
});
test('One month after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 3, 10));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, 1)).toEqual(date2);
});
test('One month after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 11));
expect(addMonths(date1, 1)).toEqual(date2);
});
});
describe('UTC Time', () => {
beforeAll(() => (process.env.TZ = 'Asia/Tokyo'));
test('One month after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 29, 10));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('Two months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 2, 31, 10));
expect(addMonths(date1, 2, 'UTC')).toEqual(date2);
});
test('Three months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 3, 30, 10));
expect(addMonths(date1, 3, 'UTC')).toEqual(date2);
});
test('One month after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 2, 10, 9));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 2, 10, 10));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 2, 10, 11));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, -1, 'UTC')).toEqual(date2);
});
test('One month before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 9));
expect(addMonths(date1, -1, 'UTC')).toEqual(date2);
});
test('One month before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, -1, 'UTC')).toEqual(date2);
});
test('One month after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 3, 8));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 3, 10));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 9));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
test('One month after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, 1, 'UTC')).toEqual(date2);
});
});
describe('America/Los_Angeles', () => {
beforeAll(() => (process.env.TZ = 'Australia/Sydney'));
test('One month after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 1, 29, 10));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('Two months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 2, 31, 9));
expect(addMonths(date1, 2, Los_Angeles)).toEqual(date2);
});
test('Three months after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2024, 3, 30, 9));
expect(addMonths(date1, 3, Los_Angeles)).toEqual(date2);
});
test('One month after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2024, 2, 10, 9));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2024, 2, 10, 10));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2024, 2, 10, 10));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 7));
expect(addMonths(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One month before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One month before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One month after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2024, 11, 3, 9));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2024, 11, 3, 10));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2024, 10, 3, 8));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2024, 10, 3, 10));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One month after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2024, 10, 3, 11));
expect(addMonths(date1, 1, Los_Angeles)).toEqual(date2);
});
});
================================================
FILE: tests/addSeconds.spec.ts
================================================
import { expect, test, beforeAll } from 'vitest';
import { addSeconds } from '@/index.ts';
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One second after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('Two seconds after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 2));
expect(addSeconds(date1, 2)).toEqual(date2);
});
test('Three seconds after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 0, 31, 10, 0, 3));
expect(addSeconds(date1, 3)).toEqual(date2);
});
test('One second after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 9, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 1, 10, 10, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 7, 59, 59));
expect(addSeconds(date1, -1)).toEqual(date2);
});
test('One second before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 8, 59, 59));
expect(addSeconds(date1, -1)).toEqual(date2);
});
test('One second before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 11, 3, 9, 59, 59));
expect(addSeconds(date1, -1)).toEqual(date2);
});
test('One second after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 8, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 9, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 10, 3, 10, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 8, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 9, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
test('One second after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10, 0, 0));
const date2 = new Date(Date.UTC(2024, 9, 3, 10, 0, 1));
expect(addSeconds(date1, 1)).toEqual(date2);
});
================================================
FILE: tests/addYears.spec.ts
================================================
import { expect, test, describe, beforeAll } from 'vitest';
import { addYears } from '@/index.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
describe('Local Time', () => {
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('One year after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2025, 0, 31, 10));
expect(addYears(date1, 1)).toEqual(date2);
});
test('Two years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2026, 0, 31, 10));
expect(addYears(date1, 2)).toEqual(date2);
});
test('Three years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2027, 0, 31, 10));
expect(addYears(date1, 3)).toEqual(date2);
});
test('One year after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2025, 1, 10, 9));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2025, 1, 10, 10));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2025, 1, 10, 11));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2023, 11, 3, 8));
expect(addYears(date1, -1)).toEqual(date2);
});
test('One year before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2023, 11, 3, 9));
expect(addYears(date1, -1)).toEqual(date2);
});
test('One year before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2023, 11, 3, 10));
expect(addYears(date1, -1)).toEqual(date2);
});
test('One year after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2025, 10, 3, 9));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2025, 10, 3, 9));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2025, 10, 3, 10));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2025, 9, 3, 8));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2025, 9, 3, 9));
expect(addYears(date1, 1)).toEqual(date2);
});
test('One year after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2025, 9, 3, 10));
expect(addYears(date1, 1)).toEqual(date2);
});
});
describe('UTC Time', () => {
beforeAll(() => (process.env.TZ = 'Asia/Tokyo'));
test('One year after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2025, 0, 31, 10));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('Two years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2026, 0, 31, 10));
expect(addYears(date1, 2, 'UTC')).toEqual(date2);
});
test('Three years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2027, 0, 31, 10));
expect(addYears(date1, 3, 'UTC')).toEqual(date2);
});
test('One year after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2025, 1, 10, 9));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2025, 1, 10, 10));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2025, 1, 10, 11));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2023, 11, 3, 8));
expect(addYears(date1, -1, 'UTC')).toEqual(date2);
});
test('One year before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2023, 11, 3, 9));
expect(addYears(date1, -1, 'UTC')).toEqual(date2);
});
test('One year before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2023, 11, 3, 10));
expect(addYears(date1, -1, 'UTC')).toEqual(date2);
});
test('One year after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2025, 10, 3, 8));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2025, 10, 3, 9));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2025, 10, 3, 10));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2025, 9, 3, 8));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2025, 9, 3, 9));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
test('One year after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2025, 9, 3, 10));
expect(addYears(date1, 1, 'UTC')).toEqual(date2);
});
});
describe('America/Los_Angeles', () => {
beforeAll(() => (process.env.TZ = 'Australia/Sydney'));
test('One year after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2025, 0, 31, 10));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('Two years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2026, 0, 31, 10));
expect(addYears(date1, 2, Los_Angeles)).toEqual(date2);
});
test('Three years after 2:00 AM on January 31, 2024', () => {
const date1 = new Date(Date.UTC(2024, 0, 31, 10));
const date2 = new Date(Date.UTC(2027, 0, 31, 10));
expect(addYears(date1, 3, Los_Angeles)).toEqual(date2);
});
test('One year after 1:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 9));
const date2 = new Date(Date.UTC(2025, 1, 10, 9));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 2:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 10));
const date2 = new Date(Date.UTC(2025, 1, 10, 10));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 3:00 AM on February 10, 2024', () => {
const date1 = new Date(Date.UTC(2024, 1, 10, 11));
const date2 = new Date(Date.UTC(2025, 1, 10, 11));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year before 1:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 8));
const date2 = new Date(Date.UTC(2023, 11, 3, 8));
expect(addYears(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One year before 2:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 9));
const date2 = new Date(Date.UTC(2023, 11, 3, 9));
expect(addYears(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One year before 3:00 AM on December 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 11, 3, 10));
const date2 = new Date(Date.UTC(2023, 11, 3, 10));
expect(addYears(date1, -1, Los_Angeles)).toEqual(date2);
});
test('One year after 1:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 8));
const date2 = new Date(Date.UTC(2025, 10, 3, 9));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 1:00 AM PST on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 9));
const date2 = new Date(Date.UTC(2025, 10, 3, 9));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 2:00 AM on November 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 10, 3, 10));
const date2 = new Date(Date.UTC(2025, 10, 3, 10));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 1:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 8));
const date2 = new Date(Date.UTC(2025, 9, 3, 8));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 2:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 9));
const date2 = new Date(Date.UTC(2025, 9, 3, 9));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
test('One year after 3:00 AM on October 3, 2024', () => {
const date1 = new Date(Date.UTC(2024, 9, 3, 10));
const date2 = new Date(Date.UTC(2025, 9, 3, 10));
expect(addYears(date1, 1, Los_Angeles)).toEqual(date2);
});
});
================================================
FILE: tests/compile.spec.ts
================================================
import { expect, test } from 'vitest';
import { compile } from '@/index.ts';
test('YYYY', () => {
const obj = ['YYYY', 'YYYY'];
expect(compile('YYYY')).toEqual(obj);
});
test('Y', () => {
const obj = ['Y', 'Y'];
expect(compile('Y')).toEqual(obj);
});
test('YYYY MMMM', () => {
const obj = ['YYYY MMMM', 'YYYY', ' ', 'MMMM'];
expect(compile('YYYY MMMM')).toEqual(obj);
});
test('YYYY MMM', () => {
const obj = ['YYYY MMM', 'YYYY', ' ', 'MMM'];
expect(compile('YYYY MMM')).toEqual(obj);
});
test('YYYY-MM', () => {
const obj = ['YYYY-MM', 'YYYY', '-', 'MM'];
expect(compile('YYYY-MM')).toEqual(obj);
});
test('YYYY-M', () => {
const obj = ['YYYY-M', 'YYYY', '-', 'M'];
expect(compile('YYYY-M')).toEqual(obj);
});
test('YYYY-MM-DD', () => {
const obj = ['YYYY-MM-DD', 'YYYY', '-', 'MM', '-', 'DD'];
expect(compile('YYYY-MM-DD')).toEqual(obj);
});
test('YYYY-M-D', () => {
const obj = ['YYYY-M-D', 'YYYY', '-', 'M', '-', 'D'];
expect(compile('YYYY-M-D')).toEqual(obj);
});
test('YYYY-MM-DD HH', () => {
const obj = ['YYYY-MM-DD HH', 'YYYY', '-', 'MM', '-', 'DD', ' ', 'HH'];
expect(compile('YYYY-MM-DD HH')).toEqual(obj);
});
test('YYYY-M-D H', () => {
const obj = ['YYYY-M-D H', 'YYYY', '-', 'M', '-', 'D', ' ', 'H'];
expect(compile('YYYY-M-D H')).toEqual(obj);
});
test('YYYY-M-D hh A', () => {
const obj = ['YYYY-M-D hh A', 'YYYY', '-', 'M', '-', 'D', ' ', 'hh', ' ', 'A'];
expect(compile('YYYY-M-D hh A')).toEqual(obj);
});
test('YYYY-M-D h A', () => {
const obj = ['YYYY-M-D h A', 'YYYY', '-', 'M', '-', 'D', ' ', 'h', ' ', 'A'];
expect(compile('YYYY-M-D h A')).toEqual(obj);
});
test('YYYY-MM-DD HH:mm', () => {
const obj = ['YYYY-MM-DD HH:mm', 'YYYY', '-', 'MM', '-', 'DD', ' ', 'HH', ':', 'mm'];
expect(compile('YYYY-MM-DD HH:mm')).toEqual(obj);
});
test('YYYY-M-D H:m', () => {
const obj = ['YYYY-M-D H:m', 'YYYY', '-', 'M', '-', 'D', ' ', 'H', ':', 'm'];
expect(compile('YYYY-M-D H:m')).toEqual(obj);
});
test('YYYY-MM-DD HH:mm:ss', () => {
const obj = ['YYYY-MM-DD HH:mm:ss', 'YYYY', '-', 'MM', '-', 'DD', ' ', 'HH', ':', 'mm', ':', 'ss'];
expect(compile('YYYY-MM-DD HH:mm:ss')).toEqual(obj);
});
test('YYYY-M-D H:m:s', () => {
const obj = ['YYYY-M-D H:m:s', 'YYYY', '-', 'M', '-', 'D', ' ', 'H', ':', 'm', ':', 's'];
expect(compile('YYYY-M-D H:m:s')).toEqual(obj);
});
test('YYYY-M-D H:m:s.SSS', () => {
const obj = ['YYYY-M-D H:m:s.SSS', 'YYYY', '-', 'M', '-', 'D', ' ', 'H', ':', 'm', ':', 's', '.', 'SSS'];
expect(compile('YYYY-M-D H:m:s.SSS')).toEqual(obj);
});
test('YYYY-M-D H:m:s.SS', () => {
const obj = ['YYYY-M-D H:m:s.SS', 'YYYY', '-', 'M', '-', 'D', ' ', 'H', ':', 'm', ':', 's', '.', 'SS'];
expect(compile('YYYY-M-D H:m:s.SS')).toEqual(obj);
});
test('YYYY-M-D H:m:s.S', () => {
const obj = ['YYYY-M-D H:m:s.S', 'YYYY', '-', 'M', '-', 'D', ' ', 'H', ':', 'm', ':', 's', '.', 'S'];
expect(compile('YYYY-M-D H:m:s.S')).toEqual(obj);
});
test('MMDDHHmmssSSS', () => {
const obj = ['MMDDHHmmssSSS', 'MM', 'DD', 'HH', 'mm', 'ss', 'SSS'];
expect(compile('MMDDHHmmssSSS')).toEqual(obj);
});
test('DDHHmmssSSS', () => {
const obj = ['DDHHmmssSSS', 'DD', 'HH', 'mm', 'ss', 'SSS'];
expect(compile('DDHHmmssSSS')).toEqual(obj);
});
test('HHmmssSSS', () => {
const obj = ['HHmmssSSS', 'HH', 'mm', 'ss', 'SSS'];
expect(compile('HHmmssSSS')).toEqual(obj);
});
test('mmssSSS', () => {
const obj = ['mmssSSS', 'mm', 'ss', 'SSS'];
expect(compile('mmssSSS')).toEqual(obj);
});
test('ssSSS', () => {
const obj = ['ssSSS', 'ss', 'SSS'];
expect(compile('ssSSS')).toEqual(obj);
});
test('SSS', () => {
const obj = ['SSS', 'SSS'];
expect(compile('SSS')).toEqual(obj);
});
test('foo', () => {
const obj = ['foo', 'f', 'oo'];
expect(compile('foo')).toEqual(obj);
});
test('bar', () => {
const obj = ['bar', 'b', 'a', 'r'];
expect(compile('bar')).toEqual(obj);
});
test('YYYYMMDD', () => {
const obj = ['YYYYMMDD', 'YYYY', 'MM', 'DD'];
expect(compile('YYYYMMDD')).toEqual(obj);
});
test('20150101235959', () => {
const obj = ['20150101235959', '2', '0', '1', '5', '0', '1', '0', '1', '2', '3', '5', '9', '5', '9'];
expect(compile('20150101235959')).toEqual(obj);
});
test('YYYY?M?D H?m?s?S', () => {
const obj = ['YYYY?M?D H?m?s?S', 'YYYY', '?', 'M', '?', 'D', ' ', 'H', '?', 'm', '?', 's', '?', 'S'];
expect(compile('YYYY?M?D H?m?s?S')).toEqual(obj);
});
test('[Y]YYYY[M]M[D]D[H]H[m]m[s]s[S]S', () => {
const obj = ['[Y]YYYY[M]M[D]D[H]H[m]m[s]s[S]S', '[Y]', 'YYYY', '[M]', 'M', '[D]', 'D', '[H]', 'H', '[m]', 'm', '[s]', 's', '[S]', 'S'];
expect(compile('[Y]YYYY[M]M[D]D[H]H[m]m[s]s[S]S')).toEqual(obj);
});
test('[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]', () => {
const obj = ['[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]', '[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]'];
expect(compile('[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]')).toEqual(obj);
});
test(' ', () => {
const obj = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '];
expect(compile(' ')).toEqual(obj);
});
test('[empty]', () => {
const obj = [''] as string[];
expect(compile('')).toEqual(obj);
});
test('\\[YYYY-MM-DD\\]', () => {
const obj = ['\\[YYYY-MM-DD\\]', '[', 'YYYY', '-', 'MM', '-', 'DD', ']'];
expect(compile('\\[YYYY-MM-DD\\]')).toEqual(obj);
});
================================================
FILE: tests/duration.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { Duration } from '@/index.ts';
describe('Duration', () => {
test('toDays', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toDays().value).toBe(365 + 0.123456 / 24 / 60 / 60 / 1000);
expect(new Duration(duration).toDays().toParts()).toEqual({ nanoseconds: 456, microseconds: 123, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: 365 });
});
test('toHours', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toHours().value).toBe(365 * 24 + 0.123456 / 60 / 60 / 1000);
expect(new Duration(duration).toHours().toParts()).toEqual({ nanoseconds: 456, microseconds: 123, milliseconds: 0, seconds: 0, minutes: 0, hours: 365 * 24 });
});
test('toMinutes', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toMinutes().value).toBe(365 * 24 * 60 + 0.123456 / 60 / 1000);
expect(new Duration(duration).toMinutes().toParts()).toEqual({ nanoseconds: 456, microseconds: 123, milliseconds: 0, seconds: 0, minutes: 365 * 24 * 60 });
});
test('toSeconds', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toSeconds().value).toBe(365 * 24 * 60 * 60 + 0.123456 / 1000);
expect(new Duration(duration).toSeconds().toParts()).toEqual({ nanoseconds: 456, microseconds: 123, milliseconds: 0, seconds: 365 * 24 * 60 * 60 });
});
test('toMilliseconds', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toMilliseconds().value).toBe(365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toMilliseconds().toParts()).toEqual({ nanoseconds: 456, microseconds: 123, milliseconds: 365 * 24 * 60 * 60 * 1000 });
});
test('toMicroseconds', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toMicroseconds().value).toBe((365 * 24 * 60 * 60 * 1000 + 0.123456) * 1000);
expect(new Duration(duration).toMicroseconds().toParts()).toEqual({ nanoseconds: 456, microseconds: 365 * 24 * 60 * 60 * 1000 * 1000 + 123 });
});
test('toNanoseconds', () => {
const duration = 365 * 24 * 60 * 60 * 1000 + 0.123456;
expect(new Duration(duration).toNanoseconds().value).toBe((365 * 24 * 60 * 60 * 1000 + 0.123456) * 1000000);
expect(new Duration(duration).toNanoseconds().toParts()).toEqual({ nanoseconds: 365 * 24 * 60 * 60 * 1000 * 1000 * 1000 + 123 * 1000 + 456 });
});
});
describe('Duration (minus)', () => {
test('toDays', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toDays().value).toBe(-1 * (365 + 0.123456 / 24 / 60 / 60 / 1000));
expect(new Duration(duration).toDays().toParts()).toEqual({ nanoseconds: -456, microseconds: -123, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: -365 });
});
test('toHours', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toHours().value).toBe(-1 * (365 * 24 + 0.123456 / 60 / 60 / 1000));
expect(new Duration(duration).toHours().toParts()).toEqual({ nanoseconds: -456, microseconds: -123, milliseconds: 0, seconds: 0, minutes: 0, hours: -365 * 24 });
});
test('toMinutes', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toMinutes().value).toBe(-1 * (365 * 24 * 60 + 0.123456 / 60 / 1000));
expect(new Duration(duration).toMinutes().toParts()).toEqual({ nanoseconds: -456, microseconds: -123, milliseconds: 0, seconds: 0, minutes: -365 * 24 * 60 });
});
test('toSeconds', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toSeconds().value).toBe(-1 * (365 * 24 * 60 * 60 + 0.123456 / 1000));
expect(new Duration(duration).toSeconds().toParts()).toEqual({ nanoseconds: -456, microseconds: -123, milliseconds: 0, seconds: -365 * 24 * 60 * 60 });
});
test('toMilliseconds', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toMilliseconds().value).toBe(-1 * (365 * 24 * 60 * 60 * 1000 + 0.123456));
expect(new Duration(duration).toMilliseconds().toParts()).toEqual({ nanoseconds: -456, microseconds: -123, milliseconds: -365 * 24 * 60 * 60 * 1000 });
});
test('toMicroseconds', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toMicroseconds().value).toBe((-1 * (365 * 24 * 60 * 60 * 1000 + 0.123456) * 1000));
expect(new Duration(duration).toMicroseconds().toParts()).toEqual({ nanoseconds: -456, microseconds: -365 * 24 * 60 * 60 * 1000 * 1000 - 123 });
});
test('toNanoseconds', () => {
const duration = -1 * (365 * 24 * 60 * 60 * 1000 + 0.123456);
expect(new Duration(duration).toNanoseconds().value).toBe((-1 * (365 * 24 * 60 * 60 * 1000 + 0.123456) * 1000000));
expect(new Duration(duration).toNanoseconds().toParts()).toEqual({ nanoseconds: -365 * 24 * 60 * 60 * 1000 * 1000 * 1000 - 123 * 1000 - 456 });
});
});
describe('Duration (Negative Zero)', () => {
test('toDays', () => {
const duration = -0;
expect(new Duration(duration).toDays().format('DDD HH mm ss SSS fff FFF')).toBe('-000 00 00 00 000 000 000');
expect(new Duration(duration).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: 0 });
});
test('toHours', () => {
const duration = -0;
expect(new Duration(duration).toHours().format('DDD HH mm ss SSS fff FFF')).toBe('DDD -00 00 00 000 000 000');
expect(new Duration(duration).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0 });
});
test('toMinutes', () => {
const duration = -0;
expect(new Duration(duration).toMinutes().format('DDD HH mm ss SSS fff FFF')).toBe('DDD HH -00 00 000 000 000');
expect(new Duration(duration).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0 });
});
test('toSeconds', () => {
const duration = -0;
expect(new Duration(duration).toSeconds().format('DDD HH mm ss SSS fff FFF')).toBe('DDD HH mm -00 000 000 000');
expect(new Duration(duration).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0 });
});
test('toMilliseconds', () => {
const duration = -0;
expect(new Duration(duration).toMilliseconds().format('DDD HH mm ss SSS fff FFF')).toBe('DDD HH mm ss -000 000 000');
expect(new Duration(duration).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0 });
});
test('toMicroseconds', () => {
const duration = -0;
expect(new Duration(duration).toMicroseconds().format('DDD HH mm ss SSS fff FFF')).toBe('DDD HH mm ss SSS -000 000');
expect(new Duration(duration).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0 });
});
test('toNanoseconds', () => {
const duration = -0;
expect(new Duration(duration).toNanoseconds().format('DDD HH mm ss SSS fff FFF')).toBe('DDD HH mm ss SSS fff -000');
expect(new Duration(duration).toNanoseconds().toParts()).toEqual({ nanoseconds: 0 });
});
});
================================================
FILE: tests/format.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { format, compile } from '@/index.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
import Tokyo from '@/timezones/Asia/Tokyo.ts';
import { Los_Angeles as los_angeles, Tokyo as tokyo } from '@/timezone.ts';
describe('YYYY', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0001', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'YYYY')).toBe('0001');
});
test('9999', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'YYYY')).toBe('9999');
});
});
describe('YY', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('01', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'YY')).toBe('01');
});
test('99', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'YY')).toBe('99');
});
});
describe('Y', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('1', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'Y')).toBe('1');
});
test('9999', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'Y')).toBe('9999');
});
});
describe('MMMM', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('January', () => {
const now = new Date(0, 1 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('January');
});
test('February', () => {
const now = new Date(0, 2 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('February');
});
test('March', () => {
const now = new Date(0, 3 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('March');
});
test('April', () => {
const now = new Date(0, 4 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('April');
});
test('May', () => {
const now = new Date(0, 5 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('May');
});
test('June', () => {
const now = new Date(0, 6 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('June');
});
test('July', () => {
const now = new Date(0, 7 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('July');
});
test('August', () => {
const now = new Date(0, 8 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('August');
});
test('September', () => {
const now = new Date(0, 9 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('September');
});
test('October', () => {
const now = new Date(0, 10 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('October');
});
test('November', () => {
const now = new Date(0, 11 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('November');
});
test('December', () => {
const now = new Date(0, 12 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMMM')).toBe('December');
});
});
describe('MMM', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('Jan', () => {
const now = new Date(0, 1 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Jan');
});
test('Feb', () => {
const now = new Date(0, 2 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Feb');
});
test('Mar', () => {
const now = new Date(0, 3 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Mar');
});
test('Apr', () => {
const now = new Date(0, 4 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Apr');
});
test('May', () => {
const now = new Date(0, 5 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('May');
});
test('Jun', () => {
const now = new Date(0, 6 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Jun');
});
test('Jul', () => {
const now = new Date(0, 7 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Jul');
});
test('Aug', () => {
const now = new Date(0, 8 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Aug');
});
test('Sep', () => {
const now = new Date(0, 9 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Sep');
});
test('Oct', () => {
const now = new Date(0, 10 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Oct');
});
test('Nov', () => {
const now = new Date(0, 11 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Nov');
});
test('Dec', () => {
const now = new Date(0, 12 - 1, 1, 0, 0, 0, 0);
expect(format(now, 'MMM')).toBe('Dec');
});
});
describe('MM', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('01', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'MM')).toBe('01');
});
test('12', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'MM')).toBe('12');
});
});
describe('M', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('1', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'M')).toBe('1');
});
test('12', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'M')).toBe('12');
});
});
describe('DD', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('01', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'DD')).toBe('01');
});
test('31', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'DD')).toBe('31');
});
});
describe('D', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('1', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'D')).toBe('1');
});
test('31', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'D')).toBe('31');
});
});
describe('dddd', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('Sunday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 0, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Sunday');
});
test('Monday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Monday');
});
test('Tuesday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 2, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Tuesday');
});
test('Wednesday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 3, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Wednesday');
});
test('Thursday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 4, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Thursday');
});
test('Friday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 5, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Friday');
});
test('Saturday', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 6, 0, 0, 0, 0);
expect(format(now, 'dddd')).toBe('Saturday');
});
});
describe('ddd', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('Sun', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 0, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Sun');
});
test('Mon', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Mon');
});
test('Tue', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 2, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Tue');
});
test('Wed', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 3, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Wed');
});
test('Thu', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 4, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Thu');
});
test('Fri', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 5, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Fri');
});
test('Sat', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 6, 0, 0, 0, 0);
expect(format(now, 'ddd')).toBe('Sat');
});
});
describe('dd', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('Su', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 0, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Su');
});
test('Mo', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Mo');
});
test('Tu', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 2, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Tu');
});
test('We', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 3, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('We');
});
test('Th', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 4, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Th');
});
test('Fr', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 5, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Fr');
});
test('Sa', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 6, 0, 0, 0, 0);
expect(format(now, 'dd')).toBe('Sa');
});
});
describe('HH', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('00', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'HH', { hour24: 'h23' })).toBe('00');
});
test('23', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 23, 0, 0, 0);
expect(format(now, 'HH', { hour24: 'h23' })).toBe('23');
});
test('24', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'HH', { hour24: 'h24' })).toBe('24');
});
});
describe('H', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'H', { hour24: 'h23' })).toBe('0');
});
test('23', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 23, 0, 0, 0);
expect(format(now, 'H', { hour24: 'h23' })).toBe('23');
});
test('24', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'H', { hour24: 'h24' })).toBe('24');
});
});
describe('hh', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('00', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'hh', { hour12: 'h11' })).toBe('00');
});
test('11', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'hh', { hour12: 'h12' })).toBe('11');
});
test('12', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'hh', { hour12: 'h12' })).toBe('12');
});
});
describe('h', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'h', { hour12: 'h11' })).toBe('0');
});
test('11', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'h', { hour12: 'h12' })).toBe('11');
});
test('12', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'h', { hour12: 'h12' })).toBe('12');
});
});
describe('AA', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('A.M.', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'AA')).toBe('A.M.');
});
test('P.M.', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'AA')).toBe('P.M.');
});
});
describe('A', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('AM', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'A')).toBe('AM');
});
test('PM', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'A')).toBe('PM');
});
});
describe('aa', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('a.m.', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'aa')).toBe('a.m.');
});
test('p.m.', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'aa')).toBe('p.m.');
});
});
describe('a', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('am', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'a')).toBe('am');
});
test('pm', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'a')).toBe('pm');
});
});
describe('mm', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('00', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'mm')).toBe('00');
});
test('59', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'mm')).toBe('59');
});
});
describe('m', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'm')).toBe('0');
});
test('59', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'm')).toBe('59');
});
});
describe('ss', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('00', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'ss')).toBe('00');
});
test('59', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'ss')).toBe('59');
});
});
describe('s', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 's')).toBe('0');
});
test('59', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 's')).toBe('59');
});
});
describe('SSS', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('000', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'SSS')).toBe('000');
});
test('456', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 456);
expect(format(now, 'SSS')).toBe('456');
});
test('999', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'SSS')).toBe('999');
});
});
describe('SS', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('00', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'SS')).toBe('00');
});
test('45', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 456);
expect(format(now, 'SS')).toBe('45');
});
test('99', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'SS')).toBe('99');
});
});
describe('S', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('0', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 0);
expect(format(now, 'S')).toBe('0');
});
test('4', () => {
const now = new Date(0, 0 - (1900 - 1) * 12, 1, 0, 0, 0, 456);
expect(format(now, 'S')).toBe('4');
});
test('9', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'S')).toBe('9');
});
});
describe('ZZ', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('-08:00', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'ZZ', { timeZone: Los_Angeles })).toBe('-08:00');
});
test('+00:00', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'ZZ', { timeZone: 'UTC' })).toBe('+00:00');
});
test('+09:00', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'ZZ', { timeZone: Tokyo })).toBe('+09:00');
});
});
describe('Z', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('-0800', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'Z', { timeZone: Los_Angeles })).toBe('-0800');
});
test('+0000', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'Z', { timeZone: 'UTC' })).toBe('+0000');
});
test('+0900', () => {
const now = new Date(9999, 12 - 1, 31, 23, 59, 59, 999);
expect(format(now, 'Z', { timeZone: Tokyo })).toBe('+0900');
});
});
describe('comments', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('dddd, MMMM D, YYYY h A', () => {
const now = new Date(2000, 1 - 1, 1, 0, 0, 0);
expect(format(now, '[dddd, MMMM D, YYYY h A]')).toBe('dddd, MMMM D, YYYY h A');
});
test('dddd, January D, 2000 h AM', () => {
const now = new Date(2000, 1 - 1, 1, 0, 0, 0);
expect(format(now, '[dddd], MMMM [D], YYYY [h] A')).toBe('dddd, January D, 2000 h AM');
});
test('[dddd], MMMM [D], YYYY [h] A', () => {
const now = new Date(2000, 1 - 1, 1, 0, 0, 0);
expect(format(now, '[[dddd], MMMM [D], YYYY [h] A]')).toBe('[dddd], MMMM [D], YYYY [h] A');
});
test('dddd, January [D], YYYY 12 A', () => {
const now = new Date(2000, 1 - 1, 1, 0, 0, 0);
expect(format(now, '[dddd], MMMM [[D], YYYY] h [A]')).toBe('dddd, January [D], YYYY 12 A');
});
});
describe('compiledObj', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('"ddd MMM DD YYYY HH:mm:ss" equals to "Thu Jan 01 2015 12:34:56"', () => {
const now = new Date(2015, 0, 1, 12, 34, 56, 789);
expect(format(now, compile('ddd MMM DD YYYY HH:mm:ss'))).toBe('Thu Jan 01 2015 12:34:56');
});
test('"YYYY/MM/DD HH:mm:ss.SSS" equals to "1900/01/01 00:00:00.000"', () => {
const now = new Date(0, 0, 1);
expect(format(now, compile('YYYY/MM/DD HH:mm:ss.SSS'))).toBe('1900/01/01 00:00:00.000');
});
test('"YY/MM/DD HH:mm:ss.SSS" equals to "00/01/01 00:00:00.000"', () => {
const now = new Date(0, 0, 1);
expect(format(now, compile('YY/MM/DD HH:mm:ss.SSS'))).toBe('00/01/01 00:00:00.000');
});
test('"Y/M/D H:m:s.SSS" equals to "999/1/1 0:0:0.000"', () => {
const now = new Date(999, 0, 1);
expect(format(now, compile('Y/M/D H:m:s.SSS'))).toBe('999/1/1 0:0:0.000');
});
test('"dddd, MMMM D, YYYY h A" equals to "Saturday, January 1, 2000 10 AM"', () => {
const now = new Date(2000, 0, 1, 10, 0, 0);
expect(format(now, compile('dddd, MMMM D, YYYY h A'))).toBe('Saturday, January 1, 2000 10 AM');
});
test('"[dddd, MMMM D, YYYY h A]" equals to "dddd, MMMM D, YYYY h A"', () => {
const now = new Date(2000, 0, 1, 10, 0, 0);
expect(format(now, compile('[dddd, MMMM D, YYYY h A]'))).toBe('dddd, MMMM D, YYYY h A');
});
test('"[dddd], MMMM [D], YYYY [h] A" equals to "dddd, January D, 2000 h AM"', () => {
const now = new Date(2000, 0, 1, 10, 0, 0);
expect(format(now, compile('[dddd], MMMM [D], YYYY [h] A'))).toBe('dddd, January D, 2000 h AM');
});
test('"[[dddd], MMMM [D], YYYY [h] A]" equals to "[dddd], MMMM [D], YYYY [h] A"', () => {
const now = new Date(2000, 0, 1, 10, 0, 0);
expect(format(now, compile('[[dddd], MMMM [D], YYYY [h] A]'))).toBe('[dddd], MMMM [D], YYYY [h] A');
});
test('"[dddd], MMMM [[D], YYYY] [h] A" equals to "dddd, January [D], YYYY h AM"', () => {
const now = new Date(2000, 0, 1, 10, 0, 0);
expect(format(now, compile('[dddd], MMMM [[D], YYYY] [h] A'))).toBe('dddd, January [D], YYYY h AM');
});
});
describe('options', () => {
beforeAll(() => (process.env.TZ = 'UTC'));
test('hour12: h11', () => {
expect(format(new Date(2000, 1 - 1, 1, 0, 0, 0), 'h A', { hour12: 'h11' })).toBe('0 AM');
expect(format(new Date(2000, 1 - 1, 1, 11, 0, 0), 'h A', { hour12: 'h11' })).toBe('11 AM');
expect(format(new Date(2000, 1 - 1, 1, 12, 0, 0), 'h A', { hour12: 'h11' })).toBe('0 PM');
expect(format(new Date(2000, 1 - 1, 1, 23, 0, 0), 'h A', { hour12: 'h11' })).toBe('11 PM');
});
test('hour12: h12', () => {
expect(format(new Date(2000, 1 - 1, 1, 0, 0, 0), 'h A', { hour12: 'h12' })).toBe('12 AM');
expect(format(new Date(2000, 1 - 1, 1, 11, 0, 0), 'h A', { hour12: 'h12' })).toBe('11 AM');
expect(format(new Date(2000, 1 - 1, 1, 12, 0, 0), 'h A', { hour12: 'h12' })).toBe('12 PM');
expect(format(new Date(2000, 1 - 1, 1, 23, 0, 0), 'h A', { hour12: 'h12' })).toBe('11 PM');
});
test('hour24: h23', () => {
expect(format(new Date(2000, 1 - 1, 1, 0, 0, 0), 'H', { hour24: 'h23' })).toBe('0');
expect(format(new Date(2000, 1 - 1, 1, 11, 0, 0), 'H', { hour24: 'h23' })).toBe('11');
expect(format(new Date(2000, 1 - 1, 1, 12, 0, 0), 'H', { hour24: 'h23' })).toBe('12');
expect(format(new Date(2000, 1 - 1, 1, 23, 0, 0), 'H', { hour24: 'h23' })).toBe('23');
});
test('hour24: h24', () => {
expect(format(new Date(2000, 1 - 1, 1, 0, 0, 0), 'H', { hour24: 'h24' })).toBe('24');
expect(format(new Date(2000, 1 - 1, 1, 11, 0, 0), 'H', { hour24: 'h24' })).toBe('11');
expect(format(new Date(2000, 1 - 1, 1, 12, 0, 0), 'H', { hour24: 'h24' })).toBe('12');
expect(format(new Date(2000, 1 - 1, 1, 23, 0, 0), 'H', { hour24: 'h24' })).toBe('23');
});
test('calendar: buddhist', () => {
expect(format(new Date(1, 0 - (1900 + 543) * 12, 1, 0, 0, 0), 'YYYY-MM-DD HH', { calendar: 'buddhist' })).toBe('0001-01-01 00');
expect(format(new Date(1, 0 - 1900 * 12, 1, 0, 0, 0), 'YYYY-MM-DD HH', { calendar: 'buddhist' })).toBe('0544-01-01 00');
expect(format(new Date(9456, 1 - 1, 1, 0, 0, 0), 'YYYY-MM-DD HH', { calendar: 'buddhist' })).toBe('9999-01-01 00');
expect(format(new Date(1, 0 - (1900 + 543) * 12, 1, 0, 0, 0), 'YY-MM-DD HH', { calendar: 'buddhist' })).toBe('01-01-01 00');
expect(format(new Date(1, 0 - 1900 * 12, 1, 0, 0, 0), 'YY-MM-DD HH', { calendar: 'buddhist' })).toBe('44-01-01 00');
expect(format(new Date(9456, 1 - 1, 1, 0, 0, 0), 'YY-MM-DD HH', { calendar: 'buddhist' })).toBe('99-01-01 00');
expect(format(new Date(1, 0 - (1900 + 543) * 12, 1, 0, 0, 0), 'Y-MM-DD HH', { calendar: 'buddhist' })).toBe('1-01-01 00');
expect(format(new Date(1, 0 - 1900 * 12, 1, 0, 0, 0), 'Y-MM-DD HH', { calendar: 'buddhist' })).toBe('544-01-01 00');
expect(format(new Date(9456, 1 - 1, 1, 0, 0, 0), 'Y-MM-DD HH', { calendar: 'buddhist' })).toBe('9999-01-01 00');
});
test('timeZone', () => {
const now = new Date(2025, 1 - 1, 1, 0);
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: Los_Angeles })).toBe('2024-12-31 16:00:00.000 -0800 Tu');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: los_angeles })).toBe('2024-12-31 16:00:00.000 -0800 Tu');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: 'America/Los_Angeles' })).toBe('2024-12-31 16:00:00.000 -0800 Tu');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: Tokyo })).toBe('2025-01-01 09:00:00.000 +0900 We');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: tokyo })).toBe('2025-01-01 09:00:00.000 +0900 We');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: 'Asia/Tokyo' })).toBe('2025-01-01 09:00:00.000 +0900 We');
expect(format(now, 'YYYY-MM-DD HH:mm:ss.SSS Z dd', { timeZone: 'UTC' })).toBe('2025-01-01 00:00:00.000 +0000 We');
});
});
describe('timeZone DST', () => {
beforeAll(() => (process.env.TZ = 'America/Los_Angeles'));
test('before DST', () => {
const dateObj = new Date(2021, 2, 14, 1, 59, 59, 999);
const dateString = '2021-03-14 01:59:59.999 UTC-0800';
expect(format(dateObj, 'YYYY-MM-DD HH:mm:ss.SSS [UTC]Z')).toBe(dateString);
});
test('start of DST', () => {
const dateObj = new Date(2021, 2, 14, 2, 0, 0, 0);
const dateString = '2021-03-14 03:00:00.000 UTC-0700';
expect(format(dateObj, 'YYYY-MM-DD HH:mm:ss.SSS [UTC]Z')).toBe(dateString);
});
test('before of PST', () => {
const dateObj = new Date(2021, 10, 7, 1, 59, 59, 999);
const dateString = '2021-11-07 01:59:59.999 UTC-0700';
expect(format(dateObj, 'YYYY-MM-DD HH:mm:ss.SSS [UTC]Z')).toBe(dateString);
});
test('end of DST', () => {
const dateObj = new Date(2021, 10, 7, 2, 0, 0, 0);
const dateString = '2021-11-07 02:00:00.000 UTC-0800';
expect(format(dateObj, 'YYYY-MM-DD HH:mm:ss.SSS [UTC]Z')).toBe(dateString);
});
test('after of DST', () => {
const dateObj = new Date(2021, 10, 7, 3, 0, 0, 0);
const dateString = '2021-11-07 03:00:00.000 UTC-0800';
expect(format(dateObj, 'YYYY-MM-DD HH:mm:ss.SSS [UTC]Z')).toBe(dateString);
});
});
================================================
FILE: tests/isValid.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { isValid, compile, format } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
test('2014-12-31 12:34:56.789 is valid', () => {
expect(isValid('20141231123456789', 'YYYYMMDDHHmmssSSS')).toBe(true);
expect(isValid('20141231123456789', compile('YYYYMMDDHHmmssSSS'))).toBe(true);
});
test('2012-2-29 is valid', () => {
expect(isValid('2012-2-29', 'YYYY-M-D')).toBe(true);
expect(isValid('2012-2-29', compile('YYYY-M-D'))).toBe(true);
});
test('2100-2-29 is invalid', () => {
expect(isValid('2100-2-29', 'YYYY-M-D')).toBe(false);
expect(isValid('2100-2-29', compile('YYYY-M-D'))).toBe(false);
});
test('2000-2-29 is valid', () => {
expect(isValid('2000-2-29', 'YYYY-M-D')).toBe(true);
expect(isValid('2000-2-29', compile('YYYY-M-D'))).toBe(true);
});
test('2014-2-29 is invalid', () => {
expect(isValid('2014-2-29', 'YYYY-M-D')).toBe(false);
expect(isValid('2014-2-29', compile('YYYY-M-D'))).toBe(false);
});
test('2014-2-28 is valid', () => {
expect(isValid('2014-2-28', 'YYYY-M-D')).toBe(true);
expect(isValid('2014-2-28', compile('YYYY-M-D'))).toBe(true);
});
test('2014-4-31 is invalid', () => {
expect(isValid('2014-4-31', 'YYYY-M-D')).toBe(false);
expect(isValid('2014-4-31', compile('YYYY-M-D'))).toBe(false);
});
test('24:00 is invalid', () => {
expect(isValid('2014-4-30 24:00', 'YYYY-M-D H:m')).toBe(false);
expect(isValid('2014-4-30 24:00', compile('YYYY-M-D H:m'))).toBe(false);
});
test('13:00 PM is invalid', () => {
expect(isValid('2014-4-30 13:00 PM', 'YYYY-M-D h:m A')).toBe(false);
expect(isValid('2014-4-30 13:00 PM', compile('YYYY-M-D h:m A'))).toBe(false);
});
test('23:60 is invalid', () => {
expect(isValid('2014-4-30 23:60', 'YYYY-M-D H:m')).toBe(false);
expect(isValid('2014-4-30 23:60', compile('YYYY-M-D H:m'))).toBe(false);
});
test('23:59:60 is invalid', () => {
expect(isValid('2014-4-30 23:59:60', 'YYYY-M-D H:m:s')).toBe(false);
expect(isValid('2014-4-30 23:59:60', compile('YYYY-M-D H:m:s'))).toBe(false);
});
test('All zero is invalid', () => {
expect(isValid('00000000000000000', 'YYYYMMDDHHmmssSSS')).toBe(false);
expect(isValid('00000000000000000', compile('YYYYMMDDHHmmssSSS'))).toBe(false);
});
test('All nine is invalid', () => {
expect(isValid('99999999999999999', 'YYYYMMDDHHmmssSSS')).toBe(false);
expect(isValid('99999999999999999', compile('YYYYMMDDHHmmssSSS'))).toBe(false);
});
test('foo is invalid', () => {
expect(isValid('20150101235959', 'foo')).toBe(false);
expect(isValid('20150101235959', compile('foo'))).toBe(false);
});
test('bar is invalid', () => {
expect(isValid('20150101235959', 'bar')).toBe(false);
expect(isValid('20150101235959', compile('bar'))).toBe(false);
});
test('YYYYMMDD is invalid', () => {
expect(isValid('20150101235959', 'YYYYMMDD')).toBe(false);
expect(isValid('20150101235959', compile('YYYYMMDD'))).toBe(false);
});
test('20150101235959 is invalid', () => {
expect(isValid('20150101235959', '20150101235959')).toBe(false);
expect(isValid('20150101235959', compile('20150101235959'))).toBe(false);
});
describe('options', () => {
test('hour12: h11', () => {
expect(isValid('2000-01-01 00:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(true);
expect(isValid('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(true);
expect(isValid('2000-01-01 00:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(true);
expect(isValid('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(true);
expect(isValid('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(false);
expect(isValid('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toBe(false);
});
test('hour12: h12', () => {
expect(isValid('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(true);
expect(isValid('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(true);
expect(isValid('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(true);
expect(isValid('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(true);
expect(isValid('2000-01-01 00:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(false);
expect(isValid('2000-01-01 00:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toBe(false);
});
test('hour24: h23', () => {
expect(isValid('2000-01-01 00:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toBe(true);
expect(isValid('2000-01-01 01:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toBe(true);
expect(isValid('2000-01-01 23:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toBe(true);
expect(isValid('2000-01-01 24:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toBe(false);
});
test('hour24: h24', () => {
expect(isValid('2000-01-01 00:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toBe(false);
expect(isValid('2000-01-01 01:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toBe(true);
expect(isValid('2000-01-01 23:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toBe(true);
expect(isValid('2000-01-01 24:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toBe(true);
});
test('ignoreCase: true', () => {
expect(isValid('2025 May 4 Sunday 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toBe(true);
expect(isValid('2025 may 4 sunday 11 am', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toBe(true);
expect(isValid('2025 MAY 4 SUNDAY 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toBe(true);
});
test('calendar: buddhist', () => {
expect(isValid('9999-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toBe(true);
expect(isValid('0544-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toBe(true);
expect(isValid('0543-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toBe(false);
});
test('timeZone: min', () => {
process.env.TZ = 'America/Metlakatla';
const dateString = format(new Date(-3225223728000), 'YYYY-MM-DD[T]HH:mm:ss ZZ');
expect(isValid(dateString, 'YYYY-MM-DD[T]HH:mm:ss ZZ')).toBe(true);
});
test('timeZone: max', () => {
process.env.TZ = 'Asia/Manila';
const dateString = format(new Date(-3944621033000), 'YYYY-MM-DD[T]HH:mm:ss ZZ');
expect(isValid(dateString, 'YYYY-MM-DD[T]HH:mm:ss ZZ')).toBe(true);
});
test('defaultDate: year for leap day validation', () => {
expect(isValid('02-29', 'MM-DD', { defaultDate: { Y: 2024 } })).toBe(true);
expect(isValid('02-29', 'MM-DD', { defaultDate: { Y: 2023 } })).toBe(false);
expect(isValid('02-29', 'MM-DD')).toBe(false); // defaults to 1970 (non-leap year)
});
test('defaultDate: month for day range validation', () => {
expect(isValid('29', 'D', { defaultDate: { Y: 2024, M: 2 } })).toBe(true);
expect(isValid('29', 'D', { defaultDate: { Y: 2023, M: 2 } })).toBe(false);
expect(isValid('31', 'D', { defaultDate: { Y: 2024, M: 4 } })).toBe(false); // April has 30 days
});
test('defaultDate: timezone offset (Z) validation', () => {
expect(isValid('12:00', 'HH:mm', { defaultDate: { Y: 2024, M: 1, D: 1, Z: 0 } })).toBe(true);
expect(isValid('12:00', 'HH:mm', { defaultDate: { Y: 2024, M: 1, D: 1, Z: -999 } })).toBe(false);
});
test('defaultDate: H out of range', () => {
expect(isValid('30', 'mm', { defaultDate: { Y: 2024, M: 1, D: 1, H: 25 } })).toBe(false);
expect(isValid('30', 'mm', { defaultDate: { Y: 2024, M: 1, D: 1, H: 0 } })).toBe(true);
});
test('defaultDate: H not in format with hour24: h24 (regression)', () => {
expect(isValid('30', 'mm', { defaultDate: { Y: 2024, M: 1, D: 1 }, hour24: 'h24' })).toBe(true);
});
});
================================================
FILE: tests/locales/ar.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ar.ts';
const locale = {
MMMM: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
MMM: ['يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو', 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'],
dddd: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
ddd: ['الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة', 'السبت'],
dd: ['أح', 'اث', 'ثل', 'أر', 'خم', 'جم', 'سب'],
A: ['ص', 'م'],
AA: ['ص', 'م'],
a: ['ص', 'م'],
aa: ['ص', 'م']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/az.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/az.ts';
const locale = {
MMMM: ['yanvar', 'fevral', 'mart', 'aprel', 'may', 'iyun', 'iyul', 'avqust', 'sentyabr', 'oktyabr', 'noyabr', 'dekabr'],
MMM: ['yan', 'fev', 'mar', 'apr', 'may', 'iyn', 'iyl', 'avq', 'sen', 'okt', 'noy', 'dek'],
dddd: ['bazar', 'bazar ertəsi', 'çərşənbə axşamı', 'çərşənbə', 'cümə axşamı', 'cümə', 'şənbə'],
ddd: ['B.', 'B.E.', 'Ç.A.', 'Ç.', 'C.A.', 'C.', 'Ş.'],
dd: ['7', '1', '2', '3', '4', '5', '6'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/bn.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/bn.ts';
const locale = {
MMMM: ['জানুয়ারী', 'ফেব্রুয়ারী', 'মার্চ', 'এপ্রিল', 'মে', 'জুন', 'জুলাই', 'আগস্ট', 'সেপ্টেম্বর', 'অক্টোবর', 'নভেম্বর', 'ডিসেম্বর'],
MMM: ['জানু', 'ফেব', 'মার্চ', 'এপ্রি', 'মে', 'জুন', 'জুল', 'আগ', 'সেপ', 'অক্টো', 'নভে', 'ডিসে'],
dddd: ['রবিবার', 'সোমবার', 'মঙ্গলবার', 'বুধবার', 'বৃহস্পতিবার', 'শুক্রবার', 'শনিবার'],
ddd: ['রবি', 'সোম', 'মঙ্গল', 'বুধ', 'বৃহস্পতি', 'শুক্র', 'শনি'],
dd: ['র', 'সো', 'ম', 'বু', 'বৃ', 'শু', 'শ'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/cs.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/cs.ts';
const locale = {
MMMM: [
['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
['ledna', 'února', 'března', 'dubna', 'května', 'června', 'července', 'srpna', 'září', 'října', 'listopadu', 'prosince']
],
MMM: [
['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
['led', 'úno', 'bře', 'dub', 'kvě', 'čvn', 'čvc', 'srp', 'zář', 'říj', 'lis', 'pro']
],
dddd: ['neděle', 'pondělí', 'úterý', 'středa', 'čtvrtek', 'pátek', 'sobota'],
ddd: ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so'],
dd: ['N', 'P', 'Ú', 'S', 'Č', 'P', 'S'],
A: ['dop.', 'odp.'],
AA: ['dop.', 'odp.'],
a: ['dop.', 'odp.'],
aa: ['dop.', 'odp.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo })).toEqual(d);
});
});
test('MMM D ignoreCase', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/da.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/da.ts';
const locale = {
MMMM: ['januar', 'februar', 'marts', 'april', 'maj', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'december'],
MMM: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun.', 'jul.', 'aug.', 'sep.', 'okt.', 'nov.', 'dec.'],
dddd: ['søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag'],
ddd: ['søn.', 'man.', 'tirs.', 'ons.', 'tors.', 'fre.', 'lør.'],
dd: ['sø', 'ma', 'ti', 'on', 'to', 'fr', 'lø'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/de.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/de.ts';
const locale = {
MMMM: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
MMM: ['Jan.', 'Feb.', 'März', 'Apr.', 'Mai', 'Juni', 'Juli', 'Aug.', 'Sept.', 'Okt.', 'Nov.', 'Dez.'],
dddd: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
ddd: ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.'],
dd: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/el.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/el.ts';
const locale = {
MMMM: [
['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'],
['Ιανουαρίου', 'Φεβρουαρίου', 'Μαρτίου', 'Απριλίου', 'Μαΐου', 'Ιουνίου', 'Ιουλίου', 'Αυγούστου', 'Σεπτεμβρίου', 'Οκτωβρίου', 'Νοεμβρίου', 'Δεκεμβρίου']
],
MMM: ['Ιαν', 'Φεβ', 'Μαρ', 'Απρ', 'Μαΐ', 'Ιουν', 'Ιουλ', 'Αυγ', 'Σεπ', 'Οκτ', 'Νοε', 'Δεκ'],
dddd: ['Κυριακή', 'Δευτέρα', 'Τρίτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σάββατο'],
ddd: ['Κυρ', 'Δευ', 'Τρί', 'Τετ', 'Πέμ', 'Παρ', 'Σάβ'],
dd: ['Κυ', 'Δε', 'Τρ', 'Τε', 'Πε', 'Πα', 'Σα'],
A: ['ΠΜ', 'ΜΜ'],
AA: ['Π.Μ.', 'Μ.Μ.'],
a: ['πμ', 'μμ'],
aa: ['π.μ.', 'μ.μ.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/en.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/en.ts';
const locale = {
MMMM: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
MMM: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
dddd: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
ddd: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
dd: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/es.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/es.ts';
const locale = {
MMMM: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
MMM: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sept', 'oct', 'nov', 'dic'],
dddd: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
ddd: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
dd: ['do', 'lu', 'ma', 'mi', 'ju', 'vi', 'sá'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/fa.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/fa.ts';
const locale = {
MMMM: ['دی', 'بهمن', 'اسفند', 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر'],
MMM: ['دی', 'بهمن', 'اسفند', 'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر'],
dddd: ['یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'],
ddd: ['یکشنبه', 'دوشنبه', 'سهشنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'],
dd: ['ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش'],
A: ['قبلازظهر', 'بعدازظهر'],
AA: ['قبلازظهر', 'بعدازظهر'],
a: ['قبلازظهر', 'بعدازظهر'],
aa: ['قبلازظهر', 'بعدازظهر']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/fi.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/fi.ts';
const locale = {
MMMM: [
['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
['tammikuuta', 'helmikuuta', 'maaliskuuta', 'huhtikuuta', 'toukokuuta', 'kesäkuuta', 'heinäkuuta', 'elokuuta', 'syyskuuta', 'lokakuuta', 'marraskuuta', 'joulukuuta']
],
MMM: [
['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu'],
['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
],
dddd: ['sunnuntai', 'maanantaina', 'tiistaina', 'keskiviikkona', 'torstaina', 'perjantaina', 'lauantaina'],
ddd: ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la'],
dd: ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la'],
A: ['ap.', 'ip.'],
AA: ['ap.', 'ip.'],
a: ['ap.', 'ip.'],
aa: ['ap.', 'ip.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo })).toEqual(d);
});
});
test('MMM D ignoreCase', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/fr.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/fr.ts';
const locale = {
MMMM: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
MMM: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'],
dddd: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
ddd: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
dd: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/he.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/he.ts';
const locale = {
MMMM: ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
MMM: ['ינו׳', 'פבר׳', 'מרץ', 'אפר׳', 'מאי', 'יוני', 'יולי', 'אוג׳', 'ספט׳', 'אוק׳', 'נוב׳', 'דצמ׳'],
dddd: ['יום ראשון', 'יום שני', 'יום שלישי', 'יום רביעי', 'יום חמישי', 'יום שישי', 'יום שבת'],
ddd: ['יום א׳', 'יום ב׳', 'יום ג׳', 'יום ד׳', 'יום ה׳', 'יום ו׳', 'שבת'],
dd: ['א׳', 'ב׳', 'ג׳', 'ד׳', 'ה׳', 'ו׳', 'ש׳'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/hi.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/hi.ts';
const locale = {
MMMM: ['जनवरी', 'फ़रवरी', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुलाई', 'अगस्त', 'सितंबर', 'अक्तूबर', 'नवंबर', 'दिसंबर'],
MMM: ['जन॰', 'फ़र॰', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुल॰', 'अग॰', 'सित॰', 'अक्तू॰', 'नव॰', 'दिस॰'],
dddd: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार'],
ddd: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
dd: ['र', 'सो', 'मं', 'बु', 'गु', 'शु', 'श'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/hu.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/hu.ts';
const locale = {
MMMM: ['január', 'február', 'március', 'április', 'május', 'június', 'július', 'augusztus', 'szeptember', 'október', 'november', 'december'],
MMM: ['jan.', 'febr.', 'márc.', 'ápr.', 'máj.', 'jún.', 'júl.', 'aug.', 'szept.', 'okt.', 'nov.', 'dec.'],
dddd: ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'],
ddd: ['vas', 'hét', 'kedd', 'sze', 'csüt', 'pén', 'szo'],
dd: ['V', 'H', 'K', 'Sze', 'Cs', 'P', 'Szo'],
A: ['DE', 'DU'],
AA: ['DE.', 'DU.'],
a: ['de', 'du'],
aa: ['de.', 'du.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/id.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/id.ts';
const locale = {
MMMM: ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'],
MMM: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'],
dddd: ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu'],
ddd: ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'],
dd: ['Mg', 'Sn', 'Sl', 'Rb', 'Km', 'Jm', 'Sb'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/it.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/it.ts';
const locale = {
MMMM: ['gennaio', 'febbraio', 'marzo', 'aprile', 'maggio', 'giugno', 'luglio', 'agosto', 'settembre', 'ottobre', 'novembre', 'dicembre'],
MMM: ['gen', 'feb', 'mar', 'apr', 'mag', 'giu', 'lug', 'ago', 'set', 'ott', 'nov', 'dic'],
dddd: ['domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato'],
ddd: ['dom', 'lun', 'mar', 'mer', 'gio', 'ven', 'sab'],
dd: ['Do', 'Lu', 'Ma', 'Me', 'Gi', 'Ve', 'Sa'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ja.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ja.ts';
const locale = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'],
ddd: ['日', '月', '火', '水', '木', '金', '土'],
dd: ['日', '月', '火', '水', '木', '金', '土'],
A: ['午前', '午後'],
AA: ['午前', '午後'],
a: ['午前', '午後'],
aa: ['午前', '午後']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ko.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ko.ts';
const locale = {
MMMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
MMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
dddd: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'],
ddd: ['일', '월', '화', '수', '목', '금', '토'],
dd: ['일', '월', '화', '수', '목', '금', '토'],
A: ['오전', '오후'],
AA: ['오전', '오후'],
a: ['오전', '오후'],
aa: ['오전', '오후']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ms.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ms.ts';
const locale = {
MMMM: ['Januari', 'Februari', 'Mac', 'April', 'Mei', 'Jun', 'Julai', 'Ogos', 'September', 'Oktober', 'November', 'Disember'],
MMM: ['Jan', 'Feb', 'Mac', 'Apr', 'Mei', 'Jun', 'Jul', 'Ogo', 'Sep', 'Okt', 'Nov', 'Dis'],
dddd: ['Ahad', 'Isnin', 'Selasa', 'Rabu', 'Khamis', 'Jumaat', 'Sabtu'],
ddd: ['Ahd', 'Isn', 'Sel', 'Rab', 'Kha', 'Jum', 'Sab'],
dd: ['Ahd', 'Isn', 'Sel', 'Rab', 'Kha', 'Jum', 'Sab'],
A: ['PG', 'PTG'],
AA: ['PG', 'PTG'],
a: ['PG', 'PTG'],
aa: ['PG', 'PTG']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/my.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/my.ts';
const locale = {
MMMM: ['ဇန်နဝါရီ', 'ဖေဖော်ဝါရီ', 'မတ်', 'ဧပြီ', 'မေ', 'ဇွန်', 'ဇူလိုင်', 'ဩဂုတ်', 'စက်တင်ဘာ', 'အောက်တိုဘာ', 'နိုဝင်ဘာ', 'ဒီဇင်ဘာ'],
MMM: ['ဇန်', 'ဖေ', 'မတ်', 'ဧ', 'မေ', 'ဇွန်', 'ဇူ', 'ဩ', 'စက်', 'အောက်', 'နို', 'ဒီ'],
dddd: ['တနင်္ဂနွေ', 'တနင်္လာ', 'အင်္ဂါ', 'ဗုဒ္ဓဟူး', 'ကြာသပတေး', 'သောကြာ', 'စနေ'],
ddd: ['တနင်္ဂနွေ', 'တနင်္လာ', 'အင်္ဂါ', 'ဗုဒ္ဓဟူး', 'ကြာသပတေး', 'သောကြာ', 'စနေ'],
dd: ['တ', 'တ', 'အ', 'ဗ', 'က', 'သ', 'စ'],
A: ['နံနက်', 'ညနေ'],
AA: ['နံနက်', 'ညနေ'],
a: ['နံနက်', 'ညနေ'],
aa: ['နံနက်', 'ညနေ']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/nl.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/nl.ts';
const locale = {
MMMM: ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
MMM: ['jan', 'feb', 'mrt', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'],
dddd: ['zondag', 'maandag', 'dinsdag', 'woensdag', 'donderdag', 'vrijdag', 'zaterdag'],
ddd: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
dd: ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/no.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/no.ts';
const locale = {
MMMM: ['januar', 'februar', 'mars', 'april', 'mai', 'juni', 'juli', 'august', 'september', 'oktober', 'november', 'desember'],
MMM: ['jan.', 'feb.', 'mars', 'apr.', 'mai', 'juni', 'juli', 'aug.', 'sep.', 'okt.', 'nov.', 'des.'],
dddd: ['søndag', 'mandag', 'tirsdag', 'onsdag', 'torsdag', 'fredag', 'lørdag'],
ddd: ['søn.', 'man.', 'tir.', 'ons.', 'tor.', 'fre.', 'lør.'],
dd: ['søn.', 'man.', 'tir.', 'ons.', 'tor.', 'fre.', 'lør.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/pl.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/pl.ts';
const locale = {
MMMM: [
['styczeń', 'luty', 'marzec', 'kwiecień', 'maj', 'czerwiec', 'lipiec', 'sierpień', 'wrzesień', 'październik', 'listopad', 'grudzień'],
['stycznia', 'lutego', 'marca', 'kwietnia', 'maja', 'czerwca', 'lipca', 'sierpnia', 'września', 'października', 'listopada', 'grudnia']
],
MMM: ['sty', 'lut', 'mar', 'kwi', 'maj', 'cze', 'lip', 'sie', 'wrz', 'paź', 'lis', 'gru'],
dddd: ['niedziela', 'poniedziałek', 'wtorek', 'środa', 'czwartek', 'piątek', 'sobota'],
ddd: ['niedz.', 'pon.', 'wt.', 'śr.', 'czw.', 'pt.', 'sob.'],
dd: ['ndz.', 'pn.', 'wt.', 'śr.', 'cz.', 'pt.', 'so.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/pt-BR.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/pt-BR.ts';
const locale = {
MMMM: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
MMM: ['jan.', 'fev.', 'mar.', 'abr.', 'mai.', 'jun.', 'jul.', 'ago.', 'set.', 'out.', 'nov.', 'dez.'],
dddd: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
ddd: ['dom.', 'seg.', 'ter.', 'qua.', 'qui.', 'sex.', 'sáb.'],
dd: ['1ª', '2ª', '3ª', '4ª', '5ª', '6ª', '7ª'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/pt-PT.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/pt-PT.ts';
const locale = {
MMMM: ['janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro'],
MMM: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
dddd: ['domingo', 'segunda-feira', 'terça-feira', 'quarta-feira', 'quinta-feira', 'sexta-feira', 'sábado'],
ddd: ['domingo', 'segunda', 'terça', 'quarta', 'quinta', 'sexta', 'sábado'],
dd: ['Do', '2ª', '3ª', '4ª', '5ª', '6ª', 'Sa'],
A: ['da manhã', 'da tarde'],
AA: ['da manhã', 'da tarde'],
a: ['da manhã', 'da tarde'],
aa: ['da manhã', 'da tarde']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ro.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ro.ts';
const locale = {
MMMM: ['ianuarie', 'februarie', 'martie', 'aprilie', 'mai', 'iunie', 'iulie', 'august', 'septembrie', 'octombrie', 'noiembrie', 'decembrie'],
MMM: ['ian.', 'feb.', 'mar.', 'apr.', 'mai', 'iun.', 'iul.', 'aug.', 'sept.', 'oct.', 'nov.', 'dec.'],
dddd: ['duminică', 'luni', 'marți', 'miercuri', 'joi', 'vineri', 'sâmbătă'],
ddd: ['dum.', 'lun.', 'mar.', 'mie.', 'joi', 'vin.', 'sâm.'],
dd: ['du', 'lu', 'ma', 'mi', 'jo', 'vi', 'sâ'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ru.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ru.ts';
const locale = {
MMMM: [
['январь', 'февраль', 'март', 'апрель', 'май', 'июнь', 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'],
['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря']
],
MMM: [
['янв.', 'февр.', 'март', 'апр.', 'май', 'июнь', 'июль', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.'],
['янв.', 'февр.', 'мар.', 'апр.', 'мая', 'июн.', 'июл.', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.']
],
dddd: ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'],
ddd: ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
dd: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM D', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo })).toEqual(d);
});
});
test('MMM D ignoreCase', () => {
locale.MMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/rw.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/rw.ts';
const locale = {
MMMM: ['Mutarama', 'Gashyantare', 'Werurwe', 'Mata', 'Gicurasi', 'Kamena', 'Nyakanga', 'Kanama', 'Nzeri', 'Ukwakira', 'Ugushyingo', 'Ukuboza'],
MMM: ['mut.', 'gas.', 'wer.', 'mat.', 'gic.', 'kam.', 'nya.', 'kan.', 'nze.', 'ukw.', 'ugu.', 'uku.'],
dddd: ['Ku cyumweru', 'Kuwa mbere', 'Kuwa kabiri', 'Kuwa gatatu', 'Kuwa kane', 'Kuwa gatanu', 'Kuwa gatandatu'],
ddd: ['cyu.', 'mbe.', 'kab.', 'gtu.', 'kan.', 'gnu.', 'gnd.'],
dd: ['cyu.', 'mbe.', 'kab.', 'gtu.', 'kan.', 'gnu.', 'gnd.'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/sr-Cyrl.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/sr-Cyrl.ts';
const locale = {
MMMM: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
MMM: ['јан', 'феб', 'мар', 'апр', 'мај', 'јун', 'јул', 'авг', 'сеп', 'окт', 'нов', 'дец'],
dddd: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
ddd: ['нед', 'пон', 'уто', 'сре', 'чет', 'пет', 'суб'],
dd: ['нед', 'пон', 'уто', 'сре', 'чет', 'пет', 'суб'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/sr-Latn.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/sr-Latn.ts';
const locale = {
MMMM: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
MMM: ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'avg', 'sep', 'okt', 'nov', 'dec'],
dddd: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
ddd: ['ned', 'pon', 'uto', 'sre', 'čet', 'pet', 'sub'],
dd: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/sv.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/sv.ts';
const locale = {
MMMM: ['januari', 'februari', 'mars', 'april', 'maj', 'juni', 'juli', 'augusti', 'september', 'oktober', 'november', 'december'],
MMM: ['jan.', 'feb.', 'mars', 'apr.', 'maj', 'juni', 'juli', 'aug.', 'sep.', 'okt.', 'nov.', 'dec.'],
dddd: ['söndag', 'måndag', 'tisdag', 'onsdag', 'torsdag', 'fredag', 'lördag'],
ddd: ['sön', 'mån', 'tis', 'ons', 'tors', 'fre', 'lör'],
dd: ['sö', 'må', 'ti', 'on', 'to', 'fr', 'lö'],
A: ['fm', 'em'],
AA: ['fm', 'em'],
a: ['fm', 'em'],
aa: ['fm', 'em']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/ta.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/ta.ts';
const locale = {
MMMM: ['ஜனவரி', 'பிப்ரவரி', 'மார்ச்', 'ஏப்ரல்', 'மே', 'ஜூன்', 'ஜூலை', 'ஆகஸ்ட்', 'செப்டம்பர்', 'அக்டோபர்', 'நவம்பர்', 'டிசம்பர்'],
MMM: ['ஜன.', 'பிப்.', 'மார்.', 'ஏப்.', 'மே', 'ஜூன்', 'ஜூலை', 'ஆக.', 'செப்.', 'அக்.', 'நவ.', 'டிச.'],
dddd: ['ஞாயிறு', 'திங்கள்', 'செவ்வாய்', 'புதன்', 'வியாழன்', 'வெள்ளி', 'சனி'],
ddd: ['ஞாயி.', 'திங்.', 'செவ்.', 'புத.', 'வியா.', 'வெள்.', 'சனி'],
dd: ['ஞா', 'தி', 'செ', 'பு', 'வி', 'வெ', 'ச'],
A: ['AM', 'PM'],
AA: ['A.M.', 'P.M.'],
a: ['am', 'pm'],
aa: ['a.m.', 'p.m.']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/th.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/th.ts';
const locale = {
MMMM: ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
MMM: ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'],
dddd: ['วันอาทิตย์', 'วันจันทร์', 'วันอังคาร', 'วันพุธ', 'วันพฤหัสบดี', 'วันศุกร์', 'วันเสาร์'],
ddd: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
dd: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'],
A: ['ก่อนเที่ยง', 'หลังเที่ยง'],
AA: ['ก่อนเที่ยง', 'หลังเที่ยง'],
a: ['ก่อนเที่ยง', 'หลังเที่ยง'],
aa: ['ก่อนเที่ยง', 'หลังเที่ยง']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/tr.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/tr.ts';
const locale = {
MMMM: ['Ocak', 'Şubat', 'Mart', 'Nisan', 'Mayıs', 'Haziran', 'Temmuz', 'Ağustos', 'Eylül', 'Ekim', 'Kasım', 'Aralık'],
MMM: ['Oca', 'Şub', 'Mar', 'Nis', 'May', 'Haz', 'Tem', 'Ağu', 'Eyl', 'Eki', 'Kas', 'Ara'],
dddd: ['Pazar', 'Pazartesi', 'Salı', 'Çarşamba', 'Perşembe', 'Cuma', 'Cumartesi'],
ddd: ['Paz', 'Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt'],
dd: ['Pz', 'Pt', 'Sa', 'Ça', 'Pe', 'Cu', 'Ct'],
A: ['ÖÖ', 'ÖS'],
AA: ['ÖÖ', 'ÖS'],
a: ['ÖÖ', 'ÖS'],
aa: ['ÖÖ', 'ÖS']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/uk.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/uk.ts';
const locale = {
MMMM: [
['січень', 'лютий', 'березень', 'квітень', 'травень', 'червень', 'липень', 'серпень', 'вересень', 'жовтень', 'листопад', 'грудень'],
['січня', 'лютого', 'березня', 'квітня', 'травня', 'червня', 'липня', 'серпня', 'вересня', 'жовтня', 'листопада', 'грудня']
],
MMM: ['січ.', 'лют.', 'бер.', 'квіт.', 'трав.', 'черв.', 'лип.', 'серп.', 'вер.', 'жовт.', 'лист.', 'груд.'],
dddd: ['неділя', 'понеділок', 'вівторок', 'середа', 'четвер', 'пʼятниця', 'субота'],
ddd: ['нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
dd: ['нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
A: ['дп', 'пп'],
AA: ['дп', 'пп'],
a: ['дп', 'пп'],
aa: ['дп', 'пп']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM D', { locale: lo })).toBe(`${v} 1`);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM[0].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMMM D', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo })).toEqual(d);
});
});
test('MMMM D ignoreCase', () => {
locale.MMMM[1].forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(`${v} 1`, 'MMMM D', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/uz-Cyrl.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/uz-Cyrl.ts';
const locale = {
MMMM: ['январ', 'феврал', 'март', 'апрел', 'май', 'июн', 'июл', 'август', 'сентябр', 'октябр', 'ноябр', 'декабр'],
MMM: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек'],
dddd: ['якшанба', 'душанба', 'сешанба', 'чоршанба', 'пайшанба', 'жума', 'шанба'],
ddd: ['якш', 'душ', 'сеш', 'чор', 'пай', 'жум', 'шан'],
dd: ['Як', 'Ду', 'Се', 'Чо', 'Па', 'Жу', 'Ша'],
A: ['ТО', 'ТК'],
AA: ['ТО', 'ТК'],
a: ['ТО', 'ТК'],
aa: ['ТО', 'ТК']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/uz-Latn.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/uz-Latn.ts';
const locale = {
MMMM: ['yanvar', 'fevral', 'mart', 'aprel', 'may', 'iyun', 'iyul', 'avgust', 'sentabr', 'oktabr', 'noyabr', 'dekabr'],
MMM: ['yan', 'fev', 'mar', 'apr', 'may', 'iyn', 'iyl', 'avg', 'sen', 'okt', 'noy', 'dek'],
dddd: ['yakshanba', 'dushanba', 'seshanba', 'chorshanba', 'payshanba', 'juma', 'shanba'],
ddd: ['Yak', 'Dush', 'Sesh', 'Chor', 'Pay', 'Jum', 'Shan'],
dd: ['Yak', 'Dush', 'Sesh', 'Chor', 'Pay', 'Jum', 'Shan'],
A: ['TO', 'TK'],
AA: ['TO', 'TK'],
a: ['TO', 'TK'],
aa: ['TO', 'TK']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/vi.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/vi.ts';
const locale = {
MMMM: ['tháng 1', 'tháng 2', 'tháng 3', 'tháng 4', 'tháng 5', 'tháng 6', 'tháng 7', 'tháng 8', 'tháng 9', 'tháng 10', 'tháng 11', 'tháng 12'],
MMM: ['thg 1', 'thg 2', 'thg 3', 'thg 4', 'thg 5', 'thg 6', 'thg 7', 'thg 8', 'thg 9', 'thg 10', 'thg 11', 'thg 12'],
dddd: ['Chủ Nhật', 'Thứ Hai', 'Thứ Ba', 'Thứ Tư', 'Thứ Năm', 'Thứ Sáu', 'Thứ Bảy'],
ddd: ['CN', 'Th 2', 'Th 3', 'Th 4', 'Th 5', 'Th 6', 'Th 7'],
dd: ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7'],
A: ['SA', 'CH'],
AA: ['SA', 'CH'],
a: ['SA', 'CH'],
aa: ['SA', 'CH']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/zh-Hans.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/zh-Hans.ts';
const locale = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
ddd: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
dd: ['日', '一', '二', '三', '四', '五', '六'],
A: ['上午', '下午'],
AA: ['上午', '下午'],
a: ['上午', '下午'],
aa: ['上午', '下午']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/locales/zh-Hant.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format, parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import lo from '@/locales/zh-Hant.ts';
const locale = {
MMMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
MMM: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
dddd: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
ddd: ['週日', '週一', '週二', '週三', '週四', '週五', '週六'],
dd: ['日', '一', '二', '三', '四', '五', '六'],
A: ['上午', '下午'],
AA: ['上午', '下午'],
a: ['上午', '下午'],
aa: ['上午', '下午']
};
describe('formatter', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMMM', { locale: lo })).toBe(v);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(format(d, 'MMM', { locale: lo })).toBe(v);
});
});
test('dddd', () => {
locale.dddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dddd', { locale: lo })).toBe(v);
});
});
test('ddd', () => {
locale.ddd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'ddd', { locale: lo })).toBe(v);
});
});
test('dd', () => {
locale.dd.forEach((v, i) => {
const d = new Date(1970, 0, i + 4);
expect(format(d, 'dd', { locale: lo })).toBe(v);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'A', { locale: lo })).toBe(v);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'AA', { locale: lo })).toBe(v);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'a', { locale: lo })).toBe(v);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(format(d, 'aa', { locale: lo })).toBe(v);
});
});
});
describe('parser', () => {
test('MMMM', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo })).toEqual(d);
});
});
test('MMMM ignoreCase', () => {
locale.MMMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('MMM', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo })).toEqual(d);
});
});
test('MMM ignoreCase', () => {
locale.MMM.forEach((v, i) => {
const d = new Date(1970, i, 1);
expect(parse(v, 'MMM', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('dddd', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dddd ignoreCase', () => {
locale.dddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('ddd', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('ddd ignoreCase', () => {
locale.ddd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'ddd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('dd', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser] })).toEqual(d);
});
});
test('dd ignoreCase', () => {
locale.dd.forEach(v => {
const d = new Date(1970, 0, 1);
expect(parse(v, 'dd', { locale: lo, plugins: [parser], ignoreCase: true })).toEqual(d);
});
});
test('A', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo })).toEqual(d);
});
});
test('A ignoreCase', () => {
locale.A.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'A', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('AA', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo })).toEqual(d);
});
});
test('AA ignoreCase', () => {
locale.AA.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'AA', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('a', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo })).toEqual(d);
});
});
test('a ignoreCase', () => {
locale.a.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'a', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
test('aa', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo })).toEqual(d);
});
});
test('aa ignoreCase', () => {
locale.aa.forEach((v, i) => {
const d = new Date(1970, 0, 1, i * 12);
expect(parse(v, 'aa', { locale: lo, ignoreCase: true })).toEqual(d);
});
});
});
================================================
FILE: tests/numerals/arab.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import numeral from '@/numerals/arab.ts';
describe('arab', () => {
test('encode', () => {
expect(numeral.encode('0 1 2 3 4 5 6 7 8 9')).toBe('٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩');
});
test('decode', () => {
expect(numeral.decode('٠ ١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩')).toBe('0 1 2 3 4 5 6 7 8 9');
});
});
================================================
FILE: tests/numerals/arabext.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import numeral from '@/numerals/arabext.ts';
describe('arabext', () => {
test('encode', () => {
expect(numeral.encode('0 1 2 3 4 5 6 7 8 9')).toBe('۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹');
});
test('decode', () => {
expect(numeral.decode('۰ ۱ ۲ ۳ ۴ ۵ ۶ ۷ ۸ ۹')).toBe('0 1 2 3 4 5 6 7 8 9');
});
});
================================================
FILE: tests/numerals/beng.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import numeral from '@/numerals/beng.ts';
describe('beng', () => {
test('encode', () => {
expect(numeral.encode('0 1 2 3 4 5 6 7 8 9')).toBe('০ ১ ২ ৩ ৪ ৫ ৬ ৭ ৮ ৯');
});
test('decode', () => {
expect(numeral.decode('০ ১ ২ ৩ ৪ ৫ ৬ ৭ ৮ ৯')).toBe('0 1 2 3 4 5 6 7 8 9');
});
});
================================================
FILE: tests/numerals/latn.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import numeral from '@/numerals/latn.ts';
describe('latn', () => {
test('encode', () => {
expect(numeral.encode('0 1 2 3 4 5 6 7 8 9')).toBe('0 1 2 3 4 5 6 7 8 9');
});
test('decode', () => {
expect(numeral.decode('0 1 2 3 4 5 6 7 8 9')).toBe('0 1 2 3 4 5 6 7 8 9');
});
});
================================================
FILE: tests/numerals/mymr.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import numeral from '@/numerals/mymr.ts';
describe('mymr', () => {
test('encode', () => {
expect(numeral.encode('0 1 2 3 4 5 6 7 8 9')).toBe('၀ ၁ ၂ ၃ ၄ ၅ ၆ ၇ ၈ ၉');
});
test('decode', () => {
expect(numeral.decode('၀ ၁ ၂ ၃ ၄ ၅ ၆ ၇ ၈ ၉')).toBe('0 1 2 3 4 5 6 7 8 9');
});
});
================================================
FILE: tests/parse.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { parse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
import Tokyo from '@/timezones/Asia/Tokyo.ts';
import Adelaide from '@/timezones/Australia/Adelaide.ts';
import Apia from '@/timezones/Pacific/Apia.ts';
import Metlakatla from '@/timezones/America/Metlakatla';
import Manila from '@/timezones/Asia/Manila';
import {
Los_Angeles as los_angeles,
Tokyo as tokyo,
Adelaide as adelaide,
Apia as apia,
Metlakatla as metlakatla,
Manila as manila
} from '@/timezone.ts';
test('YYYY', () => {
expect(Number.isNaN(parse('0000', 'YYYY').getTime())).toBe(true);
});
test('YYYY', () => {
const now = new Date(0, -1899 * 12, 1);
expect(parse('0001', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(0, -1801 * 12, 1);
expect(parse('0099', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(100, 0, 1);
expect(parse('0100', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(1899, 0, 1);
expect(parse('1899', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(1900, 0, 1);
expect(parse('1900', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(1969, 0, 1);
expect(parse('1969', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(1970, 0, 1);
expect(parse('1970', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(1999, 0, 1);
expect(parse('1999', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(2000, 0, 1);
expect(parse('2000', 'YYYY')).toEqual(now);
});
test('YYYY', () => {
const now = new Date(9999, 0, 1);
expect(parse('9999', 'YYYY')).toEqual(now);
});
test('Y', () => {
expect(Number.isNaN(parse('0', 'Y').getTime())).toBe(true);
});
test('Y', () => {
const now = new Date(0, -1899 * 12, 1);
expect(parse('1', 'Y')).toEqual(now);
});
test('Y', () => {
const now = new Date(0, -1801 * 12, 1);
expect(parse('99', 'Y')).toEqual(now);
});
test('Y', () => {
const now = new Date(100, 0, 1);
expect(parse('100', 'Y')).toEqual(now);
});
test('YYYY MMMM', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015 January', 'YYYY MMMM')).toEqual(now);
});
test('YYYY MMMM', () => {
const now = new Date(2015, 11, 1);
expect(parse('2015 December', 'YYYY MMMM')).toEqual(now);
});
test('YYYY MMMM', () => {
expect(Number.isNaN(parse('2015 Zero', 'YYYY MMMM').getTime())).toBe(true);
});
test('YYYY MMM', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015 Jan', 'YYYY MMM')).toEqual(now);
});
test('YYYY MMM', () => {
const now = new Date(2015, 11, 1);
expect(parse('2015 Dec', 'YYYY MMM')).toEqual(now);
});
test('YYYY MMM', () => {
expect(Number.isNaN(parse('2015 Zero', 'YYYY MMM').getTime())).toBe(true);
});
test('YYYY-MM', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015-01', 'YYYY-MM')).toEqual(now);
});
test('YYYY-MM', () => {
const now = new Date(2015, 11, 1);
expect(parse('2015-12', 'YYYY-MM')).toEqual(now);
});
test('YYYY-MM', () => {
expect(Number.isNaN(parse('2015-00', 'YYYY-MM').getTime())).toBe(true);
});
test('YYYY-M', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015-1', 'YYYY-M')).toEqual(now);
});
test('YYYY-M', () => {
const now = new Date(2015, 11, 1);
expect(parse('2015-12', 'YYYY-M')).toEqual(now);
});
test('YYYY-M', () => {
expect(Number.isNaN(parse('2015-0', 'YYYY-M').getTime())).toBe(true);
});
test('YYYY-MM-DD', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015-01-01', 'YYYY-MM-DD')).toEqual(now);
});
test('YYYY-MM-DD', () => {
const now = new Date(2015, 11, 31);
expect(parse('2015-12-31', 'YYYY-MM-DD')).toEqual(now);
});
test('YYYY-MM-DD', () => {
expect(Number.isNaN(parse('2015-00-00', 'YYYY-MM-DD').getTime())).toBe(true);
});
test('YYYY-M-D', () => {
const now = new Date(2015, 0, 1);
expect(parse('2015-1-1', 'YYYY-M-D')).toEqual(now);
});
test('YYYY-M-D', () => {
const now = new Date(2015, 11, 31);
expect(parse('2015-12-31', 'YYYY-M-D')).toEqual(now);
});
test('YYYY-M-D', () => {
expect(Number.isNaN(parse('2015-0-0', 'YYYY-M-D').getTime())).toBe(true);
});
test('YYYY-MM-DD HH', () => {
const now = new Date(2015, 0, 1, 0);
expect(parse('2015-01-01 00', 'YYYY-MM-DD HH')).toEqual(now);
});
test('YYYY-MM-DD HH', () => {
const now = new Date(2015, 11, 31, 23);
expect(parse('2015-12-31 23', 'YYYY-MM-DD HH')).toEqual(now);
});
test('YYYY-MM-DD HH', () => {
expect(Number.isNaN(parse('2015-00-00 24', 'YYYY-MM-DD HH').getTime())).toBe(true);
});
test('YYYY-M-D H', () => {
const now = new Date(2015, 0, 1, 0);
expect(parse('2015-1-1 0', 'YYYY-M-D H')).toEqual(now);
});
test('YYYY-M-D H', () => {
const now = new Date(2015, 11, 31, 23);
expect(parse('2015-12-31 23', 'YYYY-M-D H')).toEqual(now);
});
test('YYYY-M-D H', () => {
expect(Number.isNaN(parse('2015-0-0 24', 'YYYY-M-D H').getTime())).toBe(true);
});
test('YYYY-M-D hh A', () => {
const now = new Date(2015, 0, 1, 0);
expect(parse('2015-1-1 12 AM', 'YYYY-M-D hh A')).toEqual(now);
});
test('YYYY-M-D hh A', () => {
const now = new Date(2015, 11, 31, 23);
expect(parse('2015-12-31 11 PM', 'YYYY-M-D hh A')).toEqual(now);
});
test('YYYY-M-D hh A', () => {
expect(Number.isNaN(parse('2015-0-0 12 AM', 'YYYY-M-D hh A').getTime())).toBe(true);
});
test('YYYY-M-D h A', () => {
const now = new Date(2015, 0, 1, 0);
expect(parse('2015-1-1 12 AM', 'YYYY-M-D h A')).toEqual(now);
});
test('YYYY-M-D h A', () => {
const now = new Date(2015, 11, 31, 23);
expect(parse('2015-12-31 11 PM', 'YYYY-M-D h A')).toEqual(now);
});
test('YYYY-M-D h A', () => {
expect(Number.isNaN(parse('2015-0-0 12 AM', 'YYYY-M-D h A').getTime())).toBe(true);
});
test('YYYY-MM-DD HH:mm', () => {
const now = new Date(2015, 0, 1, 0, 0);
expect(parse('2015-01-01 00:00', 'YYYY-MM-DD HH:mm')).toEqual(now);
});
test('YYYY-MM-DD HH:mm', () => {
const now = new Date(2015, 11, 31, 23, 59);
expect(parse('2015-12-31 23:59', 'YYYY-MM-DD HH:mm')).toEqual(now);
});
test('YYYY-MM-DD HH:mm', () => {
expect(Number.isNaN(parse('2015-00-00 24:60', 'YYYY-MM-DD HH:mm').getTime())).toBe(true);
});
test('YYYY-M-D H:m', () => {
const now = new Date(2015, 0, 1, 0, 0);
expect(parse('2015-1-1 0:0', 'YYYY-M-D H:m')).toEqual(now);
});
test('YYYY-M-D H:m', () => {
const now = new Date(2015, 11, 31, 23, 59);
expect(parse('2015-12-31 23:59', 'YYYY-M-D H:m')).toEqual(now);
});
test('YYYY-M-D H:m', () => {
expect(Number.isNaN(parse('2015-0-0 24:60', 'YYYY-M-D H:m').getTime())).toBe(true);
});
test('YYYY-MM-DD HH:mm:ss', () => {
const now = new Date(2015, 0, 1, 0, 0, 0);
expect(parse('2015-01-01 00:00:00', 'YYYY-MM-DD HH:mm:ss')).toEqual(now);
});
test('YYYY-MM-DD HH:mm:ss', () => {
const now = new Date(2015, 11, 31, 23, 59, 59);
expect(parse('2015-12-31 23:59:59', 'YYYY-MM-DD HH:mm:ss')).toEqual(now);
});
test('YYYY-MM-DD HH:mm:ss', () => {
expect(Number.isNaN(parse('2015-00-00 24:60:60', 'YYYY-MM-DD HH:mm:ss').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s', () => {
const now = new Date(2015, 0, 1, 0, 0);
expect(parse('2015-1-1 0:0:0', 'YYYY-M-D H:m:s')).toEqual(now);
});
test('YYYY-M-D H:m:s', () => {
const now = new Date(2015, 11, 31, 23, 59, 59);
expect(parse('2015-12-31 23:59:59', 'YYYY-M-D H:m:s')).toEqual(now);
});
test('YYYY-M-D H:m:s', () => {
expect(Number.isNaN(parse('2015-0-0 24:60:60', 'YYYY-M-D H:m:s').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SSS', () => {
const now = new Date(2015, 0, 1, 0, 0, 0);
expect(parse('2015-1-1 0:0:0.0', 'YYYY-M-D H:m:s.SSS')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS', () => {
const now = new Date(2015, 11, 31, 23, 59, 59, 999);
expect(parse('2015-12-31 23:59:59.999', 'YYYY-M-D H:m:s.SSS')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS', () => {
expect(Number.isNaN(parse('2015-0-0 24:60:61.000', 'YYYY-M-D H:m:s.SSS').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SS', () => {
const now = new Date(2015, 0, 1, 0, 0, 0);
expect(parse('2015-1-1 0:0:0.0', 'YYYY-M-D H:m:s.SS')).toEqual(now);
});
test('YYYY-M-D H:m:s.SS', () => {
const now = new Date(2015, 11, 31, 23, 59, 59, 990);
expect(parse('2015-12-31 23:59:59.99', 'YYYY-M-D H:m:s.SS')).toEqual(now);
});
test('YYYY-M-D H:m:s.SS', () => {
expect(Number.isNaN(parse('2015-0-0 24:60:61.00', 'YYYY-M-D H:m:s.SS').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.S', () => {
const now = new Date(2015, 0, 1, 0, 0, 0);
expect(parse('2015-1-1 0:0:0.0', 'YYYY-M-D H:m:s.S')).toEqual(now);
});
test('YYYY-M-D H:m:s.S', () => {
const now = new Date(2015, 11, 31, 23, 59, 59, 900);
expect(parse('2015-12-31 23:59:59.9', 'YYYY-M-D H:m:s.S')).toEqual(now);
});
test('YYYY M D H m s S', () => {
const now = new Date(2015, 11, 31, 23, 59, 59, 900);
expect(parse('2015-12-31 23:59:59.9', 'YYYY M D H m s S')).toEqual(now);
});
test('YYYY-M-D H:m:s.S', () => {
expect(Number.isNaN(parse('2015-0-0 24:60:61.0', 'YYYY-M-D H:m:s.S').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
const now = new Date(Date.UTC(2015, 0, 1, 0, 0, 0));
expect(parse('2015-1-1 0:0:0.0 +0000', 'YYYY-M-D H:m:s.SSS Z')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
const now = new Date(Date.UTC(2015, 11, 31, 23, 59, 59, 999));
expect(parse('2015-12-31 23:00:59.999 -0059', 'YYYY-M-D H:m:s.SSS Z')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
const now = new Date(Date.UTC(2015, 11, 31, 21, 59, 59, 999));
expect(parse('2015-12-31 09:59:59.999 -1200', 'YYYY-M-D H:m:s.SSS Z')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
expect(Number.isNaN(parse('2015-12-31 09:58:59.999 -1601', 'YYYY-M-D H:m:s.SSS Z').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
const now = new Date(Date.UTC(2015, 11, 30, 22, 0, 59, 999));
expect(parse('2015-12-31 12:00:59.999 +1400', 'YYYY-M-D H:m:s.SSS Z')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS Z', () => {
expect(Number.isNaN(parse('2015-12-31 12:01:59.999 +1601', 'YYYY-M-D H:m:s.SSS Z').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
const now = new Date(Date.UTC(2015, 0, 1, 0, 0, 0));
expect(parse('2015-1-1 0:0:0.0 +00:00', 'YYYY-M-D H:m:s.SSS ZZ')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
const now = new Date(Date.UTC(2015, 11, 31, 23, 59, 59, 999));
expect(parse('2015-12-31 23:00:59.999 -00:59', 'YYYY-M-D H:m:s.SSS ZZ')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
const now = new Date(Date.UTC(2015, 11, 31, 21, 59, 59, 999));
expect(parse('2015-12-31 09:59:59.999 -12:00', 'YYYY-M-D H:m:s.SSS ZZ')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
expect(Number.isNaN(parse('2015-12-31 09:58:59.999 -16:01', 'YYYY-M-D H:m:s.SSS ZZ').getTime())).toBe(true);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
const now = new Date(Date.UTC(2015, 11, 30, 22, 0, 59, 999));
expect(parse('2015-12-31 12:00:59.999 +14:00', 'YYYY-M-D H:m:s.SSS ZZ')).toEqual(now);
});
test('YYYY-M-D H:m:s.SSS ZZ', () => {
expect(Number.isNaN(parse('2015-12-31 12:01:59.999 +16:01', 'YYYY-M-D H:m:s.SSS ZZ').getTime())).toBe(true);
});
test('MMDDHHmmssSSS', () => {
const now = new Date(1970, 11, 31, 23, 59, 59, 999);
expect(parse('1231235959999', 'MMDDHHmmssSSS')).toEqual(now);
});
test('DDHHmmssSSS', () => {
const now = new Date(1970, 0, 31, 23, 59, 59, 999);
expect(parse('31235959999', 'DDHHmmssSSS')).toEqual(now);
});
test('HHmmssSSS', () => {
const now = new Date(1970, 0, 1, 23, 59, 59, 999);
expect(parse('235959999', 'HHmmssSSS')).toEqual(now);
});
test('mmssSSS', () => {
const now = new Date(1970, 0, 1, 0, 59, 59, 999);
expect(parse('5959999', 'mmssSSS')).toEqual(now);
});
test('ssSSS', () => {
const now = new Date(1970, 0, 1, 0, 0, 59, 999);
expect(parse('59999', 'ssSSS')).toEqual(now);
});
test('SSS', () => {
const now = new Date(1970, 0, 1, 0, 0, 0, 999);
expect(parse('999', 'SSS')).toEqual(now);
});
test('Z', () => {
expect(Number.isNaN(parse('+000', 'Z').getTime())).toBe(true);
});
test('Z', () => {
expect(Number.isNaN(parse('+00', 'Z').getTime())).toBe(true);
});
test('Z', () => {
expect(Number.isNaN(parse('+0', 'Z').getTime())).toBe(true);
});
test('Z', () => {
expect(Number.isNaN(parse('0', 'Z').getTime())).toBe(true);
});
test('Z', () => {
expect(Number.isNaN(parse('0000', 'Z').getTime())).toBe(true);
});
test('Z', () => {
expect(Number.isNaN(parse('00000', 'Z').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('+00:0', 'ZZ').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('+00:', 'ZZ').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('+0:', 'ZZ').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('0:', 'ZZ').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('00:00', 'ZZ').getTime())).toBe(true);
});
test('ZZ', () => {
expect(Number.isNaN(parse('00:000', 'ZZ').getTime())).toBe(true);
});
test('foo', () => {
expect(Number.isNaN(parse('20150101235959', 'foo').getTime())).toBe(true);
});
test('bar', () => {
expect(Number.isNaN(parse('20150101235959', 'bar').getTime())).toBe(true);
});
test('YYYYMMDD', () => {
expect(Number.isNaN(parse('20150101235959', 'YYYYMMDD').getTime())).toBe(true);
});
test('20150101235959', () => {
expect(Number.isNaN(parse('20150101235959', '20150101235959').getTime())).toBe(true);
});
test('YYYY?M?D H?m?s?S', () => {
expect(Number.isNaN(parse('2015-12-31 23:59:59.9', 'YYYY?M?D H?m?s?S').getTime())).toBe(true);
});
test('[Y]YYYY[M]M[D]D[H]H[m]m[s]s[S]S', () => {
const now = new Date(2015, 11, 31, 23, 59, 59, 900);
expect(parse('Y2015M12D31H23m59s59S9', '[Y]YYYY[M]M[D]D[H]H[m]m[s]s[S]S')).toEqual(now);
});
test('[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]', () => {
expect(Number.isNaN(parse('[Y]2015[M]12[D]31[H]23[m]59[s]59[S]9', '[[Y]YYYY[M]MM[D]DD[H]HH[m]mm[s]ss[S]S]').getTime())).toBe(true);
});
test(' ', () => {
expect(Number.isNaN(parse('20151231235959900', ' ').getTime())).toBe(true);
});
test('\\[YYYY-MM-DD HH:mm:ss\\]', () => {
const now = new Date(2025, 7, 23, 14, 30, 45);
expect(parse('[2025-08-23 14:30:45]', '\\[YYYY-MM-DD HH:mm:ss\\]')).toEqual(now);
});
describe('options', () => {
test('hour12: h11', () => {
expect(parse('2000-01-01 00:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(new Date(2000, 0, 1, 0, 0));
expect(parse('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(new Date(2000, 0, 1, 11, 0));
expect(parse('2000-01-01 00:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(new Date(2000, 0, 1, 12, 0));
expect(parse('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(new Date(2000, 0, 1, 23, 0));
expect(Number.isNaN(parse('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' }).getTime())).toBe(true);
expect(Number.isNaN(parse('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' }).getTime())).toBe(true);
});
test('hour12: h12', () => {
expect(parse('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(new Date(2000, 0, 1, 0, 0));
expect(parse('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(new Date(2000, 0, 1, 11, 0));
expect(parse('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(new Date(2000, 0, 1, 12, 0));
expect(parse('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(new Date(2000, 0, 1, 23, 0));
expect(Number.isNaN(parse('2000-01-01 00:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' }).getTime())).toBe(true);
expect(Number.isNaN(parse('2000-01-01 00:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' }).getTime())).toBe(true);
});
test('ignoreCase: true', () => {
expect(parse('2025 May 4 Sunday 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(new Date(2025, 4, 4, 11, 0));
expect(parse('2025 may 4 sunday 11 am', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(new Date(2025, 4, 4, 11, 0));
expect(parse('2025 MAY 4 SUNDAY 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(new Date(2025, 4, 4, 11, 0));
});
test('calendar: buddhist', () => {
expect(parse('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(new Date(2000 - 543, 0, 1, 0, 0));
expect(parse('9999-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(new Date(9999 - 543, 0, 1, 0, 0));
expect(parse('0544-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(new Date(544 - 543, -1900 * 12, 1, 0, 0));
expect(Number.isNaN(parse('0543-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' }).getTime())).toBe(true);
});
test('timeZone', () => {
const now = new Date(Date.UTC(2025, 1 - 1, 1, 0));
expect(parse('2024-12-31 16:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2024-12-31 16:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: los_angeles })).toEqual(now);
expect(parse('2024-12-31 16:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'America/Los_Angeles' })).toEqual(now);
expect(parse('2025-01-01 09:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: Tokyo })).toEqual(now);
expect(parse('2025-01-01 09:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: tokyo })).toEqual(now);
expect(parse('2025-01-01 09:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'Asia/Tokyo' })).toEqual(now);
expect(parse('2025-01-01 00:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'UTC' })).toEqual(now);
expect(parse('2025-01-01 00:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'utc' })).toEqual(now);
const dummyTimeZone = {
zone_name: 'dummyTimeZone',
gmt_offset: [0]
};
expect(Number.isNaN(parse('2025-01-01 00:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: dummyTimeZone }).getTime())).toBe(true);
expect(Number.isNaN(parse('2025-01-01 00:00:00', 'YYYY-MM-DD HH:mm:ss', { timeZone: 'dummyTimeZone' }).getTime())).toBe(true);
});
test('defaultDate: date components', () => {
expect(parse('12:30', 'HH:mm', { defaultDate: { Y: 2024, M: 3, D: 15 } }))
.toEqual(new Date(2024, 2, 15, 12, 30));
expect(parse('03-15', 'MM-DD', { defaultDate: { Y: 2024 } }))
.toEqual(new Date(2024, 2, 15));
});
test('defaultDate: time components', () => {
expect(parse('2024-03-15', 'YYYY-MM-DD', { defaultDate: { H: 10, m: 30, s: 45 } }))
.toEqual(new Date(2024, 2, 15, 10, 30, 45));
});
test('defaultDate: timezone offset (Z)', () => {
// Z: -540 means UTC+9 (JST): minutes become 30+(-540)=-510, so Date.UTC(2024,2,15,12,-510) = 03:30 UTC
expect(parse('12:30', 'HH:mm', { defaultDate: { Y: 2024, M: 3, D: 15, Z: -540 } }))
.toEqual(new Date(Date.UTC(2024, 2, 15, 3, 30)));
});
test('defaultDate: Z takes precedence over timeZone option', () => {
// Z: -540 (UTC+9) overrides timeZone: 'UTC'; 12:30 local → 03:30 UTC
expect(parse('12:30', 'HH:mm', { defaultDate: { Y: 2024, M: 3, D: 15, Z: -540 }, timeZone: 'UTC' }))
.toEqual(new Date(Date.UTC(2024, 2, 15, 3, 30)));
});
test('defaultDate: 12-hour components (h and A)', () => {
// base.A=1 (PM), base.h=2 → hour = 1*12 + 2 = 14 (2 PM)
expect(parse('30', 'mm', { defaultDate: { Y: 2024, M: 3, D: 15, h: 2, A: 1 } }))
.toEqual(new Date(2024, 2, 15, 14, 30));
});
test('defaultDate: calendar: buddhist interaction', () => {
expect(parse('2567-03-15', 'YYYY-MM-DD', { calendar: 'buddhist' }))
.toEqual(new Date(2024, 2, 15));
});
});
describe('timeZone Los_Angeles', () => {
test('before DST', () => {
const now = new Date('2021-03-14T09:59:59.999Z');
expect(parse('2021-03-14 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-03-14 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-03-14 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
test('start DST 1', () => {
const now = new Date('2021-03-14T10:00:00.000Z');
expect(parse('2021-03-14 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-03-14 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-03-14 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
test('start DST 2', () => {
const now = new Date('2021-03-14T10:00:00.000Z');
expect(parse('2021-03-14 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-03-14 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-03-14 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
test('before of PST', () => {
const now = new Date('2021-11-07T08:59:59.999Z');
expect(parse('2021-11-07 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-11-07 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-11-07 01:59:59.999', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
test('end of DST', () => {
const now = new Date('2021-11-07T10:00:00.000Z');
expect(parse('2021-11-07 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-11-07 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-11-07 02:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
test('after of DST', () => {
const now = new Date('2021-11-07T11:00:00.000Z');
expect(parse('2021-11-07 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: Los_Angeles })).toEqual(now);
expect(parse('2021-11-07 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: los_angeles })).toEqual(now);
expect(parse('2021-11-07 03:00:00.000', 'YYYY-MM-DD HH:mm:ss.SSS', { timeZone: 'America/Los_Angeles' })).toEqual(now);
});
});
describe('timeZone Adelaide', () => {
test('before of DST', () => {
// Oct 3 2021 1:59:59.999 => 2021-10-02T16:29:59.999Z
const dateString = 'Oct 3 2021 1:59:59.999';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 9, 2, 16, 29, 59, 999));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
test('start of DST 1', () => {
// Oct 3 2021 2:00:00.000 => 2021-10-02T16:30:00.000Z
const dateString = 'Oct 3 2021 2:00:00.000';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 9, 2, 16, 30, 0, 0));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
test('start of DST 2', () => {
// Oct 3 2021 2:59:59.999 => 2021-10-02T17:29:59.999Z
const dateString = 'Oct 3 2021 2:59:59.999';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 9, 2, 17, 29, 59, 999));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
test('start of DST 3', () => {
// Oct 3 2021 3:00:00.000 => 2021-10-02T16:30:00.000Z
const dateString = 'Oct 3 2021 3:00:00.000';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 9, 2, 16, 30, 0, 0));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
test('end of DST', () => {
// Apr 4 2021 2:59:59.999 => 2021-04-03T16:29:59.999Z
const dateString = 'Apr 4 2021 2:59:59.999';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 3, 3, 16, 29, 59, 999));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
test('after DST', () => {
// Apr 4 2021 3:00:00.000 => 2021-04-03T17:30:00.000Z
const dateString = 'Apr 4 2021 3:00:00.000';
const formatString = 'MMM D YYYY H:mm:ss.SSS';
const dateObj = new Date(Date.UTC(2021, 3, 3, 17, 30, 0, 0));
expect(parse(dateString, formatString, { timeZone: Adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: adelaide }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Australia/Adelaide' }).getTime()).toBe(dateObj.getTime());
});
});
describe('timeZone Apia', () => {
beforeAll(() => (process.env.TZ = 'Pacific/Apia'));
test('1.1', () => {
const dateString = '04 July, 1892 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1892, 7 - 1, 4, 23, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('1.2', () => {
const dateString = '04 July, 1892 12:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1892, 7 - 1, 4, 0, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('2.1', () => {
const dateString = '31 December, 1910 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1910, 12 - 1, 31, 23, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('2.2', () => {
const dateString = '31 December, 1910 11:56:56 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1910, 12 - 1, 31, 23, 56, 56);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('3.1', () => {
const dateString = '31 December, 1949 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1949, 12 - 1, 31, 23, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('3.2', () => {
const dateString = '01 January, 1950 12:30:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1950, 1 - 1, 1, 0, 30, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('4.1', () => {
const dateString = '25 September, 2010 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2010, 9 - 1, 25, 23, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('4.2', () => {
const dateString = '26 September, 2010 01:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2010, 9 - 1, 26, 1, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('5.1', () => {
const dateString = '02 April, 2011 03:59:59 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 4 - 1, 2, 3, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('5.2', () => {
const dateString = '02 April, 2011 03:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 4 - 1, 2, 3, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('6.1', () => {
const dateString = '24 September, 2011 02:59:59 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 9 - 1, 24, 2, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('6.2', () => {
const dateString = '24 September, 2011 04:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 9 - 1, 24, 4, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('7.1', () => {
const dateString = '29 December, 2011 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 12 - 1, 29, 23, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('7.2', () => {
const dateString = '31 December, 2011 12:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2011, 12 - 1, 31, 0, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('8.1', () => {
const dateString = '01 April, 2012 03:59:59 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2012, 4 - 1, 1, 3, 59, 59);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
test('8.2', () => {
const dateString = '01 April, 2012 03:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2012, 4 - 1, 1, 3, 0, 0);
expect(parse(dateString, formatString, { timeZone: Apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: apia }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Pacific/Apia' }).getTime()).toBe(dateObj.getTime());
});
});
describe('timeZone Metlakatla', () => {
beforeAll(() => (process.env.TZ = 'America/Metlakatla'));
test('1.1', () => {
const dateString = '19 October, 1867 03:44:54 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(-3225223728000);
expect(parse(dateString, formatString, { timeZone: Metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'America/Metlakatla' }).getTime()).toBe(dateObj.getTime());
});
test('1.2', () => {
const dateString = '19 October, 1867 03:44:55 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1867, 10 - 1, 19, 15, 44, 55);
expect(parse(dateString, formatString, { timeZone: Metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'America/Metlakatla' }).getTime()).toBe(dateObj.getTime());
});
test('2.1', () => {
const dateString = '02 November, 2025 01:59:59 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2025, 11 - 1, 2, 1, 59, 59);
expect(parse(dateString, formatString, { timeZone: Metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'America/Metlakatla' }).getTime()).toBe(dateObj.getTime());
});
test('2.2', () => {
const dateString = '02 November, 2025 01:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(2025, 11 - 1, 2, 1, 0, 0);
expect(parse(dateString, formatString, { timeZone: Metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: metlakatla }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'America/Metlakatla' }).getTime()).toBe(dateObj.getTime());
});
});
describe('timeZone Manila', () => {
beforeAll(() => (process.env.TZ = 'Asia/Manila'));
test('1.1', () => {
const dateString = '30 December, 1844 11:59:59 PM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(-3944621033000);
expect(parse(dateString, formatString, { timeZone: Manila }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: manila }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Asia/Manila' }).getTime()).toBe(dateObj.getTime());
});
test('1.2', () => {
const dateString = '01 January, 1845 12:00:00 AM';
const formatString = 'DD MMMM, YYYY hh:mm:ss A';
const dateObj = new Date(1845, 1 - 1, 1, 0, 0, 0);
expect(parse(dateString, formatString, { timeZone: Manila }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: manila }).getTime()).toBe(dateObj.getTime());
expect(parse(dateString, formatString, { timeZone: 'Asia/Manila' }).getTime()).toBe(dateObj.getTime());
});
});
================================================
FILE: tests/plugins/microsecond.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { parse } from '@/index.ts';
import { parser as microsecond } from '@/plugins/microsecond.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
test('SSSS', () => {
expect(parse('12:34:56 0000', 'HH:mm:ss SSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 9999', 'HH:mm:ss SSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('SSSSS', () => {
expect(parse('12:34:56 00000', 'HH:mm:ss SSSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 99999', 'HH:mm:ss SSSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('SSSSSS', () => {
expect(parse('12:34:56 000000', 'HH:mm:ss SSSSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999999', 'HH:mm:ss SSSSSS', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('f', () => {
expect(parse('12:34:56 000.0', 'HH:mm:ss SSS.f', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999.9', 'HH:mm:ss SSS.f', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('ff', () => {
expect(parse('12:34:56 000.00', 'HH:mm:ss SSS.ff', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999.99', 'HH:mm:ss SSS.ff', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('fff', () => {
expect(parse('12:34:56 000.000', 'HH:mm:ss SSS.fff', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999.999', 'HH:mm:ss SSS.fff', { plugins: [microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
});
================================================
FILE: tests/plugins/nanosecond.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { parse } from '@/index.ts';
import { parser as nanosecond } from '@/plugins/nanosecond.ts';
import { parser as microsecond } from '@/plugins/microsecond.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
test('SSSSSSS', () => {
expect(parse('12:34:56 0000000', 'HH:mm:ss SSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 9999999', 'HH:mm:ss SSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('SSSSSSSS', () => {
expect(parse('12:34:56 00000000', 'HH:mm:ss SSSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 99999999', 'HH:mm:ss SSSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('SSSSSSSSS', () => {
expect(parse('12:34:56 000000000', 'HH:mm:ss SSSSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999999999', 'HH:mm:ss SSSSSSSSS', { plugins: [nanosecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('F', () => {
expect(parse('12:34:56 000000.0', 'HH:mm:ss SSSSSS.F', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999999.9', 'HH:mm:ss SSSSSS.F', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('FF', () => {
expect(parse('12:34:56 000000.00', 'HH:mm:ss SSSSSS.FF', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999999.99', 'HH:mm:ss SSSSSS.FF', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
test('FFF', () => {
expect(parse('12:34:56 000000.000', 'HH:mm:ss SSSSSS.FFF', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 0));
expect(parse('12:34:56 999999.999', 'HH:mm:ss SSSSSS.FFF', { plugins: [nanosecond, microsecond] })).toEqual(new Date(1970, 1 - 1, 1, 12, 34, 56, 999));
});
});
================================================
FILE: tests/plugins/ordinal.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { format, parse } from '@/index.ts';
import { formatter, parser } from '@/plugins/ordinal.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
describe('formatter', () => {
test('DDD', () => {
expect(format(new Date(2025, 1 - 1, 1, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 1st, 2025');
expect(format(new Date(2025, 1 - 1, 2, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 2nd, 2025');
expect(format(new Date(2025, 1 - 1, 3, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 3rd, 2025');
expect(format(new Date(2025, 1 - 1, 11, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 11th, 2025');
expect(format(new Date(2025, 1 - 1, 12, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 12th, 2025');
expect(format(new Date(2025, 1 - 1, 13, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 13th, 2025');
expect(format(new Date(2025, 1 - 1, 21, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 21st, 2025');
expect(format(new Date(2025, 1 - 1, 22, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 22nd, 2025');
expect(format(new Date(2025, 1 - 1, 23, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 23rd, 2025');
expect(format(new Date(2025, 1 - 1, 31, 0), 'MMMM DDD, YYYY', { plugins: [formatter] })).toBe('January 31st, 2025');
});
});
describe('parser', () => {
test('DDD', () => {
expect(parse('January 1st, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 1));
expect(parse('January 2nd, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 2));
expect(parse('January 3rd, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 3));
expect(parse('January 11th, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 11));
expect(parse('January 12th, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 12));
expect(parse('January 13th, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 13));
expect(parse('January 21st, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 21));
expect(parse('January 22nd, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 22));
expect(parse('January 23rd, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 23));
expect(parse('January 31st, 2025', 'MMMM DDD, YYYY', { plugins: [parser] })).toEqual(new Date(2025, 0, 31));
});
test('DDD ignoreCase', () => {
expect(parse('JANUARY 1ST, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 1));
expect(parse('JANUARY 2ND, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 2));
expect(parse('JANUARY 3RD, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 3));
expect(parse('JANUARY 11TH, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 11));
expect(parse('JANUARY 12TH, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 12));
expect(parse('JANUARY 13TH, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 13));
expect(parse('JANUARY 21ST, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 21));
expect(parse('JANUARY 22ND, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 22));
expect(parse('JANUARY 23RD, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 23));
expect(parse('JANUARY 31ST, 2025', 'MMMM DDD, YYYY', { plugins: [parser], ignoreCase: true })).toEqual(new Date(2025, 0, 31));
});
});
});
================================================
FILE: tests/plugins/quarter.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format } from '@/index.ts';
import { formatter } from '@/plugins/quarter.ts';
describe('plugins', () => {
describe('formatter', () => {
test('Q — first month of each quarter', () => {
expect(format(new Date(2025, 0, 1), 'Q', { plugins: [formatter] })).toBe('1'); // Jan → Q1
expect(format(new Date(2025, 3, 1), 'Q', { plugins: [formatter] })).toBe('2'); // Apr → Q2
expect(format(new Date(2025, 6, 1), 'Q', { plugins: [formatter] })).toBe('3'); // Jul → Q3
expect(format(new Date(2025, 9, 1), 'Q', { plugins: [formatter] })).toBe('4'); // Oct → Q4
});
test('Q — last month of each quarter', () => {
expect(format(new Date(2025, 2, 31), 'Q', { plugins: [formatter] })).toBe('1'); // Mar → Q1
expect(format(new Date(2025, 5, 30), 'Q', { plugins: [formatter] })).toBe('2'); // Jun → Q2
expect(format(new Date(2025, 8, 30), 'Q', { plugins: [formatter] })).toBe('3'); // Sep → Q3
expect(format(new Date(2025, 11, 31), 'Q', { plugins: [formatter] })).toBe('4'); // Dec → Q4
});
test('Q — middle month of each quarter', () => {
expect(format(new Date(2025, 1, 14), 'Q', { plugins: [formatter] })).toBe('1'); // Feb → Q1
expect(format(new Date(2025, 4, 15), 'Q', { plugins: [formatter] })).toBe('2'); // May → Q2
expect(format(new Date(2025, 7, 16), 'Q', { plugins: [formatter] })).toBe('3'); // Aug → Q3
expect(format(new Date(2025, 10, 11), 'Q', { plugins: [formatter] })).toBe('4'); // Nov → Q4
});
});
});
================================================
FILE: tests/plugins/timestamp.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { format } from '@/index.ts';
import { formatter } from '@/plugins/timestamp.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
describe('formatter', () => {
test('t — Unix timestamp in seconds (floor)', () => {
expect(format(new Date(0), 't', { plugins: [formatter] })).toBe('0'); // epoch
expect(format(new Date(1000), 't', { plugins: [formatter] })).toBe('1'); // exactly 1 second
expect(format(new Date(999), 't', { plugins: [formatter] })).toBe('0'); // just under 1 second → floor
expect(format(new Date(1999), 't', { plugins: [formatter] })).toBe('1'); // 1.999 s → floor to 1
expect(format(new Date(1000000000000), 't', { plugins: [formatter] })).toBe('1000000000'); // Sep 9, 2001
expect(format(new Date(-1), 't', { plugins: [formatter] })).toBe('-1'); // -1ms → floor to -1s
expect(format(new Date(-1500), 't', { plugins: [formatter] })).toBe('-2'); // -1.5s → floor to -2s
expect(format(new Date(-1000), 't', { plugins: [formatter] })).toBe('-1'); // exactly -1s
expect(format(new Date(2147483648000), 't', { plugins: [formatter] })).toBe('2147483648'); // year 2038+
});
test('T — Unix timestamp in milliseconds', () => {
expect(format(new Date(0), 'T', { plugins: [formatter] })).toBe('0'); // epoch
expect(format(new Date(1000), 'T', { plugins: [formatter] })).toBe('1000'); // 1 second
expect(format(new Date(999), 'T', { plugins: [formatter] })).toBe('999'); // 999 ms
expect(format(new Date(1000000000000), 'T', { plugins: [formatter] })).toBe('1000000000000');
});
});
});
================================================
FILE: tests/plugins/two-digit-year.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { parse } from '@/index.ts';
import { parser as year } from '@/plugins/two-digit-year.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
test('YY gregory', () => {
expect(parse('00-05-05', 'YY-MM-DD', { plugins: [year] })).toEqual(new Date(2000, 5 - 1, 5));
expect(parse('69-05-05', 'YY-MM-DD', { plugins: [year] })).toEqual(new Date(2069, 5 - 1, 5));
expect(parse('70-05-05', 'YY-MM-DD', { plugins: [year] })).toEqual(new Date(1970, 5 - 1, 5));
expect(parse('99-05-05', 'YY-MM-DD', { plugins: [year] })).toEqual(new Date(1999, 5 - 1, 5));
});
test('YY buddhist', () => {
expect(parse('00-05-05', 'YY-MM-DD', { plugins: [year], calendar: 'buddhist' })).toEqual(new Date(2600 - 543, 5 - 1, 5));
expect(parse('12-05-05', 'YY-MM-DD', { plugins: [year], calendar: 'buddhist' })).toEqual(new Date(2612 - 543, 5 - 1, 5));
expect(parse('13-05-05', 'YY-MM-DD', { plugins: [year], calendar: 'buddhist' })).toEqual(new Date(2513 - 543, 5 - 1, 5));
expect(parse('99-05-05', 'YY-MM-DD', { plugins: [year], calendar: 'buddhist' })).toEqual(new Date(2599 - 543, 5 - 1, 5));
});
});
================================================
FILE: tests/plugins/week.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { format } from '@/index.ts';
import { formatter } from '@/plugins/week.ts';
describe('plugins', () => {
describe('formatter', () => {
test('W', () => {
// 2024-01-01 is Monday - ISO week year equals calendar year, no offset bug
expect(format(new Date(2024, 0, 1), 'W', { plugins: [formatter] })).toBe('1');
// last day of ISO week 1 (Sunday)
expect(format(new Date(2024, 0, 7), 'W', { plugins: [formatter] })).toBe('1');
// first day of ISO week 2 (Monday)
expect(format(new Date(2024, 0, 8), 'W', { plugins: [formatter] })).toBe('2');
// mid-year (Thursday is the anchor day of its own ISO week)
expect(format(new Date(2024, 6, 4), 'W', { plugins: [formatter] })).toBe('27');
// late December still in ISO week year 2024
expect(format(new Date(2024, 11, 23), 'W', { plugins: [formatter] })).toBe('52');
// Dec 30, 2024 (Monday) belongs to ISO week 1 of 2025
expect(format(new Date(2024, 11, 30), 'W', { plugins: [formatter] })).toBe('1');
// Jan 1, 2021 (Friday) belongs to ISO week 53 of 2020
expect(format(new Date(2021, 0, 1), 'W', { plugins: [formatter] })).toBe('53');
// Dec 31, 2015 (Thursday) belongs to ISO week 53 of 2015
expect(format(new Date(2015, 11, 31), 'W', { plugins: [formatter] })).toBe('53');
// Jan 6, 2025 (Monday) is ISO week 2 of 2025
expect(format(new Date(2025, 0, 6), 'W', { plugins: [formatter] })).toBe('2');
});
test('WW', () => {
expect(format(new Date(2024, 0, 1), 'WW', { plugins: [formatter] })).toBe('01');
expect(format(new Date(2024, 0, 8), 'WW', { plugins: [formatter] })).toBe('02');
expect(format(new Date(2024, 6, 4), 'WW', { plugins: [formatter] })).toBe('27');
expect(format(new Date(2024, 11, 23), 'WW', { plugins: [formatter] })).toBe('52');
expect(format(new Date(2021, 0, 1), 'WW', { plugins: [formatter] })).toBe('53');
});
test('GGGG', () => {
// ISO week year equals calendar year
expect(format(new Date(2024, 0, 1), 'GGGG', { plugins: [formatter] })).toBe('2024');
// Dec 30, 2024 crosses into ISO week year 2025
expect(format(new Date(2024, 11, 30), 'GGGG', { plugins: [formatter] })).toBe('2025');
// Jan 1, 2021 crosses back into ISO week year 2020
expect(format(new Date(2021, 0, 1), 'GGGG', { plugins: [formatter] })).toBe('2020');
});
test('GG', () => {
expect(format(new Date(2024, 0, 1), 'GG', { plugins: [formatter] })).toBe('24');
expect(format(new Date(2024, 11, 30), 'GG', { plugins: [formatter] })).toBe('25');
expect(format(new Date(2021, 0, 1), 'GG', { plugins: [formatter] })).toBe('20');
});
test('GGGG and YYYY differ at year boundaries', () => {
// Dec 30, 2024: calendar year = 2024, ISO week year = 2025
expect(format(new Date(2024, 11, 30), 'YYYY GGGG', { plugins: [formatter] })).toBe('2024 2025');
});
test('edge cases - min date', () => {
const minDate = new Date(1, 0 - 1900 * 12, 1);
// Jan 1, year 1 (Monday): Thursday of that week is Jan 4, year 1
// → ISO week year = 1, first week of year 1
expect(format(minDate, 'GGGG', { plugins: [formatter] })).toBe('0001');
expect(format(minDate, 'GG', { plugins: [formatter] })).toBe('01');
expect(format(minDate, 'G', { plugins: [formatter] })).toBe('1');
expect(format(minDate, 'W', { plugins: [formatter] })).toBe('1');
expect(format(minDate, 'WW', { plugins: [formatter] })).toBe('01');
});
test('edge cases - year 9999', () => {
const maxDate = new Date(9999, 11, 31);
// Dec 31, 9999 (Friday): Thursday of that week is Dec 30, 9999
// → ISO week year = 9999 (does NOT cross into 10000)
expect(format(maxDate, 'GGGG', { plugins: [formatter] })).toBe('9999');
expect(format(maxDate, 'GG', { plugins: [formatter] })).toBe('99');
expect(format(maxDate, 'G', { plugins: [formatter] })).toBe('9999');
expect(format(maxDate, 'W', { plugins: [formatter] })).toBe('52');
expect(format(maxDate, 'WW', { plugins: [formatter] })).toBe('52');
});
});
});
================================================
FILE: tests/plugins/zonename.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { format } from '@/index.ts';
import { formatter as zonename } from '@/plugins/zonename.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
import Tokyo from '@/timezones/Asia/Tokyo.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('plugins', () => {
test('z', () => {
const now = new Date(2025, 1 - 1, 1, 0);
expect(format(now, 'z', { plugins: [zonename] })).toBe('UTC');
expect(format(now, 'z', { plugins: [zonename], timeZone: 'UTC' })).toBe('UTC');
expect(format(now, 'z', { plugins: [zonename], timeZone: Los_Angeles })).toBe('PST');
expect(format(now, 'z', { plugins: [zonename], timeZone: Tokyo })).toBe('JST');
});
test('zz', () => {
const now = new Date(2025, 1 - 1, 1, 0);
expect(format(now, 'zz', { plugins: [zonename] })).toBe('Coordinated Universal Time');
expect(format(now, 'zz', { plugins: [zonename], timeZone: 'UTC' })).toBe('Coordinated Universal Time');
expect(format(now, 'zz', { plugins: [zonename], timeZone: Los_Angeles })).toBe('Pacific Standard Time');
expect(format(now, 'zz', { plugins: [zonename], timeZone: Tokyo })).toBe('Japan Standard Time');
});
});
================================================
FILE: tests/preparse.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { preparse } from '@/index.ts';
import { parser } from '@/plugins/day-of-week.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('YYYY', () => {
test('0000', () => {
const dt = { Y: 0, _index: 4, _length: 4, _match: 1 };
expect(preparse('0000', 'YYYY')).toEqual(dt);
});
test('0001', () => {
const dt = { Y: 1, _index: 4, _length: 4, _match: 1 };
expect(preparse('0001', 'YYYY')).toEqual(dt);
});
test('0099', () => {
const dt = { Y: 99, _index: 4, _length: 4, _match: 1 };
expect(preparse('0099', 'YYYY')).toEqual(dt);
});
test('0100', () => {
const dt = { Y: 100, _index: 4, _length: 4, _match: 1 };
expect(preparse('0100', 'YYYY')).toEqual(dt);
});
test('1899', () => {
const dt = { Y: 1899, _index: 4, _length: 4, _match: 1 };
expect(preparse('1899', 'YYYY')).toEqual(dt);
});
test('1900', () => {
const dt = { Y: 1900, _index: 4, _length: 4, _match: 1 };
expect(preparse('1900', 'YYYY')).toEqual(dt);
});
test('1969', () => {
const dt = { Y: 1969, _index: 4, _length: 4, _match: 1 };
expect(preparse('1969', 'YYYY')).toEqual(dt);
});
test('1970', () => {
const dt = { Y: 1970, _index: 4, _length: 4, _match: 1 };
expect(preparse('1970', 'YYYY')).toEqual(dt);
});
test('1999', () => {
const dt = { Y: 1999, _index: 4, _length: 4, _match: 1 };
expect(preparse('1999', 'YYYY')).toEqual(dt);
});
test('2000', () => {
const dt = { Y: 2000, _index: 4, _length: 4, _match: 1 };
expect(preparse('2000', 'YYYY')).toEqual(dt);
});
test('9999', () => {
const dt = { Y: 9999, _index: 4, _length: 4, _match: 1 };
expect(preparse('9999', 'YYYY')).toEqual(dt);
});
});
describe('Y', () => {
test('0', () => {
const dt = { Y: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'Y')).toEqual(dt);
});
test('1', () => {
const dt = { Y: 1, _index: 1, _length: 1, _match: 1 };
expect(preparse('1', 'Y')).toEqual(dt);
});
test('99', () => {
const dt = { Y: 99, _index: 2, _length: 2, _match: 1 };
expect(preparse('99', 'Y')).toEqual(dt);
});
test('100', () => {
const dt = { Y: 100, _index: 3, _length: 3, _match: 1 };
expect(preparse('100', 'Y')).toEqual(dt);
});
test('1899', () => {
const dt = { Y: 1899, _index: 4, _length: 4, _match: 1 };
expect(preparse('1899', 'Y')).toEqual(dt);
});
test('1900', () => {
const dt = { Y: 1900, _index: 4, _length: 4, _match: 1 };
expect(preparse('1900', 'Y')).toEqual(dt);
});
test('1969', () => {
const dt = { Y: 1969, _index: 4, _length: 4, _match: 1 };
expect(preparse('1969', 'Y')).toEqual(dt);
});
test('1970', () => {
const dt = { Y: 1970, _index: 4, _length: 4, _match: 1 };
expect(preparse('1970', 'Y')).toEqual(dt);
});
test('1999', () => {
const dt = { Y: 1999, _index: 4, _length: 4, _match: 1 };
expect(preparse('1999', 'Y')).toEqual(dt);
});
test('2000', () => {
const dt = { Y: 2000, _index: 4, _length: 4, _match: 1 };
expect(preparse('2000', 'Y')).toEqual(dt);
});
test('9999', () => {
const dt = { Y: 9999, _index: 4, _length: 4, _match: 1 };
expect(preparse('9999', 'Y')).toEqual(dt);
});
});
describe('MMMM', () => {
test('January', () => {
const dt = { M: 1, _index: 7, _length: 7, _match: 1 };
expect(preparse('January', 'MMMM')).toEqual(dt);
});
test('December', () => {
const dt = { M: 12, _index: 8, _length: 8, _match: 1 };
expect(preparse('December', 'MMMM')).toEqual(dt);
});
test('Zero', () => {
const dt = { _index: 0, _length: 4, _match: 0 };
expect(preparse('Zero', 'MMMM')).toEqual(dt);
});
});
describe('MMM', () => {
test('January', () => {
const dt = { M: 1, _index: 3, _length: 3, _match: 1 };
expect(preparse('Jan', 'MMM')).toEqual(dt);
});
test('December', () => {
const dt = { M: 12, _index: 3, _length: 3, _match: 1 };
expect(preparse('Dec', 'MMM')).toEqual(dt);
});
test('Zero', () => {
const dt = { _index: 0, _length: 4, _match: 0 };
expect(preparse('Zero', 'MMM')).toEqual(dt);
});
});
describe('MM', () => {
test('01', () => {
const dt = { M: 1, _index: 2, _length: 2, _match: 1 };
expect(preparse('01', 'MM')).toEqual(dt);
});
test('12', () => {
const dt = { M: 12, _index: 2, _length: 2, _match: 1 };
expect(preparse('12', 'MM')).toEqual(dt);
});
test('00', () => {
const dt = { M: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'MM')).toEqual(dt);
});
});
describe('M', () => {
test('1', () => {
const dt = { M: 1, _index: 1, _length: 1, _match: 1 };
expect(preparse('1', 'M')).toEqual(dt);
});
test('12', () => {
const dt = { M: 12, _index: 2, _length: 2, _match: 1 };
expect(preparse('12', 'M')).toEqual(dt);
});
test('0', () => {
const dt = { M: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'M')).toEqual(dt);
});
});
describe('DD', () => {
test('01', () => {
const dt = { D: 1, _index: 2, _length: 2, _match: 1 };
expect(preparse('01', 'DD')).toEqual(dt);
});
test('31', () => {
const dt = { D: 31, _index: 2, _length: 2, _match: 1 };
expect(preparse('31', 'DD')).toEqual(dt);
});
test('00', () => {
const dt = { D: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'DD')).toEqual(dt);
});
});
describe('D', () => {
test('1', () => {
const dt = { D: 1, _index: 1, _length: 1, _match: 1 };
expect(preparse('1', 'D')).toEqual(dt);
});
test('31', () => {
const dt = { D: 31, _index: 2, _length: 2, _match: 1 };
expect(preparse('31', 'D')).toEqual(dt);
});
test('0', () => {
const dt = { D: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'D')).toEqual(dt);
});
});
describe('HH', () => {
test('00', () => {
const dt = { H: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'HH')).toEqual(dt);
});
test('23', () => {
const dt = { H: 23, _index: 2, _length: 2, _match: 1 };
expect(preparse('23', 'HH')).toEqual(dt);
});
test('24', () => {
const dt = { H: 24, _index: 2, _length: 2, _match: 1 };
expect(preparse('24', 'HH')).toEqual(dt);
});
});
describe('H', () => {
test('0', () => {
const dt = { H: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'H')).toEqual(dt);
});
test('23', () => {
const dt = { H: 23, _index: 2, _length: 2, _match: 1 };
expect(preparse('23', 'H')).toEqual(dt);
});
test('24', () => {
const dt = { H: 24, _index: 2, _length: 2, _match: 1 };
expect(preparse('24', 'H')).toEqual(dt);
});
});
describe('hh', () => {
test('00', () => {
const dt = { h: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'hh')).toEqual(dt);
});
test('11', () => {
const dt = { h: 11, _index: 2, _length: 2, _match: 1 };
expect(preparse('11', 'hh')).toEqual(dt);
});
test('12', () => {
const dt = { h: 12, _index: 2, _length: 2, _match: 1 };
expect(preparse('12', 'hh')).toEqual(dt);
});
});
describe('h', () => {
test('0', () => {
const dt = { h: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'h')).toEqual(dt);
});
test('11', () => {
const dt = { h: 11, _index: 2, _length: 2, _match: 1 };
expect(preparse('11', 'h')).toEqual(dt);
});
test('12', () => {
const dt = { h: 12, _index: 2, _length: 2, _match: 1 };
expect(preparse('12', 'h')).toEqual(dt);
});
});
describe('AA', () => {
test('A.M.', () => {
const dt = { A: 0, _index: 4, _length: 4, _match: 1 };
expect(preparse('A.M.', 'AA')).toEqual(dt);
});
test('P.M.', () => {
const dt = { A: 1, _index: 4, _length: 4, _match: 1 };
expect(preparse('P.M.', 'AA')).toEqual(dt);
});
test('M.M.', () => {
const dt = { _index: 0, _length: 4, _match: 0 };
expect(preparse('M.M.', 'AA')).toEqual(dt);
});
});
describe('A', () => {
test('AM', () => {
const dt = { A: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('AM', 'A')).toEqual(dt);
});
test('PM', () => {
const dt = { A: 1, _index: 2, _length: 2, _match: 1 };
expect(preparse('PM', 'A')).toEqual(dt);
});
test('MM', () => {
const dt = { _index: 0, _length: 2, _match: 0 };
expect(preparse('MM', 'A')).toEqual(dt);
});
});
describe('aa', () => {
test('a.m.', () => {
const dt = { A: 0, _index: 4, _length: 4, _match: 1 };
expect(preparse('a.m.', 'aa')).toEqual(dt);
});
test('p.m.', () => {
const dt = { A: 1, _index: 4, _length: 4, _match: 1 };
expect(preparse('p.m.', 'aa')).toEqual(dt);
});
test('m.m.', () => {
const dt = { _index: 0, _length: 4, _match: 0 };
expect(preparse('m.m.', 'aa')).toEqual(dt);
});
});
describe('a', () => {
test('am', () => {
const dt = { A: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('am', 'a')).toEqual(dt);
});
test('pm', () => {
const dt = { A: 1, _index: 2, _length: 2, _match: 1 };
expect(preparse('pm', 'a')).toEqual(dt);
});
test('mm', () => {
const dt = { _index: 0, _length: 2, _match: 0 };
expect(preparse('mm', 'a')).toEqual(dt);
});
});
describe('mm', () => {
test('00', () => {
const dt = { m: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'mm')).toEqual(dt);
});
test('59', () => {
const dt = { m: 59, _index: 2, _length: 2, _match: 1 };
expect(preparse('59', 'mm')).toEqual(dt);
});
test('60', () => {
const dt = { m: 60, _index: 2, _length: 2, _match: 1 };
expect(preparse('60', 'mm')).toEqual(dt);
});
});
describe('m', () => {
test('0', () => {
const dt = { m: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 'm')).toEqual(dt);
});
test('59', () => {
const dt = { m: 59, _index: 2, _length: 2, _match: 1 };
expect(preparse('59', 'm')).toEqual(dt);
});
test('60', () => {
const dt = { m: 60, _index: 2, _length: 2, _match: 1 };
expect(preparse('60', 'm')).toEqual(dt);
});
});
describe('ss', () => {
test('00', () => {
const dt = { s: 0, _index: 2, _length: 2, _match: 1 };
expect(preparse('00', 'ss')).toEqual(dt);
});
test('59', () => {
const dt = { s: 59, _index: 2, _length: 2, _match: 1 };
expect(preparse('59', 'ss')).toEqual(dt);
});
test('60', () => {
const dt = { s: 60, _index: 2, _length: 2, _match: 1 };
expect(preparse('60', 'ss')).toEqual(dt);
});
});
describe('s', () => {
test('0', () => {
const dt = { s: 0, _index: 1, _length: 1, _match: 1 };
expect(preparse('0', 's')).toEqual(dt);
});
test('59', () => {
const dt = { s: 59, _index: 2, _length: 2, _match: 1 };
expect(preparse('59', 's')).toEqual(dt);
});
test('60', () => {
const dt = { s: 60, _index: 2, _length: 2, _match: 1 };
expect(preparse('60', 's')).toEqual(dt);
});
});
describe('SSS', () => {
test('000', () => {
const dt = { S: 0, _index: 3, _length: 3, _match: 1 };
expect(preparse('000', 'SSS')).toEqual(dt);
});
test('456', () => {
const dt = { S: 456, _index: 3, _length: 3, _match: 1 };
expect(preparse('456', 'SSS')).toEqual(dt);
});
test('999', () => {
const dt = { S: 999, _index: 3, _length: 3, _match: 1 };
expect(preparse('999', 'SSS')).toEqual(dt);
});
});
describe('SS', () => {
test('000', () => {
const dt = { S: 0, _index: 2, _length: 3, _match: 1 };
expect(preparse('000', 'SS')).toEqual(dt);
});
test('456', () => {
const dt = { S: 450, _index: 2, _length: 3, _match: 1 };
expect(preparse('456', 'SS')).toEqual(dt);
});
test('999', () => {
const dt = { S: 990, _index: 2, _length: 3, _match: 1 };
expect(preparse('999', 'SS')).toEqual(dt);
});
});
describe('S', () => {
test('000', () => {
const dt = { S: 0, _index: 1, _length: 3, _match: 1 };
expect(preparse('000', 'S')).toEqual(dt);
});
test('456', () => {
const dt = { S: 400, _index: 1, _length: 3, _match: 1 };
expect(preparse('456', 'S')).toEqual(dt);
});
test('999', () => {
const dt = { S: 900, _index: 1, _length: 3, _match: 1 };
expect(preparse('999', 'S')).toEqual(dt);
});
});
describe('ZZ', () => {
test('-08:00', () => {
const dt = { Z: 480, _index: 6, _length: 6, _match: 1 };
expect(preparse('-08:00', 'ZZ')).toEqual(dt);
});
test('+00:00', () => {
const dt = { Z: 0, _index: 6, _length: 6, _match: 1 };
expect(preparse('+00:00', 'ZZ')).toEqual(dt);
});
test('+09:00', () => {
const dt = { Z: -540, _index: 6, _length: 6, _match: 1 };
expect(preparse('+09:00', 'ZZ')).toEqual(dt);
});
});
describe('Z', () => {
test('-0800', () => {
const dt = { Z: 480, _index: 5, _length: 5, _match: 1 };
expect(preparse('-0800', 'Z')).toEqual(dt);
});
test('+0000', () => {
const dt = { Z: 0, _index: 5, _length: 5, _match: 1 };
expect(preparse('+0000', 'Z')).toEqual(dt);
});
test('+0900', () => {
const dt = { Z: -540, _index: 5, _length: 5, _match: 1 };
expect(preparse('+0900', 'Z')).toEqual(dt);
});
});
describe('special tokens', () => {
test('ellipsis', () => {
const dt1 = { Y: 2000, M: 1, D: 1, h: 0, m: 0, _index: 19, _length: 19, _match: 5 };
expect(preparse('2000-01-01 00:00 xx', 'YYYY-MM-DD hh:mm...')).toEqual(dt1);
});
});
describe('options', () => {
test('hour12: h11', () => {
const dt1 = { Y: 2000, M: 1, D: 1, A: 0, h: 0, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 00:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(dt1);
const dt2 = { Y: 2000, M: 1, D: 1, A: 0, h: 11, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(dt2);
const dt3 = { Y: 2000, M: 1, D: 1, A: 1, h: 12, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(dt3);
const dt4 = { Y: 2000, M: 1, D: 1, A: 1, h: 11, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h11' })).toEqual(dt4);
});
test('hour12: h12', () => {
const dt1 = { Y: 2000, M: 1, D: 1, A: 0, h: 12, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(dt1);
const dt2 = { Y: 2000, M: 1, D: 1, A: 0, h: 11, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 11:00 AM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(dt2);
const dt3 = { Y: 2000, M: 1, D: 1, A: 1, h: 12, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 12:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(dt3);
const dt4 = { Y: 2000, M: 1, D: 1, A: 1, h: 11, m: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 11:00 PM', 'YYYY-MM-DD hh:mm A', { hour12: 'h12' })).toEqual(dt4);
});
test('hour24: h23', () => {
const dt1 = { Y: 2000, M: 1, D: 1, H: 0, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 00:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toEqual(dt1);
const dt2 = { Y: 2000, M: 1, D: 1, H: 1, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 01:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toEqual(dt2);
const dt3 = { Y: 2000, M: 1, D: 1, H: 23, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 23:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toEqual(dt3);
const dt4 = { Y: 2000, M: 1, D: 1, H: 24, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 24:00', 'YYYY-MM-DD HH:mm', { hour24: 'h23' })).toEqual(dt4);
});
test('hour24: h24', () => {
const dt1 = { Y: 2000, M: 1, D: 1, H: 0, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 00:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toEqual(dt1);
const dt2 = { Y: 2000, M: 1, D: 1, H: 1, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 01:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toEqual(dt2);
const dt3 = { Y: 2000, M: 1, D: 1, H: 23, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 23:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toEqual(dt3);
const dt4 = { Y: 2000, M: 1, D: 1, H: 24, m: 0, _index: 16, _length: 16, _match: 5 };
expect(preparse('2000-01-01 24:00', 'YYYY-MM-DD HH:mm', { hour24: 'h24' })).toEqual(dt4);
});
test('ignoreCase: true', () => {
const dt = { Y: 2025, M: 5, D: 4, h: 11, A: 0, _index: 23, _length: 23, _match: 6 };
expect(preparse('2025 May 4 Sunday 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(dt);
expect(preparse('2025 may 4 sunday 11 am', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(dt);
expect(preparse('2025 MAY 4 SUNDAY 11 AM', 'YYYY MMMM D dddd h A', { ignoreCase: true, plugins: [parser] })).toEqual(dt);
});
test('calendar: buddhist', () => {
const dt1 = { Y: 2000, M: 1, D: 1, h: 12, m: 0, A: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('2000-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(dt1);
const dt2 = { Y: 9999, M: 1, D: 1, h: 12, m: 0, A: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('9999-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(dt2);
const dt3 = { Y: 544, M: 1, D: 1, h: 12, m: 0, A: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('0544-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(dt3);
const dt4 = { Y: 543, M: 1, D: 1, h: 12, m: 0, A: 0, _index: 19, _length: 19, _match: 6 };
expect(preparse('0543-01-01 12:00 AM', 'YYYY-MM-DD hh:mm A', { calendar: 'buddhist' })).toEqual(dt4);
});
});
================================================
FILE: tests/subtract.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { subtract } from '@/index.ts';
describe('subtraction', () => {
test('One year is 365 days', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2015, 11, 31, 23, 59, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(365);
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: 365 });
expect(subtract(date1, date2).toHours().value).toBe(365 * 24);
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 365 * 24 });
expect(subtract(date1, date2).toMinutes().value).toBe(365 * 24 * 60);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 365 * 24 * 60 });
expect(subtract(date1, date2).toSeconds().value).toBe(365 * 24 * 60 * 60);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 365 * 24 * 60 * 60 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(365 * 24 * 60 * 60 * 1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 365 * 24 * 60 * 60 * 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(365 * 24 * 60 * 60 * 1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 365 * 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(365 * 24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 365 * 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One year is 365 days (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2015, 11, 31, 23, 59, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-365);
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: -365 });
expect(subtract(date2, date1).toHours().value).toBe(-365 * 24);
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: -365 * 24 });
expect(subtract(date2, date1).toMinutes().value).toBe(-365 * 24 * 60);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -365 * 24 * 60 });
expect(subtract(date2, date1).toSeconds().value).toBe(-365 * 24 * 60 * 60);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -365 * 24 * 60 * 60 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-365 * 24 * 60 * 60 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -365 * 24 * 60 * 60 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-365 * 24 * 60 * 60 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -365 * 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-365 * 24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -365 * 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One month is 31 days', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 12, 31, 23, 59, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(31);
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: 31 });
expect(subtract(date1, date2).toHours().value).toBe(31 * 24);
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 31 * 24 });
expect(subtract(date1, date2).toMinutes().value).toBe(31 * 24 * 60);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 31 * 24 * 60 });
expect(subtract(date1, date2).toSeconds().value).toBe(31 * 24 * 60 * 60);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 31 * 24 * 60 * 60 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(31 * 24 * 60 * 60 * 1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 31 * 24 * 60 * 60 * 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(31 * 24 * 60 * 60 * 1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 31 * 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(31 * 24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 31 * 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One month is 31 days (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 12, 31, 23, 59, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-31);
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: -31 });
expect(subtract(date2, date1).toHours().value).toBe(-31 * 24);
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: -31 * 24 });
expect(subtract(date2, date1).toMinutes().value).toBe(-31 * 24 * 60);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -31 * 24 * 60 });
expect(subtract(date2, date1).toSeconds().value).toBe(-31 * 24 * 60 * 60);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -31 * 24 * 60 * 60 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-31 * 24 * 60 * 60 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -31 * 24 * 60 * 60 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-31 * 24 * 60 * 60 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -31 * 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-31 * 24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -31 * 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One day', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 32, 23, 59, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(1);
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: 1 });
expect(subtract(date1, date2).toHours().value).toBe(24);
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 24 });
expect(subtract(date1, date2).toMinutes().value).toBe(24 * 60);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 24 * 60 });
expect(subtract(date1, date2).toSeconds().value).toBe(24 * 60 * 60);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 24 * 60 * 60 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(24 * 60 * 60 * 1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 24 * 60 * 60 * 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(24 * 60 * 60 * 1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One day (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 32, 23, 59, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-1);
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 0, days: -1 });
expect(subtract(date2, date1).toHours().value).toBe(-1 * 24);
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: -1 * 24 });
expect(subtract(date2, date1).toMinutes().value).toBe(-1 * 24 * 60);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -1 * 24 * 60 });
expect(subtract(date2, date1).toSeconds().value).toBe(-1 * 24 * 60 * 60);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1 * 24 * 60 * 60 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-1 * 24 * 60 * 60 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1 * 24 * 60 * 60 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-1 * 24 * 60 * 60 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -1 * 24 * 60 * 60 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-1 * 24 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -1 * 24 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One hour', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 24, 59, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(1 / 24);
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 1, days: 0 });
expect(subtract(date1, date2).toHours().value).toBe(1);
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: 1 });
expect(subtract(date1, date2).toMinutes().value).toBe(60);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 60 });
expect(subtract(date1, date2).toSeconds().value).toBe(60 * 60);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 60 * 60 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(60 * 60 * 1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 60 * 60 * 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(60 * 60 * 1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 60 * 60 * 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 60 * 60 * 1000 * 1000 * 1000 });
});
test('One hour (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 24, 59, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-1 / 24);
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: -1, days: 0 });
expect(subtract(date2, date1).toHours().value).toBe(-1);
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 0, hours: -1 });
expect(subtract(date2, date1).toMinutes().value).toBe(-1 * 60);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -1 * 60 });
expect(subtract(date2, date1).toSeconds().value).toBe(-1 * 60 * 60);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1 * 60 * 60 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-1 * 60 * 60 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1 * 60 * 60 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-1 * 60 * 60 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -1 * 60 * 60 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-1 * 60 * 60 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -1 * 60 * 60 * 1000 * 1000 * 1000 });
});
test('One minute', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 23, 60, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(1 / (24 * 60));
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 1, hours: 0, days: 0 });
expect(subtract(date1, date2).toHours().value).toBe(1 / 60);
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 1, hours: 0 });
expect(subtract(date1, date2).toMinutes().value).toBe(1);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: 1 });
expect(subtract(date1, date2).toSeconds().value).toBe(60);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 60 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(60 * 1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 60 * 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(60 * 1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 60 * 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(60 * 1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 60 * 1000 * 1000 * 1000 });
});
test('One minute (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 23, 60, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-1 / (24 * 60));
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -1, hours: 0, days: 0 });
expect(subtract(date2, date1).toHours().value).toBe(-1 / 60);
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -1, hours: 0 });
expect(subtract(date2, date1).toMinutes().value).toBe(-1);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 0, minutes: -1 });
expect(subtract(date2, date1).toSeconds().value).toBe(-1 * 60);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1 * 60 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-1 * 60 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1 * 60 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-1 * 60 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -1 * 60 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-1 * 60 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -1 * 60 * 1000 * 1000 * 1000 });
});
test('One second', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 23, 59, 60, 999);
expect(subtract(date1, date2).toDays().value).toBe(1 / (24 * 60 * 60));
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 1, minutes: 0, hours: 0, days: 0 });
expect(subtract(date1, date2).toHours().value).toBe(1 / (60 * 60));
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 1, minutes: 0, hours: 0 });
expect(subtract(date1, date2).toMinutes().value).toBe(1 / 60);
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 1, minutes: 0 });
expect(subtract(date1, date2).toSeconds().value).toBe(1);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: 1 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(1000);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1000 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(1000 * 1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 1000 * 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(1000 * 1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 1000 * 1000 * 1000 });
});
test('One second (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 999);
const date2 = new Date(2014, 11, 31, 23, 59, 60, 999);
expect(subtract(date2, date1).toDays().value).toBe(-1 / (24 * 60 * 60));
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1, minutes: 0, hours: 0, days: 0 });
expect(subtract(date2, date1).toHours().value).toBe(-1 / (60 * 60));
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1, minutes: 0, hours: 0 });
expect(subtract(date2, date1).toMinutes().value).toBe(-1 / 60);
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1, minutes: 0 });
expect(subtract(date2, date1).toSeconds().value).toBe(-1);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 0, seconds: -1 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-1 * 1000);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1 * 1000 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-1 * 1000 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -1 * 1000 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-1 * 1000 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -1 * 1000 * 1000 * 1000 });
});
test('One millisecond', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 998);
const date2 = new Date(2014, 11, 31, 23, 59, 59, 999);
expect(subtract(date1, date2).toDays().value).toBe(1 / (24 * 60 * 60 * 1000));
expect(subtract(date1, date2).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1, seconds: 0, minutes: 0, hours: 0, days: 0 });
expect(subtract(date1, date2).toHours().value).toBe(1 / (60 * 60 * 1000));
expect(subtract(date1, date2).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1, seconds: 0, minutes: 0, hours: 0 });
expect(subtract(date1, date2).toMinutes().value).toBe(1 / (60 * 1000));
expect(subtract(date1, date2).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1, seconds: 0, minutes: 0 });
expect(subtract(date1, date2).toSeconds().value).toBe(1 / 1000);
expect(subtract(date1, date2).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1, seconds: 0 });
expect(subtract(date1, date2).toMilliseconds().value).toBe(1);
expect(subtract(date1, date2).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: 1 });
expect(subtract(date1, date2).toMicroseconds().value).toBe(1000);
expect(subtract(date1, date2).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 1000 });
expect(subtract(date1, date2).toNanoseconds().value).toBe(1000 * 1000);
expect(subtract(date1, date2).toNanoseconds().toParts()).toEqual({ nanoseconds: 1000 * 1000 });
});
test('One millisecond (reverse)', () => {
const date1 = new Date(2014, 11, 31, 23, 59, 59, 998);
const date2 = new Date(2014, 11, 31, 23, 59, 59, 999);
expect(subtract(date2, date1).toDays().value).toBe(-1 / (24 * 60 * 60 * 1000));
expect(subtract(date2, date1).toDays().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1, seconds: 0, minutes: 0, hours: 0, days: 0 });
expect(subtract(date2, date1).toHours().value).toBe(-1 / (60 * 60 * 1000));
expect(subtract(date2, date1).toHours().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1, seconds: 0, minutes: 0, hours: 0 });
expect(subtract(date2, date1).toMinutes().value).toBe(-1 / (60 * 1000));
expect(subtract(date2, date1).toMinutes().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1, seconds: 0, minutes: 0 });
expect(subtract(date2, date1).toSeconds().value).toBe(-1 / 1000);
expect(subtract(date2, date1).toSeconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1, seconds: 0 });
expect(subtract(date2, date1).toMilliseconds().value).toBe(-1);
expect(subtract(date2, date1).toMilliseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: 0, milliseconds: -1 });
expect(subtract(date2, date1).toMicroseconds().value).toBe(-1 * 1000);
expect(subtract(date2, date1).toMicroseconds().toParts()).toEqual({ nanoseconds: 0, microseconds: -1 * 1000 });
expect(subtract(date2, date1).toNanoseconds().value).toBe(-1 * 1000 * 1000);
expect(subtract(date2, date1).toNanoseconds().toParts()).toEqual({ nanoseconds: -1 * 1000 * 1000 });
});
test('format', () => {
const date1 = new Date(2025, 6, 13, 8, 42, 53, 998);
const date2 = new Date(2025, 6, 14, 9, 43, 54, 999);
expect(subtract(date1, date2).toDays().format('D[days] H[hours] m[minites] s[seconds] S.fffFFF')).toBe('1days 1hours 1minites 1seconds 1.000000');
expect(subtract(date1, date2).toHours().format('H[hours] m[minites] s[seconds] S.fffFFF')).toBe('25hours 1minites 1seconds 1.000000');
expect(subtract(date1, date2).toMinutes().format('m[minites] s[seconds] S.fffFFF')).toBe('1501minites 1seconds 1.000000');
expect(subtract(date1, date2).toSeconds().format('s[seconds] S.fffFFF')).toBe('90061seconds 1.000000');
expect(subtract(date1, date2).toMilliseconds().format('S.fffFFF')).toBe('90061001.000000');
expect(subtract(date1, date2).toMicroseconds().format('f.FFF')).toBe('90061001000.000');
expect(subtract(date1, date2).toNanoseconds().format('F')).toBe('90061001000000');
});
test('format (reverse)', () => {
const date1 = new Date(2025, 6, 13, 8, 42, 53, 998);
const date2 = new Date(2025, 6, 14, 9, 43, 54, 999);
expect(subtract(date2, date1).toDays().format('D[days] H[hours] m[minites] s[seconds] S.fffFFF')).toBe('-1days 1hours 1minites 1seconds 1.000000');
expect(subtract(date2, date1).toHours().format('H[hours] m[minites] s[seconds] S.fffFFF')).toBe('-25hours 1minites 1seconds 1.000000');
expect(subtract(date2, date1).toMinutes().format('m[minites] s[seconds] S.fffFFF')).toBe('-1501minites 1seconds 1.000000');
expect(subtract(date2, date1).toSeconds().format('s[seconds] S.fffFFF')).toBe('-90061seconds 1.000000');
expect(subtract(date2, date1).toMilliseconds().format('S.fffFFF')).toBe('-90061001.000000');
expect(subtract(date2, date1).toMicroseconds().format('f.FFF')).toBe('-90061001000.000');
expect(subtract(date2, date1).toNanoseconds().format('F')).toBe('-90061001000000');
});
});
================================================
FILE: tests/timezones/timezones.spec.ts
================================================
import { expect, test, describe } from 'vitest';
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
import type { TimeZone } from '@/zone.ts';
const importModules = async (path: string) => {
const items = await readdir(path, { recursive: true, withFileTypes: true });
const modules: TimeZone[] = [];
for (const item of items) {
if (item.isFile()) {
modules.push((await import(join('../../', item.parentPath, item.name)) as { default: TimeZone }).default);
}
}
return modules;
};
describe('Timezones', async () => {
const modules = await importModules('src/timezones/');
for (const module of modules) {
test.concurrent('timezone', () => {
expect(typeof module === 'object').toBe(true);
expect('zone_name' in module).toBe(true);
expect(typeof module.zone_name === 'string').toBe(true);
expect('gmt_offset' in module).toBe(true);
expect(Array.isArray(module.gmt_offset)).toBe(true);
});
}
});
================================================
FILE: tests/transform.spec.ts
================================================
import { describe, expect, test, beforeAll } from 'vitest';
import { compile, format, transform } from '@/index.ts';
import Los_Angeles from '@/timezones/America/Los_Angeles.ts';
import New_York from '@/timezones/America/New_York.ts';
import Tokyo from '@/timezones/Asia/Tokyo.ts';
beforeAll(() => (process.env.TZ = 'UTC'));
describe('transform', () => {
test('D/M/YYYY => M/D/YYYY', () => {
expect(transform('3/8/2020', 'D/M/YYYY', 'M/D/YYYY')).toBe('8/3/2020');
});
test('HH:mm => hh:mm A', () => {
expect(transform('13:05', 'HH:mm', 'hh:mm A')).toBe('01:05 PM');
});
test('HH:mm => hh:mm A, output as UTC', () => {
const utc = format(new Date(2020, 3, 1, 13, 5), 'hh:mm A');
expect(transform('13:05', 'HH:mm', 'hh:mm A')).toBe(utc);
});
test('D/M/YYYY => M/D/YYYY, with compile', () => {
const arg1 = compile('D/M/YYYY');
const arg2 = compile('M/D/YYYY');
expect(transform('3/8/2020', arg1, arg2)).toBe('8/3/2020');
});
test('transform EST to PST', () => {
const string1 = '2021-11-07T04:00:00.000'; // UTC-5
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'November 7 2021 1:00:00.000'; // UTC-8
// 2021-11-07T04:00:00.000 => November 7 2021 1:00:00.000
expect(transform(string1, formatString1, formatString2, { timeZone: New_York }, { timeZone: Los_Angeles })).toBe(string2);
});
test('transform EST to PDT (End of DST)', () => {
const string1 = '2021-11-07T03:59:59.999'; // UTC-5
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'November 7 2021 1:59:59.999'; // UTC-7
// 2021-11-07T03:59:59.999 => November 7 2021 1:59:59.999
expect(transform(string1, formatString1, formatString2, { timeZone: New_York }, { timeZone: Los_Angeles })).toBe(string2);
});
test('transform EDT to PST', () => {
const string1 = '2021-03-14T05:59:59.999'; // UTC-4
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'March 14 2021 1:59:59.999'; // UTC-8
// 2021-03-14T05:59:59.999 => March 14 2021 1:59:59.999
expect(transform(string1, formatString1, formatString2, { timeZone: New_York }, { timeZone: Los_Angeles })).toBe(string2);
});
test('transform EDT to PDT (Start of DST)', () => {
const string1 = '2021-03-14T06:00:00.000'; // UTC-4
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'March 14 2021 3:00:00.000'; // UTC-7
// 2021-03-14T06:00:00.000 => March 14 2021 3:00:00.000
expect(transform(string1, formatString1, formatString2, { timeZone: New_York }, { timeZone: Los_Angeles })).toBe(string2);
});
test('transform PST to JST', () => {
const string1 = '2021-03-14T01:59:59.999'; // UTC-8
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'March 14 2021 18:59:59.999'; // UTC+9
// 2021-03-14T01:59:59.999 => March 14 2021 18:59:59.999
expect(transform(string1, formatString1, formatString2, { timeZone: Los_Angeles }, { timeZone: Tokyo })).toBe(string2);
});
test('transform PDT to JST', () => {
const string1 = '2021-03-14T03:00:00.000'; // UTC-7
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'March 14 2021 19:00:00.000'; // UTC+9
// 2021-03-14T03:00:00.000 => March 14 2021 19:00:00.000
expect(transform(string1, formatString1, formatString2, { timeZone: Los_Angeles }, { timeZone: Tokyo })).toBe(string2);
});
test('transform UTC to JST', () => {
const string1 = '2021-03-14T03:00:00.000'; // UTC+0
const formatString1 = 'YYYY-MM-DD[T]HH:mm:ss.SSS';
const formatString2 = 'MMMM D YYYY H:mm:ss.SSS';
const string2 = 'March 14 2021 12:00:00.000'; // UTC+9
// 2021-03-14T03:00:00.000 => March 14 2021 12:00:00.000
expect(transform(string1, formatString1, formatString2, { timeZone: 'UTC' }, { timeZone: Tokyo })).toBe(string2);
});
});
================================================
FILE: tests/utils.spec.ts
================================================
import { describe, expect, test } from 'vitest';
import { isLeapYear, isSameDay, getDaysInMonth, getISOWeekYear, getISOWeek } from '@/index.ts';
test('isLeapYear', () => {
expect(isLeapYear(4)).toBe(true);
expect(isLeapYear(100)).toBe(false);
expect(isLeapYear(400)).toBe(true);
expect(isLeapYear(2024)).toBe(true);
expect(isLeapYear(2025)).toBe(false);
});
test('isSameDay', () => {
const date1 = new Date(2025, 6, 18, 0, 0, 0, 0);
const date2 = new Date(2025, 6, 18, 23, 59, 59, 999);
expect(isSameDay(date1, date2)).toBe(true);
const date3 = new Date(2025, 6, 18, 23, 59, 59, 999);
const date4 = new Date(2025, 6, 19, 0, 0, 0, 0);
expect(isSameDay(date3, date4)).toBe(false);
});
describe('getDaysInMonth', () => {
test('Date overload', () => {
expect(getDaysInMonth(new Date(2024, 0, 15))).toBe(31); // Jan
expect(getDaysInMonth(new Date(2024, 1, 15))).toBe(29); // Feb (leap year)
expect(getDaysInMonth(new Date(2025, 1, 15))).toBe(28); // Feb (non-leap year)
expect(getDaysInMonth(new Date(2024, 3, 15))).toBe(30); // Apr
expect(getDaysInMonth(new Date(2024, 11, 15))).toBe(31); // Dec
});
test('(year, month) overload', () => {
expect(getDaysInMonth(2024, 1)).toBe(31); // Jan
expect(getDaysInMonth(2024, 2)).toBe(29); // Feb (leap year)
expect(getDaysInMonth(2025, 2)).toBe(28); // Feb (non-leap year)
expect(getDaysInMonth(2024, 4)).toBe(30); // Apr
expect(getDaysInMonth(2024, 12)).toBe(31); // Dec
});
test('leap year rules', () => {
expect(getDaysInMonth(2000, 2)).toBe(29); // divisible by 400 → leap
expect(getDaysInMonth(2100, 2)).toBe(28); // divisible by 100, not 400 → non-leap
expect(getDaysInMonth(2400, 2)).toBe(29); // divisible by 400 → leap
expect(getDaysInMonth(2024, 2)).toBe(29); // divisible by 4, not 100 → leap
expect(getDaysInMonth(2023, 2)).toBe(28); // not divisible by 4 → non-leap
});
test('Date overload for year < 100', () => {
// year 4 is a leap year
const date = new Date(4, 1 - 1900 * 12, 15);
expect(getDaysInMonth(date)).toBe(29);
});
});
describe('getISOWeekYear', () => {
test('Date overload', () => {
expect(getISOWeekYear(new Date(2024, 0, 1))).toBe(2024); // Mon Jan 1 → week 1 of 2024
expect(getISOWeekYear(new Date(2024, 11, 29))).toBe(2024); // Sun Dec 29 → week 52 of 2024
expect(getISOWeekYear(new Date(2024, 11, 30))).toBe(2025); // Mon Dec 30 → week 1 of 2025
expect(getISOWeekYear(new Date(2021, 0, 1))).toBe(2020); // Fri Jan 1 → week 53 of 2020
});
test('(year, month, day) overload', () => {
expect(getISOWeekYear(2024, 1, 1)).toBe(2024); // Jan 1
expect(getISOWeekYear(2024, 12, 30)).toBe(2025); // Dec 30
expect(getISOWeekYear(2021, 1, 1)).toBe(2020); // Jan 1
});
test('Date overload for year < 100', () => {
// year 3: Dec 29 is a Monday → its Thursday is Jan 1 of year 4 → iso year = 4
const date1 = new Date(3, 11 - 1900 * 12, 29);
expect(getISOWeekYear(date1)).toBe(4);
// year 4: Jan 5 is a Monday → belongs to week 2 of year 4
const date2 = new Date(4, 0 - 1900 * 12, 5);
expect(getISOWeekYear(date2)).toBe(4);
});
test('(year, month, day) overload for year < 100', () => {
// year 3: Dec 29 is a Monday → its Thursday is Jan 1 of year 4 → iso year = 4
expect(getISOWeekYear(3, 12, 29)).toBe(4);
// year 4: Jan 5 is a Monday → belongs to week 2 of year 4
expect(getISOWeekYear(4, 1, 5)).toBe(4);
});
});
describe('getISOWeek', () => {
test('Date overload', () => {
expect(getISOWeek(new Date(2024, 0, 1))).toBe(1); // Mon Jan 1 → week 1
expect(getISOWeek(new Date(2024, 0, 7))).toBe(1); // Sun Jan 7 → still week 1
expect(getISOWeek(new Date(2024, 0, 8))).toBe(2); // Mon Jan 8 → week 2
expect(getISOWeek(new Date(2024, 6, 4))).toBe(27); // Thu Jul 4 → week 27
expect(getISOWeek(new Date(2024, 11, 23))).toBe(52); // Mon Dec 23 → week 52
expect(getISOWeek(new Date(2024, 11, 30))).toBe(1); // Mon Dec 30 → week 1 of 2025
expect(getISOWeek(new Date(2021, 0, 1))).toBe(53); // Fri Jan 1 → week 53 of 2020
expect(getISOWeek(new Date(2015, 11, 31))).toBe(53); // Thu Dec 31 → week 53 of 2015
});
test('(year, month, day) overload', () => {
expect(getISOWeek(2024, 1, 1)).toBe(1); // Jan 1
expect(getISOWeek(2024, 1, 8)).toBe(2); // Jan 8
expect(getISOWeek(2024, 7, 4)).toBe(27); // Jul 4
expect(getISOWeek(2021, 1, 1)).toBe(53); // Jan 1
});
test('Date overload for year < 100', () => {
// year 4: Jan 5 is a Monday → belongs to week 2 of year 4
const date1 = new Date(4, 0 - 1900 * 12, 5);
expect(getISOWeek(date1)).toBe(2);
// year 4: Dec 31 is a Friday → its Thursday is Dec 30 → week 53 of year 4
const date2 = new Date(4, 11 - 1900 * 12, 31);
expect(getISOWeek(date2)).toBe(53);
});
test('(year, month, day) overload for year < 100', () => {
// year 4: Jan 5 is a Monday → belongs to week 2 of year 4
expect(getISOWeek(4, 1, 5)).toBe(2);
// year 4: Dec 31 is a Friday → its Thursday is Dec 30 → week 53 of year 4
expect(getISOWeek(4, 12, 31)).toBe(53);
});
});
================================================
FILE: tools/locale.ts
================================================
const compare = (array1: string[], array2: string[]) => {
if (array1.length !== array2.length) {
return false;
}
for (let i = 0, len = array1.length; i < len; i++) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
};
const getMonths = (locale: string, style: 'long' | 'short' | 'narrow') => {
const options1: Intl.DateTimeFormatOptions = { hour12: true, weekday: 'long', year: 'numeric', month: style, hour: 'numeric' };
const options2: Intl.DateTimeFormatOptions = { ...options1, day: 'numeric' };
const dtf1 = new Intl.DateTimeFormat(locale, options1);
const dtf2 = new Intl.DateTimeFormat(locale, options2);
const months1 = [];
const months2 = [];
for (let i = 0; i < 12; i++) {
months1.push(dtf1.formatToParts(new Date(2024, i, 1, 0)).find(p => p.type === 'month')?.value ?? '');
}
for (let i = 0; i < 12; i++) {
months2.push(dtf2.formatToParts(new Date(2024, i, 1, 0)).find(p => p.type === 'month')?.value ?? '');
}
return compare(months1, months2) ? months1 : [months1, months2];
};
const getWeekdays = (locale: string, style: 'long' | 'short' | 'narrow') => {
const options1: Intl.DateTimeFormatOptions = { hour12: true, weekday: style, year: 'numeric', month: 'long', hour: 'numeric' };
const options2: Intl.DateTimeFormatOptions = { ...options1, day: 'numeric' };
const dtf1 = new Intl.DateTimeFormat(locale, options1);
const dtf2 = new Intl.DateTimeFormat(locale, options2);
const weekdays1 = [];
const weekdays2 = [];
for (let i = 1; i <= 7; i++) {
weekdays1.push(dtf1.formatToParts(new Date(2024, 11, i, 0)).find(p => p.type === 'weekday')?.value ?? '');
}
for (let i = 1; i <= 7; i++) {
weekdays2.push(dtf2.formatToParts(new Date(2024, 11, i, 0)).find(p => p.type === 'weekday')?.value ?? '');
}
return compare(weekdays1, weekdays2) ? weekdays1 : [weekdays1, weekdays2];
};
const getDayPeriod = (locale: string) => {
const options1: Intl.DateTimeFormatOptions = { hour12: true, hour: 'numeric' };
const options2: Intl.DateTimeFormatOptions = { ...options1, weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
const dtf1 = new Intl.DateTimeFormat(locale, options1);
const dtf2 = new Intl.DateTimeFormat(locale, options2);
const dayperiod1: string[] = [];
const dayperiod2: string[] = [];
for (let i = 0; i < 24; i++) {
const value = dtf1.formatToParts(new Date(2024, 11, 1, i)).find(p => p.type === 'dayPeriod')?.value ?? '';
if (!dayperiod1.includes(value)) {
dayperiod1.push(value);
}
}
for (let i = 0; i < 24; i++) {
const value = dtf2.formatToParts(new Date(2024, 11, 1, i)).find(p => p.type === 'dayPeriod')?.value ?? '';
if (!dayperiod2.includes(value)) {
dayperiod2.push(value);
}
}
return compare(dayperiod1, dayperiod2) ? dayperiod1 : [dayperiod1, dayperiod2];
};
const getParts = (locale: string) => {
const options: Intl.DateTimeFormatOptions = {
hour12: false, weekday: 'long',
year: 'numeric', month: 'long', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
timeZone: 'UTC', timeZoneName: 'longOffset'
};
const parts = new Intl.DateTimeFormat(locale, options).formatToParts(new Date());
return parts.filter(part => part.type !== 'literal');
};
const getDate = (locale: string) => {
const options: Intl.DateTimeFormatOptions = {
hour12: true, weekday: 'short',
year: 'numeric', month: 'short', day: 'numeric',
hour: 'numeric', minute: 'numeric', second: 'numeric', fractionalSecondDigits: 3,
timeZone: 'Europe/Paris', timeZoneName: 'longOffset'
};
return new Intl.DateTimeFormat(locale, options).format(new Date());
};
const locale = process.argv[2];
if (!locale) {
process.exit();
}
const list = {
MMMM: getMonths(locale, 'long'),
MMM: getMonths(locale, 'short'),
dddd: getWeekdays(locale, 'long'),
ddd: getWeekdays(locale, 'short'),
dd: getWeekdays(locale, 'narrow'),
A: getDayPeriod(locale)
};
console.log(JSON.stringify(list, undefined, 2));
console.log(JSON.stringify(getParts(locale), undefined, 2));
console.log(getDate(locale));
================================================
FILE: tools/timezone.ts
================================================
/**
* @description
* This script generates timezone data files from a CSV file obtained from timezonedb.com,
* creates individual timezone files, and an integrated timezone file for easier imports.
*/
import { readFile, mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import prettier from 'prettier';
import type { TimeZone } from '@/zone.ts';
const createTimeZones = (csv: string) => {
const map = new Map();
csv.split('\n').forEach(line => {
const [zone_name, , , , gmt_offset] = line.split(',');
if (zone_name && !zone_name.endsWith('UTC')) {
const data = map.get(zone_name);
if (data) {
if (!data.gmt_offset.includes(+gmt_offset)) {
data.gmt_offset.push(+gmt_offset);
}
} else {
map.set(zone_name, { zone_name, gmt_offset: [+gmt_offset] });
}
}
});
return map;
};
const getPath = (timezone: TimeZone) => {
const re = /[^/]+$/;
return {
dir: join('src', 'timezones', timezone.zone_name.replace(re, '')),
name: re.exec(timezone.zone_name)?.[0] ?? ''
};
};
const format = (timezone: TimeZone) => {
const code = `export default {
zone_name: '${timezone.zone_name}',
gmt_offset: ${JSON.stringify(timezone.gmt_offset.sort((a, b) => b - a))}
};`;
return prettier.format(code, { parser: 'typescript', singleQuote: true, trailingComma: 'none' });
};
const sortMap = (map: Map) => {
return Array.from(map.values()).sort((a, b) => getPath(a).name.localeCompare(getPath(b).name));
};
const formatAll = (map: Map) => {
const code = [];
code.push('import { TimeZone } from \'@/zone.ts\';');
for (const timezone of sortMap(map)) {
const name = getPath(timezone).name.replace(/-/g, '_');
code.push(`export const ${name}: TimeZone = {
zone_name: '${timezone.zone_name}',
gmt_offset: ${JSON.stringify(timezone.gmt_offset.sort((a, b) => b - a))}
};`);
}
return prettier.format(code.join('\n\n'), { parser: 'typescript', singleQuote: true, trailingComma: 'none' });
};
const path = process.argv[2];
if (!path) {
console.error('Please provide a CSV file path');
process.exit();
}
const csv = await readFile(path, 'utf8');
const map = createTimeZones(csv);
// Generate individual timezone files
for (const timezone of map.values()) {
const { dir, name } = getPath(timezone);
await mkdir(dir, { recursive: true });
await writeFile(join(dir, `${name}.ts`), await format(timezone));
}
// Generate integrated timezone file
await writeFile(join('src', 'timezone.ts'), await formatAll(map));
================================================
FILE: tools/zonename.ts
================================================
/**
* @description
* This script reads timezone data from a CSV file obtained from timezonedb.com,
* extracts unique timezone names, and generates a mapping of timezone long names
* to their abbreviations by analyzing timezone name variations across historical time periods.
*/
import { readFile } from 'node:fs/promises';
import prettier from 'prettier';
import zonenames from '@/zonenames.ts';
const getTimezone = async (path: string) => {
try {
const csv = await readFile(path, 'utf8');
const timezones = new Set();
csv.split('\n').forEach(line => {
const [zone_name] = line.split(',');
if (zone_name) {
timezones.add(zone_name);
}
});
return Array.from(timezones);
} catch (e) {
console.error(`Error reading CSV file: ${path}`);
console.error(e);
return [];
}
};
// Extract the timezone name from the formatted date parts
const getTimezoneName = (dtf: Intl.DateTimeFormat, time: number) => {
return dtf.formatToParts(time).find(part => part.type === 'timeZoneName')?.value.replace(/^GMT([+-].+)?$/, '') ?? '';
};
// Extract timezone names and their abbreviations by analyzing historical time periods
const getTimezoneNames = (timeZone: string, names: Record) => {
const dtf = new Intl.DateTimeFormat('en-US', { timeZone, timeZoneName: 'long' });
const map = new Map();
const errors = new Set();
const start = Date.UTC(0, -12 * 16, 1); // year 1884
const end = Date.UTC(new Date().getUTCFullYear(), 0, 1); // current year
const step = 30 * 24 * 60 * 60 * 1000; // 30days
for (let i = start, len = end; i < len; i += step) {
const timeZoneName = getTimezoneName(dtf, i);
if (timeZoneName && !map.has(timeZoneName)) {
const abbreviation = names[timeZoneName];
if (abbreviation) {
map.set(timeZoneName, abbreviation);
} else {
errors.add(timeZoneName);
}
}
}
return { names: map, errors };
};
const sort = (timeZoneNames: Map) => {
return new Map(Array.from(timeZoneNames).sort((a, b) => a[0].localeCompare(b[0])));
};
const format = (code: Map) => {
return prettier.format(`export default {
${Array.from(code).map(([key, value]) => `'${key}': '${value}',`).join('\n')}
};`, { parser: 'typescript', singleQuote: true, trailingComma: 'none' });
};
const path = process.argv[2];
if (!path) {
console.error('Please provide a CSV file path');
process.exit();
}
const timezones = await getTimezone(path);
const timeZoneNames = new Map();
const errorNames = new Set();
// Extract timezone names and their abbreviations by analyzing historical time periods
timezones.forEach(timeZone => {
const { names, errors } = getTimezoneNames(timeZone, zonenames);
for (const [key, value] of names.entries()) {
timeZoneNames.set(key, value);
}
errors.forEach(err => errorNames.add(err));
});
// Add missing timezone names from the existing mapping
for (const [key, value] of Object.entries(zonenames)) {
if (!timeZoneNames.has(key)) {
timeZoneNames.set(key, value);
}
}
if (errorNames.size) {
// Log any timezone names that were not found in the existing mapping
console.error('Not Found');
console.error(Array.from(errorNames));
} else {
// Output the final mapping of timezone long names to their abbreviations
process.stdout.write(await format(sort(timeZoneNames)));
}
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"lib": ["ES2021", "DOM"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ESNext", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
"paths": { "@/*": ["./src/*"] }, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
"allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
"emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
// "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
// "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"exclude": ["docs", "dist", "node_modules"]
}
================================================
FILE: vitest.config.ts
================================================
import { defineConfig } from 'vitest/config';
import { resolve } from 'path';
export default defineConfig({
resolve: {
alias: {
'@': resolve(__dirname, './src')
}
},
test: {
coverage: {
exclude: ['src/**/*.d.ts'],
include: ['src/**/*.ts'],
provider: 'v8',
reporter: ['json-summary', 'html']
},
include: ['tests/**/*.spec.ts']
}
});