Kot razvijalec programske opreme ne morete pobegniti pred manipulacijo z datumi. Skoraj vsaka aplikacija, ki jo razvije razvijalec, bo imela neko komponento, pri kateri je treba od uporabnika pridobiti datum / čas, ga shraniti v bazo podatkov in uporabniku prikazati nazaj.
Vprašajte katerega koli programerja o njihovih izkušnjah z rokovanjem z datumi in časovnimi pasovi in verjetno bo delil nekaj vojnih zgodb. Ravnanje z datumskimi in časovnimi polji zagotovo ni raketna znanost, vendar je pogosto lahko dolgočasno in nagnjeno k napakam.
Obstaja na stotine člankov o tej temi, vendar je večina bodisi preveč akademskih, osredotočenih na drobne podrobnosti, bodisi preveč razdrobljenih, saj vsebujejo kratke delčke kode, ne da bi jim priložili veliko razlage. Ta poglobljeni vodnik za manipulacijo z datumom vam bo pomagal razumeti programske koncepte in najboljše prakse, pomembne za čas in datum, ne da bi vam bilo treba brskati po morju informacij o tej temi.
V tem članku vam bom pomagal jasno razmisliti o poljih za datum in čas ter predlagal nekaj najboljših praks, s katerimi se boste lahko izognili peklu z datumom in časom. Tu bomo raziskali nekatere ključne koncepte, ki so potrebni za pravilno manipulacijo z vrednostmi datuma in časa, formate, ki so primerni za shranjevanje vrednosti DateTime in njihov prenos prek API-jev in še več.
Za začetek je pravi odgovor za produkcijsko kodo skoraj vedno uporaba ustrezne knjižnice, namesto da bi se valjali sami. Potencialne težave z izračunom datuma, o katerih razpravljamo v tem članku, so le vrh ledene gore, vendar jih je še vedno koristno vedeti o knjižnici s knjižnico ali brez nje.
Datumske knjižnice vam na več načinov olajšajo življenje. Zelo poenostavijo razčlenjevanje datumov, aritmetične in logične operacije datuma ter oblikovanje datuma. Za sprednji in zadnji del najdete zanesljivo knjižnico datumov, ki bo za vas izvedla večino težkega dviganja.
Vendar pogosto uporabljamo knjižnice datumov, ne da bi razmišljali o tem, kako datum / čas dejansko deluje. Datum / čas je kompleksen koncept. Napake, ki se pojavijo zaradi nepravilnega razumevanja, je izredno težko razumeti in odpraviti, tudi s pomočjo knjižnic datumov. Kot programer morate razumeti osnove in znati ceniti težave, ki jih knjižnice z datumom rešujejo, da jih kar najbolje izkoristijo.
Prav tako vas lahko knjižnice z datumi / časi pripeljejo le tako daleč. Vse knjižnice datumov delujejo tako, da vam omogočajo dostop do priročnih podatkovnih struktur, ki predstavljajo datum. Če podatke pošiljate in prejemate prek API-ja REST, boste na koncu morali datum pretvoriti v niz in obratno, ker JSON nima izvorne podatkovne strukture, ki bi predstavljala DateTime. Koncepti, ki sem jih tukaj opisal, vam bodo pomagali, da se izognete nekaterim pogostim težavam, ki bi se lahko pojavile pri teh preoblikovanjih datuma in niza do datuma.
Opomba: Čeprav sem uporabil JavaScript kot programski jezik, obravnavan v tem članku, gre za splošne koncepte, ki v veliki meri veljajo za skoraj vse programske jezike in njihove knjižnice datumov. Torej, tudi če še nikoli niste napisali vrstice JavaScripta, vas prosimo, da nadaljujete z branjem, saj v članku komajda predvidevam kakršno koli predhodno znanje JavaScript.
DateTime je zelo natančen čas. Pomislimo na to. Ko pišem v ta članek, ura na mojem prenosniku kaže 21. julija 13:29. Temu pravimo »lokalni čas«, čas, ki ga vidim na stenskih urah okoli sebe in na ročni uri.
Dajte ali vzemite si nekaj minut, če prosim prijateljico, da se dobimo v bližnji kavarni ob 15.00, lahko pričakujem, da jo bom tam videl približno takrat. Podobno ne bi prišlo do zmede, če bi na primer rekel, na primer: 'se dobimo v uri in pol.' O tem se rutinsko pogovarjamo z ljudmi, ki živijo v istem mestu ali časovnem pasu.
Pomislimo na drugačen scenarij: prijatelju, ki živi v Uppsali na Švedskem, naj povem, da se želim z njim pogovoriti ob 17. uri. Pošljem mu sporočilo: 'Hej, Anton, pogovorimo se ob 17. uri.' Takoj dobim odgovor: 'Vaš ali moj čas?'
Anton mi pove, da živi v srednjeevropskem časovnem pasu, ki je UTC + 01: 00. Živim v UTC + 05: 45. To pomeni, da ko sem 17:00, kjer živim, je 17:00 - 05:45 = 11:15 UTC, kar pomeni 11:15 UTC + 01:00 = 12:15 v Uppsali, kot nalašč za oba o nas.
Upoštevajte tudi razliko med časovnim pasom (srednjeevropski čas) in odmikom časovnega pasu (UTC + 05: 45). Države se lahko odločijo za spremembo časovnih pasov za poletni čas tudi iz političnih razlogov. Skoraj vsako leto se pravila spremenijo vsaj v eni državi, kar pomeni, da je treba vsako kodo s temi pravili posodabljati - vredno je razmisliti, od česa je odvisna vaša kodna baza za vsako stopnjo vaše aplikacije.
To je še en dober razlog, da priporočamo, da se v večini primerov s časovnimi pasovi ukvarja le sprednji del. Kaj se zgodi, ko se pravila, ki jih uporablja mehanizem zbirke podatkov, ne ujemajo s pravili vašega sprednjega ali zadnjega dela?
Ta problem upravljanja dveh različnih različic časa, glede na uporabnika in glede na splošno sprejet standard, je težaven, še toliko bolj v svetu programiranja, kjer je natančnost ključnega pomena in celo ena sekunda lahko močno spremeni. Prvi korak k reševanju teh težav je shranjevanje DateTime v UTC.
Poenotenje časa je čudovito, ker moram shraniti samo čas UTC in dokler poznam časovni pas uporabnika, lahko vedno pretvorim v njihov čas. Če poznam lokalni čas uporabnika in poznam njegov časovni pas, ga lahko pretvorim v UTC.
Toda datume in ure lahko določite v različnih oblikah zapisa. Za datum lahko napišete “30. julij” ali “30. julij” ali “7. 7.” (ali 30. 7., odvisno od tega, kje živite). Zaenkrat lahko pišete »21:30« ali »2130«.
Znanstveniki po vsem svetu so se zbrali za reševanje tega problema in se odločili za obliko, ki opisuje čas, ki je programerjem zelo všeč, ker je kratek in natančen. Radi ga imenujemo »format datuma ISO«, ki je poenostavljena različica razširjenega formata ISO-8601 in izgleda tako:
Za 00:00 ali UTC namesto tega uporabimo 'Z', kar pomeni čas Zulu, drugo ime za UTC.
Preden začnemo z najboljšimi praksami, se bomo seznanili z manipulacijo z datumi z uporabo JavaScript, da bomo razumeli skladnjo in splošne koncepte. Čeprav uporabljamo JavaScript, lahko te podatke enostavno prilagodite svojemu priljubljenemu programskemu jeziku.
Z aritmetiko datuma bomo rešili pogoste težave, povezane z datumom, na katere naleti večina razvijalcev.
Moj cilj je, da vam je prijetno ustvariti datumski predmet iz niza in iz njega izvleči komponente. Pri tem vam lahko pomaga knjižnica zmenkov, vendar je vedno bolje razumeti, kako se to počne v zakulisju.
Ko si roke umažemo z datumom / uro, potem lažje razmišljamo o težavah, s katerimi se soočamo, izvlečemo najboljše prakse in gremo naprej. Če želite preskočiti na najboljše prakse, vas prosimo, da to storite, vendar vam toplo priporočam, da vsaj pregledate spodnji odsek z aritmetiko datuma.
Programski jeziki vsebujejo koristne konstrukcije, ki nam olajšajo življenje. JavaScript Date
predmet je ena taka stvar. Ponuja priročne metode za pridobitev trenutnega datuma in ure, shranjevanje datuma v spremenljivko, izvajanje aritmetike datuma in oblikovanje datuma glede na uporabnikov jezik.
Zaradi razlik med implementacijami brskalnika in nepravilnim ravnanjem s poletnim časom (DST) odvisno od predmeta Date za kritične aplikacije ni priporočljivo in verjetno bi morali uporabljati knjižnico DateTime, kot je Luxon, date-fns ali dayjs . (Karkoli uporabljate, se izogibajte nekoč priljubljenemu Moment.js, ki se pogosto imenuje moment
, kot je prikazano v kodi, saj je zdaj zastarel.)
Toda v izobraževalne namene bomo uporabili metode, ki jih ponuja objekt Date (), da se naučimo, kako JavaScript obravnava DateTime.
const currentDate = new Date();
Če konstruktorju Date ne posredujete ničesar, vrnjeni predmet datuma vsebuje trenutni datum in čas.
kupna moč bo večja takrat
Nato ga lahko formatirate tako, da izvleče samo datumski del, kot sledi:
const currentDate = new Date(); const currentDayOfMonth = currentDate.getDate(); const currentMonth = currentDate.getMonth(); // Be careful! January is 0, not 1 const currentYear = currentDate.getFullYear(); const dateString = currentDayOfMonth + '-' + (currentMonth + 1) + '-' + currentYear; // '27-11-2020'
Opomba: Pasja “Januar je 0” je pogosta, vendar ne univerzalna. Preden ga začnete uporabljati, je vredno dvakrat preveriti dokumentacijo katerega koli jezika (ali oblike konfiguracije: npr. Cron temelji predvsem na 1).
Če želite namesto tega dobiti trenutni časovni žig, lahko ustvarite nov objekt Date in uporabite metodo getTime ().
const currentDate = new Date(); const timestamp = currentDate.getTime();
V JavaScript je časovni žig število milisekund, ki so pretekle od 1. januarja 1970.
Če ne nameravate podpirati Pretvorba niza v datumski objekt JavaScript se izvaja na različne načine. Konstruktor predmeta Date sprejema najrazličnejše formate datumov: Upoštevajte, da vam ni treba vključiti dneva v tednu, ker lahko JS določi dan v tednu za kateri koli datum. Kot ločene argumente lahko prenesete tudi leto, mesec, dan, ure, minute in sekunde: Seveda lahko vedno uporabite obliko zapisa datuma ISO: Vendar pa lahko naletite na težave, če časovnega pasu ne navedete izrecno! Vsako od teh vam bo omogočilo 25. julij 2016 00:00:00 po lokalnem času. Če uporabljate format ISO, tudi če navedete samo datum in ne čas in časovni pas, bo samodejno sprejel časovni pas kot UTC. To pomeni da: Na srečo ima sodobni JavaScript nekaj standardnih funkcij za internacionalizacijo, ki so vgrajene v standard Za to bomo potrebovali dva predmeta: a Če bi namesto tega želeli nizozemski format (D / M / LLLL), bi samo posredovali drugo kodo kulture Ali daljša oblika ameriškega formata z navedenim imenom meseca: Zdaj, če smo želeli pravilno redno obliko na dan v mesecu - to je »14.« namesto samo »14«, je to na žalost treba nekoliko rešiti, ker Na žalost, Če morate podpirati starejše brskalnike, kot je IE pred različico 11, je oblikovanje datuma v JavaScript strožje, ker ni bilo standardnih funkcij za oblikovanje datuma, kot je V PHP na primer funkcija Uporabite lahko različna kombinacija črk pred tem Če ste prepričani v obliko, ki jo želite uporabiti, je najbolje, da posamezne bite izvlečete s pomočjo funkcij JavaScript, ki smo jih pokrili zgoraj, in sami ustvarite niz. Datum lahko dobimo v obliki MM / DD / LLLL kot Težava te rešitve je v tem, da lahko datumom daje nedosledno dolžino, ker so nekateri meseci in dnevi v mesecu enomestni, drugi pa dvomestni. To je lahko na primer težavno, če datum prikazujete v stolpcu tabele, ker se datumi ne ujemajo. To lahko rešimo s pomočjo funkcije 'pad', ki doda začetno 0. Zdaj dobimo pravilen datum v obliki MM / DD / LLLL z uporabo: Če namesto tega želimo DD-MM-LLLL, je postopek podoben: Dvignimo ante in poskusimo datum natisniti v obliki »Mesečni datum, leto«. Potrebovali bomo preslikavo mesečnih indeksov v imena: Nekateri radi datum prikažejo kot 1. januar 2013. Ni problema, potrebujemo le pomožno funkcijo Dan iz tedna je enostavno določiti po datumu, zato dodajte, da v: Večja točka je v tem, da ko dobite številke, izpisane z datuma, je oblikovanje večinoma povezano z nizi. Ko enkrat veste, kako razčleniti datum in ga formatirati, je sprememba datuma iz ene oblike v drugo le kombinacija obeh. Če imate na primer datum v obliki 21. julij 2013 in želite spremeniti obliko na 21-07-2013, jo lahko dosežete tako: Načini oblikovanja datuma, o katerih smo razpravljali zgoraj, bi morali delovati v večini aplikacij, če pa res želite lokalizirati oblikovanje datuma, predlagam, da uporabite … Nam daje nekaj takega Če spremenite jezik v »en-US«, bo namesto tega »26. julij 2016«. Opazite, kako se je spremenilo oblikovanje, vendar so možnosti prikaza še vedno enake - zelo uporabna funkcija. Kot je prikazano v prejšnjem razdelku, novejša tehnika, osnovana na Z Če sem namesto tega želel cel mesec »julij«, spremenim samo parameter meseca v možnostih na »dolg«. JavaScript zame ureja vse. Za en-US zdaj dobim 26. julij 2016. Opomba: Če želite, da brskalnik samodejno uporablja lokacijo uporabnika, lahko kot prvi parameter prenesete »undefined«. Če želite prikazati številčno različico datuma in se ne želite truditi z MM / DD / LLLL v primerjavi z DD / MM / LLLL za različne kraje, predlagam naslednjo preprosto rešitev: V mojem računalniku to odda To izpiše Za lokalizacijo prikaza časa in datuma lahko uporabite tudi nekatere druge povezane funkcije: Tu je primer dodajanja 20 dni na datum JavaScript (tj. Ugotavljanje datuma 20 dni po znanem datumu): Izvirni datumski objekt zdaj predstavlja datum 20 dni po 20. juliju in Za izračun relativnih časovnih žigov z natančnejšo razliko kot celotni dnevi lahko uporabite Kot pri vsem drugem, povezanem z datumom, ima tudi primerjava datumov svoje težave. Najprej moramo ustvariti datumske predmete. Na srečo,, = vse delo. Primerjava 19. julija 2014 in 18. julija 2014 je tako preprosta kot: Preverjanje enakovrednosti je bolj zapleteno, saj sta dva datumska predmeta, ki predstavljata isti datum, še vedno dva različna datumska predmeta in ne bosta enaka. Primerjava nizov datumov je slaba ideja, ker na primer »20. julij 2014« in »20. julij 2014« predstavljata isti datum, vendar imata različni predstavitvi nizov. Spodnji delček prikazuje prvo točko: To bo prikazalo Ta poseben primer lahko popravimo s primerjavo celoštevilčnih ekvivalentov datumov (njihovih časovnih žigov) na naslednji način: Ta primer sem videl na mnogih mestih, vendar mi ni všeč, ker običajno ne ustvarite datuma iz drugega datuma. Zato menim, da je primer pomemben samo z akademskega vidika. To zahteva tudi, da se oba predmeta Date nanašata na enako sekundo, medtem ko boste morda želeli vedeti le, ali se nanašata na isti dan, uro ali minuto. Oglejmo si bolj praktičen primer. Poskušate primerjati, ali je rojstni dan, ki ga je uporabnik vnesel, enak srečnemu datumu, ki ga dobite od API-ja. Oba sta predstavljala isti datum, žal pa vaš uporabnik ne bo dobil milijona dolarjev. Tu je težava: JavaScript vedno predvideva, da je časovni pas tisti, ki ga brskalnik določi, razen če ni izrecno določeno drugače. To zame pomeni Ni mogoče spremeniti samo časovnega pasu obstoječega datumskega predmeta, zato je naš cilj zdaj ustvariti nov datumski objekt, vendar z UTC namesto lokalnega časovnega pasu. Uporabnikov časovni pas bomo prezrli in pri ustvarjanju datuma uporabili UTC. To lahko storite na dva načina: To deluje tudi, če ne določite časa, saj bo to privzeto na polnoč (tj. 00: 00: 00Z): Ne pozabite: Če je konstruktorju dat niz v pravilni obliki zapisa datuma ISO LLLL-MM-DD, samodejno prevzame UTC. Pogost scenarij, na katerega boste naleteli, je ugotoviti razliko med dvema datumoma. Razpravljamo o dveh primerih uporabe: Pretvorite oba datuma v časovni žig UTC, poiščite razliko v milisekundah in poiščite ustrezne dni. Opomba: Imamo nestandardno obliko. Preberite dokument o API-ju, da ugotovite, ali to pomeni 12. oktober ali 10. december. Ustrezno spremenite format ISO. Vem, da obstajajo bolj jedrnati načini za pisanje te kode, vendar jo rad napišem na ta način zaradi same jasnosti logike. Zdaj, ko se z aritmetiko datumov dobro počutimo, lahko razumemo najboljše prakse in razloge za njihovo upoštevanje. Če od uporabnika dobivate datum in uro, najverjetneje iščete njegov lokalni datum. V aritmetičnem odseku datuma smo videli, da Če želite odstraniti kakršno koli zmedo, vedno predlagam, da ustvarite datum z uporabo Fino je, da lahko uporabite različice, ki vam omogočajo, da izpustite katerega koli od zadnjih štirih parametrov, če so enaki nič; tj. Če na primer uporabljate izbirnik datuma in časa, ki vam določa datum 2012-10-12 in čas 12:30, lahko izvlečete dele in ustvarite nov objekt Date, kot sledi: Poskusite se izogniti ustvarjanju datuma iz niza, razen če je v obliki zapisa datuma ISO. Namesto tega uporabite metodo Datum (leto, mesec, datum, ure, minute, sekunde, mikrosekunde). Če dobite samo datum, na primer uporabnikov rojstni datum, je najbolje, da pretvorite obliko v veljavno obliko datuma ISO, da odstranite kakršne koli informacije o časovnem pasu, ki lahko povzročijo premik datuma naprej ali nazaj, ko se pretvori v UTC. Na primer: Če ste pozabili, če ustvarite Vedno shrani DateTime v UTC. Vedno pošljite niz ISO ali časovni žig na zadnji del. Generacije računalniških programerjev so to preprosto resnico spoznale po grenkih izkušnjah, ki so poskušale uporabniku pokazati pravi lokalni čas. Shranjevanje lokalnega časa v zaledju je slaba ideja, bolje je, da brskalnik dovoli pretvorbo v lokalni čas na sprednjem delu. Prav tako bi moralo biti jasno, da nikdar ne smete pošiljati niza DateTime, kot je '20. julij 1989 12:10', na zadnji del. Tudi če pošljete tudi časovni pas, si še bolj prizadevate, da bi drugi programerji razumeli vaše namene in datum pravilno razčlenili in shranili. Uporabite »Včasih je pomembno je poznati časovni pas v katerem se je zgodil dogodek in pretvorba v en časovni pas nepreklicno izbriše te informacije. 'Če izvajate marketinško promocijo in želite vedeti, katere stranke so oddale naročila v času kosila, naročilo, za katero se zdi, da je bilo oddano opoldne po GMT, ni zelo koristno, ko je bilo dejansko oddano med zajtrkom v New Yorku.' Če naletite na tovrstne razmere, bi bilo pametneje prihraniti tudi lokalni čas. Kot običajno bi radi ustvarili datum v formatu ISO, vendar moramo najprej najti odmik časovnega pasu. Objekt Date Za moj časovni pas +05: 45 dobim -345, to ni samo nasprotno znamenje, ampak številka, kot je -345, lahko popolnoma zmede zalednega razvijalca. Torej pretvorimo to v +05: 45. Zdaj dobimo preostale vrednosti in ustvarimo veljaven niz ISO, ki predstavlja lokalni DateTime. Če želite, lahko UTC in lokalne datume zavijete v predmet. Če želite na koncu ugotoviti, ali se je dogodek zgodil pred poldnevom po lokalnem času, lahko razčlenite datum in preprosto uporabite Nismo uporabili Včasih, tudi če je shranjen lokalni časovni pas, boste želeli prikazati datume v določenem časovnem pasu. Na primer, časi dogodkov so lahko bolj smiselni v časovnem pasu trenutnega uporabnika, če so navidezni, ali v časovnem pasu, kjer se bodo fizično odvijali, če niso. V vsakem primeru se splača pogledati vnaprej uveljavljene rešitve za formatiranje z eksplicitnimi imeni časovnih pasov. Vedno konfigurirajte svoje strežnike in zbirke podatkov tako, da uporabljajo časovni pas UTC. (Upoštevajte, da sta UTC in GMT ni ista stvar —GMT, na primer, poleti lahko pomeni prehod na BST, UTC pa nikoli.) Že videli smo, koliko pretvorbe v časovnem pasu so lahko bolečine, zlasti kadar so nenamerne. Vedno pošiljanje UTC DateTime in nastavitev strežnikov, da so v časovnem pasu UTC, vam lahko olajša življenje. Vaša vmesna koda bo veliko enostavnejša in čistejša, saj ni treba pretvarjati v časovni pas. Podatke DateTime, ki prihajajo iz strežnikov po vsem svetu, je mogoče enostavno primerjati in razvrščati. Koda na zadnji strani mora imeti možnost, da predpostavlja, da je časovni pas strežnika UTC (vendar mora vseeno imeti preverjeno mesto). Preprosto preverjanje konfiguracije prihrani razmislek in kodo za pretvorbe vsakič, ko je nova koda DateTime napisana. Manipulacija z datumi je težka težava. Koncepti za praktične primere v tem članku veljajo tudi za JavaScript in so šele začetek pravilnega ravnanja s podatki in izračuni DateTime. Poleg tega bo prišla vsaka knjižnica pomočnikov svoj nabor odtenkov. Bottom line je: Uporabite ISO na hrbtni strani in pustite sprednji del, da pravilno oblikujete stvari za uporabnika. Poklicni programerji se bodo zavedali nekaterih odtenkov in bodo (še bolj odločno) uporabljali dobro podprte knjižnice DateTime na hrbtni in sprednji strani. Vgrajene funkcije na strani zbirke podatkov so druga zgodba, vendar upam, da ta članek daje dovolj ozadja, da bi se tudi v tem kontekstu modreje odločali.Razčlenjevanje datuma
Date.now()
const date1 = new Date('Wed, 27 July 2016 13:30:00'); const date2 = new Date('Wed, 27 July 2016 07:45:00 UTC'); const date3 = new Date('27 July 2016 13:30:00 UTC+05:45');
const date = new Date(2016, 6, 27, 13, 30, 0);
const date = new Date('2016-07-27T07:45:00Z');
const date1 = new Date('25 July 2016'); const date2 = new Date('July 25, 2016');
Oblikovanje datuma
new Date('25 July 2016').getTime() !== new Date('2016-07-25').getTime() new Date('2016-07-25').getTime() === new Date('2016-07-25T00:00:00Z').getTime()
imenski prostor, zaradi katerega je oblikovanje datuma enostavno.Intl
in Date
, inicializirano z našimi izhodnimi nastavitvami. Recimo, da bi radi uporabili ameriško obliko (M / D / LLLL), bi to izgledalo takole:Intl.DateTimeFormat
const firstValentineOfTheDecade = new Date(2020, 1, 14); // 1 for February const enUSFormatter = new Intl.DateTimeFormat('en-US'); console.log(enUSFormatter.format(firstValentineOfTheDecade)); // 2/14/2020
konstruktor:DateTimeFormat
const nlBEFormatter = new Intl.DateTimeFormat('nl-BE'); console.log(nlBEFormatter.format(firstValentineOfTheDecade)); // 14/2/2020
const longEnUSFormatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', }); console.log(longEnUSFormatter.format(firstValentineOfTheDecade)); // February 14, 2020
veljajo le veljavne vrednosti kot tega pisanja so day
ali 'numeric'
. Izposojanje Različica Flavio Copes od Koda Mathiasa Bynensa izkoristiti še en del '2-digit'
za to lahko prilagodimo dan v mesecu z Intl
:formatToParts()
const pluralRules = new Intl.PluralRules('en-US', { type: 'ordinal' }) const suffixes = { 'one': 'st', 'two': 'nd', 'few': 'rd', 'other': 'th' } const convertToOrdinal = (number) => `${number}${suffixes[pluralRules.select(number)]}` // At this point: // convertToOrdinal('1') === '1st' // convertToOrdinal('2') === '2nd' // etc. const extractValueAndCustomizeDayOfMonth = (part) => { if (part.type === 'day') { return convertToOrdinal(part.value); } return part.value; }; console.log( longEnUSFormatter.formatToParts(firstValentineOfTheDecade) .map(extractValueAndCustomizeDayOfMonth) .join('') ); // February 14th, 2020
od tega pisanja Internet Explorer (IE) sploh ne podpira, ampak vse druge namizne, mobilne in zaledne (tj. Node.js) tehnologije imajo podporo . Za tiste, ki morajo podpirati IE in nujno potrebujejo redne znake, spodnji sidenote (ali bolje, ustrezna knjižnica datumov) ponuja odgovor.formatToParts
v Pythonu ali PHP.strftime
vam strftime('Today is %b %d %Y %X', mktime(5,10,0,12,30,99))
.Today is Dec 30 1999 05:10:00
da dobite datum v različnih oblikah. (Previdno, vsak jezik vsaki črki ne pripiše enakega pomena - zlasti »M« in »m« se lahko zamenjata za minute in mesece.)%
var currentDate = new Date(); var date = currentDate.getDate(); var month = currentDate.getMonth(); var year = currentDate.getFullYear();
var monthDateYear = (month+1) + '/' + date + '/' + year;
function pad(n) { return n<10 ? '0'+n : n; }
var mmddyyyy = pad(month + 1) + '/' + pad(date) + '/' + year;
var ddmmyyyy = pad(date) + '-' + pad(month + 1) + '-' + year;
var monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; var dateWithFullMonthName = monthNames[month] + ' ' + pad(date) + ', ' + year;
ki vrne 1. za 1, 12. za 12 in 103. za 103 itd., ostalo pa je preprosto:ordinal
var ordinalDate = ordinal(date) + ' ' + monthNames[month] + ', ' + year;
Spreminjanje oblike zapisa datuma
var daysOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; ordinalDateWithDayOfWeek = daysOfWeek[currentDate.getDay()] + ', ' + ordinalDate;
Uporaba funkcij lokalizacije predmeta JavaScript Date Object
const myDate = new Date('Jul 21, 2013'); const dayOfMonth = myDate.getDate(); const month = myDate.getMonth(); const year = myDate.getFullYear(); function pad(n) { return n<10 ? '0'+n : n } const ddmmyyyy = pad(dayOfMonth) + '-' + pad(month + 1) + '-' + year; // '21-07-2013'
predmetov Date
metoda:toLocaleDateString()
const today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric', });
.26 Jul 2016
, deluje zelo podobno tej, vendar vam omogoča ponovno uporabo predmeta oblikovalnika, tako da morate možnosti nastaviti le enkrat.Intl.DateTimeFormat
je dobra navada, da vedno prenesete možnosti oblikovanja, tudi če je izpis v računalniku videti v redu. To lahko zaščiti uporabniški vmesnik pred vdorom v nepričakovane kraje z res dolgimi imeni mesecev ali videti neroden zaradi kratkih.toLocaleDateString()
const today = new Date().toLocaleDateString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', });
. Če želite zagotoviti, da imata mesec in datum dve števki, samo spremenite možnosti:7/26/2016
const today = new Date().toLocaleDateString(undefined, { day: '2-digit', month: '2-digit', year: 'numeric', });
. Le tisto, kar smo želeli!
Koda Izhod Opis 07/26/2016
'4:21:38 AM' Prikaži lokalizirano različico samo časa now.toLocaleTimeString()
'04: 21: 38 AM ' Prikaz lokaliziranega časa glede na ponujene možnosti now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
'22.7.2016, 04:21:38' Prikaz datuma in ure za uporabnikovo področje now.toLocaleString()
'22.7.2016, 04:21' Prikažite lokalizirani datum in uro glede na ponujene možnosti Izračunavanje relativnih datumov in časov
now.toLocaleString(undefined, { day: 'numeric', month: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit', });
const myDate = new Date('July 20, 2016 15:00:00'); const nextDayOfMonth = myDate.getDate() + 20; myDate.setDate(nextDayOfMonth); const newDate = myDate.toLocaleString();
vsebuje lokaliziran niz, ki predstavlja ta datum. V mojem brskalniku newDate
vsebuje »9.8.2016, 15:00:00«.newDate
in Date.getTime()
za delo s celimi števili, ki predstavljajo število milisekund od določene dobe - in sicer 1. januarja 1970. Če na primer želite vedeti, kdaj je zdaj 17 ur po tem:Date.setTime()
Primerjava datumov
const msSinceEpoch = (new Date()).getTime(); const seventeenHoursLater = new Date(msSinceEpoch + 17 * 60 * 60 * 1000);
const date1 = new Date('July 19, 2014'); const date2 = new Date('July 28, 2014'); if(date1 > date2) { console.log('First date is more recent'); } else { console.log('Second date is more recent'); }
const date1 = new Date('June 10, 2003'); const date2 = new Date(date1); const equalOrNot = date1 == date2 ? 'equal' : 'not equal'; console.log(equalOrNot);
.not equal
date1.getTime() == date2.getTime()
const userEnteredString = '12/20/1989'; // MM/DD/YYYY format const dateStringFromAPI = '1989-12-20T00:00:00Z'; const dateFromUserEnteredString = new Date(userEnteredString) const dateFromAPIString = new Date(dateStringFromAPI); if (dateFromUserEnteredString.getTime() == dateFromAPIString.getTime()) { transferOneMillionDollarsToUserAccount(); } else { doNothing(); }
bo ustvaril datum 1989-12-20T00: 00: 00: 00 + 5: 45 ali 1989-12-19T18: 15: 00Z, kar po časovni znamki ni enako kot 1989-12-20T00: 00: 00Z.
new Date ('12/20/1989')
const userEnteredDate = '12/20/1989'; const parts = userEnteredDate.split('/'); const userEnteredDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const userEnteredDateObj = new Date(userEnteredDateISO + 'T00:00:00Z'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true
const userEnteredDate = new Date('1989-12-20'); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true
Iskanje razlike med dvema datumoma
Iskanje števila dni med dvema datumoma
const userEnteredDate = new Date('12/20/1989'); const userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0); const dateFromAPI = new Date('1989-12-20T00:00:00Z'); const result = userEnteredDateTimeStamp == dateFromAPI.getTime(); // true ...
Iskanje uporabnikove starosti od datuma rojstva
const dateFromAPI = '2016-02-10T00:00:00Z'; const now = new Date(); const datefromAPITimeStamp = (new Date(dateFromAPI)).getTime(); const nowTimeStamp = now.getTime(); const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp); // Math.round is used instead of Math.floor to account for certain DST cases // Number of milliseconds per day = // 24 hrs/day * 60 minutes/hour * 60 seconds/minute * 1000 ms/second const daysDiff = Math.round(microSecondsDiff / (1000 * 60 * 60 * 24)); console.log(daysDiff);
const birthDateFromAPI = '12/10/1989';
Predlogi za izogibanje peklu zmenkov
Pridobivanje datuma od uporabnika
const parts = birthDateFromAPI.split('/'); const birthDateISO = parts[2] + '-' + parts[0] + '-' + parts[1]; const birthDate = new Date(birthDateISO); const today = new Date(); let age = today.getFullYear() - birthDate.getFullYear(); if(today.getMonth()
Date
format, tudi če imate datum že v veljavni obliki, ki ga je mogoče razčleniti. Če se vsi programerji v vaši ekipi držijo tega preprostega pravila, bo dolgoročno zelo enostavno vzdrževati kodo, saj je čim bolj eksplicitna z new Date(year, month, day, hours, minutes, seconds, milliseconds)
konstruktor.Date
je enako new Date(2012, 10, 12)
ker so nedoločeni parametri privzeto nič.new Date(2012, 10, 12, 0, 0, 0, 0)
Pridobivanje samo datuma
const dateFromPicker = '2012-10-12'; const timeFromPicker = '12:30'; const dateParts = dateFromPicker.split('-'); const timeParts = timeFromPicker.split(':'); const localDate = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1]);
const dateFromPicker = '12/20/2012'; const dateParts = dateFromPicker.split('/'); const ISODate = dateParts[2] + '-' + dateParts[0] + '-' + dateParts[1]; const birthDate = new Date(ISODate).toISOString();
predmet z vnosom v veljavni obliki zapisa datuma ISO (LLLL-MM-DD), bo privzeto UTC, namesto da bi bil privzet za časovni pas brskalnika.Shranjevanje datuma
Date
ali toISOString()
metode predmeta Date za pretvorbo lokalnega DateTime v UTC.toJSON()
Prikaz datuma in ure
const dateFromUI = '12-13-2012'; const timeFromUI = '10:20'; const dateParts = dateFromUI.split('-'); const timeParts = timeFromUI.split(':'); const date = new Date(dateParts[2], dateParts[0]-1, dateParts[1], timeParts[0], timeParts[1]); const dateISO = date.toISOString(); $.post('http://example.com/', {date: dateISO}, ...)
predmet.Date
ali toLocaleString()
in toLocaleDateString()
metode ali knjižnico datumov za prikaz lokalnega časa.toLocaleTimeString()
Kdaj naj shranjujete tudi lokalni čas?
const dateFromAPI = '2016-01-02T12:30:00Z'; const localDate = new Date(dateFromAPI); const localDateString = localDate.toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric', }); const localTimeString = localDate.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit', });
Funkcija nam pove število minut, ki so dodane določenemu lokalnemu času, ki ustreza ekvivalentu UTC časa. Predlagam, da jo pretvorite v format (+ -) hh: mm, ker je bolj očitno, da gre za odmik časovnega pasu.getTimeZoneOffset()
const now = new Date(); const tz = now.gettime zoneOffset();
const sign = tz > 0 ? '-' : '+'; const hours = pad(Math.floor(Math.abs(tz)/60)); const minutes = pad(Math.abs(tz)%60); const tzOffset = sign + hours + ':' + minutes;
const localDateTime = now.getFullYear() + '-' + pad(now.getMonth()+1) + '-' + pad(now.getDate()) + 'T' + pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds());
const eventDate = { utc: now.toISOString(), local: localDateTime, tzOffset: tzOffset, }
funkcijo.getHours()
const localDateString = eventDate.local; const localDate = new Date(localDateString); if(localDate.getHours() <12) { console.log('Event happened before noon local time'); }
tukaj, vendar ga še vedno shranjujemo, ker ga bomo v prihodnosti morda potrebovali za odpravljanje napak. Pravzaprav lahko pošljete samo odmik časovnega pasu in samo UTC čas. Všeč pa mi je tudi shranjevanje lokalnega časa, ker boste morali datum shraniti v bazo podatkov, če imate lokalni čas shranjen ločeno, pa lahko neposredno poizvedujete na podlagi polja, namesto da bi morali opraviti izračune, da dobite lokalni datum.Konfiguracija strežnika in baze podatkov
Čas je za boljše urejanje zmenkov