Hvor kan jeg finne dokumentasjon på formatering av en dato i JavaScript?
Jeg la merke til at JavaScript sin new Date()-funksjon er veldig smart når det gjelder å akseptere datoer i flere formater.
Xmas95 = new Date("25 Dec, 1995 23:15:00")
Xmas95 = new Date("2009 06 12,12:52:39")
Xmas95 = new Date("20 09 2006,12:52:39")
Jeg kunne ikke finne dokumentasjon noe sted som viser alle gyldige strengformater når man kaller new Date()-funksjonen.
Dette er for å konvertere en streng til en dato. Hvis vi ser på motsatt side, det vil si å konvertere et datoobjekt til en streng, hadde jeg inntil nå inntrykk av at JavaScript ikke har et innebygd API for å formatere et datoobjekt til en streng.
Redaktørens merknad: Følgende fremgangsmåte er den som spørsmålsstilleren prøvde, og som fungerte på en bestemt nettleser, men fungerer ikke generelt; se svarene på denne siden for å se noen faktiske løsninger.
I dag lekte jeg med toString()-metoden på dato-objektet, og overraskende nok tjener den formålet med å formatere dato til strenger.
var d1 = new Date();
d1.toString('yyyy-MM-dd'); //Returns "2009-06-29" in Internet Explorer, but not Firefox or Chrome
d1.toString('dddd, MMMM ,yyyy') //Returns "Monday, June 29,2009" in Internet Explorer, but not Firefox or Chrome
Også her kunne jeg ikke finne noen dokumentasjon på alle måtene vi kan formatere datoobjektet til en streng.
Hvor er dokumentasjonen som viser hvilke formatspesifikatorer som støttes av Date()-objektet?
Svar #1
Jeg elsker 10 måter å formatere tid og dato på ved hjelp av JavaScript og Arbeide med datoer.
I utgangspunktet har du tre metoder, og du må kombinere strengene selv:
getDate() // Returns the date
getMonth() // Returns the month
getFullYear() // Returns the year
Eksempel :
var d = new Date();
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1; //Months are zero based
var curr_year = d.getFullYear();
console.log(curr_date + "-" + curr_month + "-" + curr_year);Svar #2
Moment.js
Det er et (lettvekts)* JavaScript-datobibliotek for å analysere, manipulere og formatere datoer.
var a = moment([2010, 1, 14, 15, 25, 50, 125]);
a.format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
a.format("ddd, hA"); // "Sun, 3PM"
(*) lettvekt betyr 9,3KB minifisert + gzipet i den minste mulige oppsettet (februar 2014)
Svar #3
Hvis du allerede bruker jQuery UI i prosjektet ditt, kan du bruke den innebygde datepicker-metoden for å formatere datoobjektet ditt:
$.datepicker.formatDate('yy-mm-dd', new Date(2007, 1 - 1, 26));
Men datovelgeren formaterer bare datoer, og kan ikke formatere klokkeslett.
Ta en titt på jQuery UI datepicker formatDate, eksemplene.
Svar #4
Egendefinert formateringsfunksjon:
For faste formater gjør en enkel funksjon jobben. Følgende eksempel genererer det internasjonale formatet ÅÅÅÅ-MM-DD:
function dateToYMD(date) {
var d = date.getDate();
var m = date.getMonth() + 1;
var y = date.getFullYear();
return '' + y + '-' + (m<=9 ? '0' + m : m) + '-' + (d <= 9 ? '0' + d : d);
}
Merk: Det er imidlertid vanligvis ikke en god idé å utvide Javascript-standardbibliotekene (f.eks. ved å legge til denne funksjonen til prototypen til Date).
En mer avansert funksjon kunne generere konfigurerbar utgang basert på en formatparameter. Det finnes et par gode eksempler på denne samme siden.
Hvis det å skrive en formateringsfunksjon er for langt, finnes det mange biblioteker som gjør det. Noen andre svar nevner dem allerede. Men å øke avhengigheter har også sin motpart.
Standard ECMAScript-formateringsfunksjoner:
Siden nyere versjoner av ECMAscript har Date-klassen noen spesifikke formateringsfunksjoner:
toDateString: Implementeringsavhengig, viser bare datoen.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.todatestring
new Date().toDateString(); // e.g. "Fri Nov 11 2016"
toISOString: Vis ISO 8601-dato og klokkeslett.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.toisostring
new Date().toISOString(); // e.g. "2016-11-21T08:00:00.000Z"
toJSON: Strenggjører for JSON.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tojson
new Date().toJSON(); // e.g. "2016-11-21T08:00:00.000Z"
toLocaleDateString: Implementeringsavhengig, en dato i lokalt format.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocaledatestring
new Date().toLocaleDateString(); // e.g. "21/11/2016"
toLocaleString: Implementeringsavhengig, en dato&tid i lokalt format.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocalestring
new Date().toLocaleString(); // e.g. "21/11/2016, 08:00:00 AM"
toLocaleTimeString: Implementeringsavhengig, en tid i lokalt format.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tolocaletimestring
new Date().toLocaleTimeString(); // e.g. "08:00:00 AM"
toString: Generisk toString for dato.
http://www.ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.tostring
new Date().toString(); // e.g. "Fri Nov 11 2016 08:00:00 GMT+0100 (W. Europe Standard Time)"
Merk: det er mulig å generere tilpasset utdata fra disse formateringsfunksjonene:
new Date().toISOString().slice(0,10); // By @Image72, return YYYY-MM-DD
Svar #5
Hvor er dokumentasjonen som viser hvilke formatspesifikatorer som støttes av
Date()-objektet?
Jeg snublet over dette i dag og ble ganske overrasket over at ingen tok seg tid til å svare på dette enkle spørsmålet. Sant nok, det finnes mange biblioteker der ute for å hjelpe med dato-manipulasjon. Noen er bedre enn andre. Men det var ikke det spørsmålet som ble stilt.
Så vidt jeg vet, støtter ikke ren JavaScript formatspesifikatorer på den måten du har indikert at du ønsker å bruke dem. Men det støtter metoder for formatering av datoer og/eller tider, som .toLocaleDateString(), .toLocaleTimeString(), og .toUTCString().
Referansen til Date-objektet jeg bruker oftest, er på w3schools.com-nettstedet (men et raskt Google-søk vil avsløre mange flere som kanskje passer bedre til dine behov).
Merk også at Datoobjektets egenskaper-delen gir en lenke til prototype, som viser noen måter du kan utvide Dato-objektet med egendefinerte metoder. Det har vært en viss debatt i JavaScript-fellesskapet gjennom årene om hvorvidt dette er beste praksis eller ikke, og jeg tar ikke stilling for eller imot det, bare påpeker at det eksisterer.
Svar #6
Det korte svaret
Det finnes ingen «universell» dokumentasjon som JavaScript retter seg mot; hver nettleser som har JavaScript er egentlig en implementering. Imidlertid finnes det en standard som de fleste moderne nettlesere pleier å følge, og det er ECMAScript-standarden; ECMAScript-standardstrenger vil ta, minst, en modifisert implementering av ISO 8601-definisjonen.
I tillegg til dette finnes det en annen standard satt frem av IETF som nettlesere også har en tendens til å følge, som er definisjonen for tidsstempler laget i RFC 2822. Faktisk dokumentasjon kan finnes i referanselisten nederst.
Fra dette kan du forvente grunnleggende funksjonalitet, men det som «bør» være er ikke nødvendigvis hva som «er». Jeg kommer imidlertid til å gå litt mer i dybden med dette prosedyremessig, ettersom det ser ut til at bare tre personer faktisk svarte på spørsmålet (Scott, goofballLogic og peller nemlig), noe som for meg antyder at de fleste ikke er klar over hva som faktisk skjer når du oppretter et Date-objekt.
Det lange svaret
Hvor er dokumentasjonen som lister opp formatspesifikatorene som støttes av Date()-objektet?
For å svare på spørsmålet, eller vanligvis til og med lete etter svaret på dette spørsmålet, må du vite at javascript ikke er et nytt språk; det er faktisk en implementering av ECMAScript, og følger ECMAScript-standardene (men merk at javascript faktisk også eksisterte før disse standardene; ECMAScript-standardene er bygget på den tidlige implementeringen av LiveScript/JavaScript). Den nåværende ECMAScript-standarden er 5.1 (2011); på tidspunktet da spørsmålet opprinnelig ble stilt (juni ’09), var standarden 3 (4 ble forkastet), men 5 ble utgitt kort tid etter innlegget mot slutten av 2009. Dette bør tydeliggjøre ett problem; hvilken standard en javascript-implementering følger, gjenspeiler kanskje ikke hva som faktisk er på plass, fordi a) det er en implementering av en gitt standard, b) ikke alle implementeringer av en standard er puritanske, og c) funksjonalitet blir ikke utgitt i synkronisering med en ny standard, og d) en implementering er et konstant arbeid pågående.
I hovedsak, når man arbeider med javascript, arbeider man med en derivat (javascript spesifikk for nettleseren) av en implementering (selve javascript). Googles V8, for eksempel, implementerer ECMAScript 5.0, men Internet Explorers JScript prøver ikke å overholde noen ECMAScript-standard, likevel overholder Internet Explorer 9 ECMAScript 5.0.
Når et enkelt argument gis til new Date(), kaster det denne funksjonsprototypen:
new Date(value)
Når to eller flere argumenter sendes til new Date(), kaster det dette funksjonsprototypen:
new Date (year, month [, date [, hours [, minutes [, seconds [, ms ] ] ] ] ] )
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.3.2
Fra dette kan vi utlede at for å få den strengeformateringen som tillates for new Date(value), må vi se på metoden Date.parse(string). Dokumentasjonen for denne metoden kan finnes her:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.4.2
Og vi kan videre slutte oss til at datoer forventes å være i et modifisert ISO 8601 utvidet format, som spesifisert her:
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
Vi kan imidlertid gjenkjenne fra erfaring at javascripts Date-objekt aksepterer andre formater (påtvunget av eksistensen av dette spørsmålet i første omgang), og dette er greit fordi ECMAScript tillater implementeringsspesifikke formater. Dette svarer imidlertid fortsatt ikke på spørsmålet om hvilken dokumentasjon som er tilgjengelig om de tilgjengelige formatene, eller hvilke formater som faktisk er tillatt. Vi skal se på Googles javascript-implementering, V8; vær oppmerksom på at jeg ikke foreslår at dette er den "beste" javascript-motoren (hvordan kan man definere "beste" eller til og med "god") og man kan ikke anta at formatene som er tillatt i V8 representerer alle formater som er tilgjengelige i dag, men jeg synes det er rettferdig å anta at de følger moderne forventninger.
Googles V8, date.js, DateConstructor
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#141
Når vi ser på DateConstructor-funksjonen, kan vi slutte oss til at vi trenger å finne DateParse-funksjonen; merk imidlertid at «year» ikke er det faktiske året og kun er en referanse til «year»-parameteren.
Googles V8, date.js, DateParse
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#270
Dette kaller %DateParseString, som faktisk er en kjøretidsfunksjonsreferanse for en C++-funksjon. Det refererer til følgende kode:
Googles V8, runtime.cc, %DateParseString
https://code.google.com/p/v8/source/browse/trunk/src/runtime.cc?r=18400#9559
Funksjonskallet vi er opptatt av i denne funksjonen er for DateParser::Parse(); ignorer logikken rundt disse funksjonskallene, dette er bare kontroller for å samsvare med kodetypen (ASCII og UC16). DateParser::Parse er definert her:
Googles V8, dateparser-inl.h, DateParser::Parse
https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h?r=18400#36
Dette er funksjonen som faktisk definerer hvilke formater den aksepterer. I hovedsak sjekker den for EMCAScript 5.0 ISO 8601-standarden, og hvis den ikke er standardkompatibel, vil den forsøke å bygge datoen basert på eldre formater. Noen viktige punkter basert på kommentarene:
- Ord før det første tallet som er ukjente for parseren, blir ignorert.
- Tekst i parentes blir ignorert.
- Usignerte tall etterfulgt av «: » tolkes som en «tid komponent ».
- Usignerte tall etterfulgt av «. » tolkes som en «tidskomponent», og må følges av millisekunder.
- Signerte tall etterfulgt av time eller time og minutt (f.eks. +5:15 eller +0515) tolkes som tidssonen.
- Når du angir timen og minuttet, kan du bruke enten «hh:mm» eller «hhmm».
- Ord som indikerer en tidssone tolkes som en tidssone.
- Alle andre tall tolkes som "datokomponenter".
- Alle ord som starter med de første tre bokstavene i en måned blir tolket som måneden.
- Du kan definere minutter og timer sammen i en av de to formatene: «hh:mm» eller «hhmm».
- Symboler som «+», «-» og uparrede «)» er ikke tillatt etter at et tall har blitt behandlet.
- Elementer som samsvarer med flere formater (f.eks. 1970-01-01) behandles som en standardkompatibel EMCAScript 5.0 ISO 8601-streng.
Så dette bør være nok til å gi deg en grunnleggende idé om hva du kan forvente når det gjelder å sende en streng inn i et Date-objekt. Du kan utvide dette ytterligere ved å se på følgende spesifikasjon som Mozilla henviser til på Mozilla Developer Network (i samsvar med IETF RFC 2822-tidsstempler):
https://www.rfc-editor.org/rfc/rfc2822#page-14
Microsoft Developer Network nevner i tillegg en ekstra standard for Date-objektet: ECMA-402, ECMAScript Internationalization API Specification, som er komplementær til ECMAScript 5.1-standarden (og fremtidige standarder). Det kan finnes her:
http://www.ecma-international.org/ecma-402/1.0/
Uansett bør dette bidra til å fremheve at det ikke finnes noen «dokumentasjon» som universelt representerer alle implementeringer av JavaScript, men det finnes likevel nok dokumentasjon tilgjengelig til å gjøre en rimelig forståelse av hvilke strenger som er akseptable for et Date-objekt. Ganske et utfordrende spørsmål når du tenker over det, ikke sant? :P
Referanser
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.3.2
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.4.2
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
https://www.rfc-editor.org/rfc/rfc2822#page-14
http://www.ecma-international.org/ecma-402/1.0/
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#141
https://code.google.com/p/v8/source/browse/trunk/src/date.js?r=18400#270
https://code.google.com/p/v8/source/browse/trunk/src/runtime.cc?r=18400#9559
https://code.google.com/p/v8/source/browse/trunk/src/dateparser-inl.h?r=18400#36
Ressurser
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
http://msdn.microsoft.com/en-us/library/ff743760(v=vs.94).aspx
Svar #7
Sørg for at du sjekker ut Datejs når du håndterer datoer i JavaScript. Det er ganske imponerende og godt dokumentert, som du kan se i tilfelle av funksjonen toString.
REDIGER: Tyler Forsythe påpeker at datejs er utdatert. Jeg bruker det i mitt nåværende prosjekt og har ikke hatt noen problemer med det, men du bør være klar over dette og vurdere alternativer.
Svar #8
Du kan bare utvide Date-objektet med en ny format-metode som nevnt av meizz, nedenfor er koden gitt av forfatteren. Og her er en jsfiddle.
Date.prototype.format = function(format) //author: meizz
{
var o = {
"M+" : this.getMonth()+1, //month
"d+" : this.getDate(), //day
"h+" : this.getHours(), //hour
"m+" : this.getMinutes(), //minute
"s+" : this.getSeconds(), //second
"q+" : Math.floor((this.getMonth()+3)/3), //quarter
"S" : this.getMilliseconds() //millisecond
}
if(/(y+)/.test(format)) format=format.replace(RegExp.$1,
(this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)if(new RegExp("("+ k +")").test(format))
format = format.replace(RegExp.$1,
RegExp.$1.length==1 ? o[k] :
("00"+ o[k]).substr((""+ o[k]).length));
return format;
}
alert(new Date().format("yyyy-MM-dd"));
alert(new Date("january 12 2008 11:12:30").format("yyyy-MM-dd h:mm:ss"));
Svar #9
Funksjonaliteten du nevner er ikke standard Javascript, sannsynligvis ikke portabel på tvers av nettlesere og derfor ikke god praksis. ECMAScript 3-spesifikasjonen lar analyse- og utdataformatene være opp til Javascript-implementeringen. ECMAScript 5 legger til et delsett av ISO8601-støtte. Jeg tror toString()-funksjonen du nevner er en nyvinning i én nettleser (Mozilla?).
Flere biblioteker tilbyr rutiner for å parameterisere dette, noen med omfattende støtte for lokalisering. Du kan også sjekke metodene i dojo.date.locale.
Svar #10
Jeg laget denne veldig enkle formatteren, den er klipp/limbar (Oppdatert med en ryddigere versjon):
function DateFmt(fstr) {
this.formatString = fstr
var mthNames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
var dayNames = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
var zeroPad = function(number) {
return ("0"+number).substr(-2,2);
}
var dateMarkers = {
d:['getDate',function(v) { return zeroPad(v)}],
m:['getMonth',function(v) { return zeroPad(v+1)}],
n:['getMonth',function(v) { return mthNames[v]; }],
w:['getDay',function(v) { return dayNames[v]; }],
y:['getFullYear'],
H:['getHours',function(v) { return zeroPad(v)}],
M:['getMinutes',function(v) { return zeroPad(v)}],
S:['getSeconds',function(v) { return zeroPad(v)}],
i:['toISOString']
};
this.format = function(date) {
var dateTxt = this.formatString.replace(/%(.)/g, function(m, p) {
var rv = date[(dateMarkers[p])[0]]()
if ( dateMarkers[p][1] != null ) rv = dateMarkers[p][1](rv)
return rv
});
return dateTxt
}
}
fmt = new DateFmt("%w %d:%n:%y - %H:%M:%S %i")
v = fmt.format(new Date())
http://snipplr.com/view/66968.82825/
Svar #11
Rammeverkfri, begrenset men lett
var d = (new Date()+'').split(' ');
// ["Tue", "Sep", "03", "2013", "21:54:52", "GMT-0500", "(Central", "Daylight", "Time)"]
[d[3], d[1], d[2], d[4]].join(' ');
// "2013 Sep 03 21:58:03"
Svar #12
DateJS er absolutt fullverdig, men jeg vil anbefale dette MYE enklere biblioteket (JavaScript Date Format) som jeg foretrekker simpelthen fordi det bare er rundt 120 linjer.
Svar #13
Etter å ha sett gjennom flere av alternativene som ble gitt i andre svar, bestemte jeg meg for å skrive min egen begrensede, men enkle løsning som andre også kan finne nyttig.
/**
* Format date as a string
* @param date - a date object (usually "new Date();")
* @param format - a string format, eg. "DD-MM-YYYY"
*/
function dateFormat(date, format) {
// Calculate date parts and replace instances in format string accordingly
format = format.replace("DD", (date.getDate() < 10 ? '0' : '') + date.getDate()); // Pad with '0' if needed
format = format.replace("MM", (date.getMonth() < 9 ? '0' : '') + (date.getMonth() + 1)); // Months are zero-based
format = format.replace("YYYY", date.getFullYear());
return format;
}
Eksempel på bruk:
console.log("The date is: " + dateFormat(new Date(), "DD/MM/YYYY"));
Svar #14
Her er en funksjon jeg bruker mye. Resultatet er åååå-mm-dd tt:mm:ss.nnn.
function date_and_time() {
var date = new Date();
//zero-pad a single zero if needed
var zp = function (val){
return (val <= 9 ? '0' + val : '' + val);
}
//zero-pad up to two zeroes if needed
var zp2 = function(val){
return val <= 99? (val <=9? '00' + val : '0' + val) : ('' + val ) ;
}
var d = date.getDate();
var m = date.getMonth() + 1;
var y = date.getFullYear();
var h = date.getHours();
var min = date.getMinutes();
var s = date.getSeconds();
var ms = date.getMilliseconds();
return '' + y + '-' + zp(m) + '-' + zp(d) + ' ' + zp(h) + ':' + zp(min) + ':' + zp(s) + '.' + zp2(ms);
}
Svar #15
Du kan finne nyttig denne modifikasjonen av datoobjektet, som er mindre enn hvilket som helst bibliotek og lett kan utvides for å støtte forskjellige formater:
MERK:
- Den bruker Object.keys() som er udefinert i eldre nettlesere, så du må kanskje implementere en polyfill fra gitt lenke.
KODE
Date.prototype.format = function(format) {
// set default format if function argument not provided
format = format || 'YYYY-MM-DD hh:mm';
var zeropad = function(number, length) {
number = number.toString();
length = length || 2;
while(number.length < length)
number = '0' + number;
return number;
},
// here you can define your formats
formats = {
YYYY: this.getFullYear(),
MM: zeropad(this.getMonth() + 1),
DD: zeropad(this.getDate()),
hh: zeropad(this.getHours()),
mm: zeropad(this.getMinutes())
},
pattern = '(' + Object.keys(formats).join(')|(') + ')';
return format.replace(new RegExp(pattern, 'g'), function(match) {
return formats[match];
});
};
BRUK
var now = new Date;
console.log(now.format());
// outputs: 2015-02-09 11:47
var yesterday = new Date('2015-02-08');
console.log(yesterday.format('hh:mm YYYY/MM/DD'));
// outputs: 00:00 2015/02/08
Svar #16
Alle nettlesere
Den mest pålitelige måten å formatere en dato med kildeformatet du bruker, er å følge disse trinnene:
- Bruk
new Date()for å lage etDate-objekt - Bruk
.getDate(),.getMonth()og.getFullYear()for å hente henholdsvis dag, måned og år - Lim bitene sammen i henhold til målet ditt format
Eksempel :
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
var date = new Date(input);
return [
("0" + date.getDate()).slice(-2),
("0" + (date.getMonth()+1)).slice(-2),
date.getFullYear()
].join('/');
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015(Se også denne Fiddle).
Moderne nettlesere bare
Du kan også bruke den innebygde .toLocaleDateString-metoden for å gjøre formateringen for deg. Du trenger bare å sende med riktig lokalitet og alternativer for å matche riktig format, noe som dessverre kun støttes av moderne nettlesere (*) :
var date = '2015-11-09T10:46:15.097Z';
function format(input) {
return new Date(input).toLocaleDateString('en-GB', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
});
}
document.body.innerHTML = format(date); // OUTPUT : 09/11/2015(Se også denne Fiddle).
(*) I følge MDN, betyr "moderne nettlesere" Chrome 24+, Firefox 29+, IE11, Edge12+, Opera 15+ og Safari nightly build
