Jak uzyskać aktualną datę w JavaScript?


2306

Jak uzyskać aktualną datę w JavaScript?


383
var currentTime = new Date();
Hendrik,

11
Zobacz dokumentację obiektu Date . Ma przykłady.
Quentin,


24
new Date()zwraca bieżącą godzinę , a nie bieżącą datę . To rozróżnienie ma znaczenie, jeśli próbujesz porównać go z inną datą, która nie ma elementu czasu (tj. Jest o północy).
Steve Bennett,

11
użyj momentJs, ta biblioteka jest złotem dla programistów.
RBoschini

Odpowiedzi:


2715

Służy new Date()do generowania nowego Dateobiektu zawierającego bieżącą datę i godzinę.

var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();

today = mm + '/' + dd + '/' + yyyy;
document.write(today);

To da ci dzisiejszą datę w formacie mm / dd / rrrr.

Po prostu zmień today = mm +'/'+ dd +'/'+ yyyy;format na dowolny.


7
dzięki za kod .. ale nadal nie rozumiem, czy wiersz to (dd <10) {dd = '0' + dd} ... dlaczego <10? z kodu rozumiem, że jeśli znak dnia jest mniejszy niż 2, po prostu dodaj poprzedzające 0 przed dniem .. ale dlaczego 10?
imin

20
@imin: ponieważ mniej niż 2 znaki oznaczają 1 znak ... a wszystko pod 10 (od 1 do 9) 1 znak, więc mamy 01, 02...,09
ZFM

11
@MounaCheikhna - Jak moglibyśmy być w roku 999?
nnnnnn

21
Zamień miesiąc i datę, jeśli nie jesteś w Ameryce Północnej.
Mark Micallef,

3
Nowa Date.prototype.toLocaleDateString()metoda jest bardziej elastycznym rozwiązaniem. Jest częścią JavaScript od ECMAScript 5.1 i jest dobrze obsługiwany przez wiecznie zielone przeglądarki. MDN:toLocaleDateString()
Adam Brown

443

var utc = new Date().toJSON().slice(0,10).replace(/-/g,'/');
document.write(utc);

Użyj tej replaceopcji, jeśli zamierzasz ponownie użyć utczmiennej, np. new Date(utc)Ponieważ Firefox i Safari nie rozpoznają daty z myślnikami.


6
Nie sądzę :) Wydaje się to całkiem proste!
Varun Natraaj

6
Zwraca toJSON () jako utc datetime
Andy N

1
Zwraca datę / godzinę JSON. toUTCString()zwraca jako utc datetime.
Varun Natraaj

25
Nie uwzględnia TimezoneOffset. W czasie testów szukałem „teraz” i dostałem „wczoraj”. stackoverflow.com/questions/13646446/…
mickmackusa

7
Doskonały. To najczystszy sposób na zrobienie tego, co tu widzę. Działa dobrze w MomentJS dla „Today, Not Now”moment( new Date().toJSON().slice(0, 10) )
Kyle Hotchkiss,

234

AKTUALIZACJA! , Przewiń w dół

Jeśli chcesz czegoś prostego dla użytkownika końcowego ... Also, fixed a small suffix issue in the first version below. Now properly returns suffix.

var objToday = new Date(),
	weekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
	dayOfWeek = weekday[objToday.getDay()],
	domEnder = function() { var a = objToday; if (/1/.test(parseInt((a + "").charAt(0)))) return "th"; a = parseInt((a + "").charAt(1)); return 1 == a ? "st" : 2 == a ? "nd" : 3 == a ? "rd" : "th" }(),
	dayOfMonth = today + ( objToday.getDate() < 10) ? '0' + objToday.getDate() + domEnder : objToday.getDate() + domEnder,
	months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
	curMonth = months[objToday.getMonth()],
	curYear = objToday.getFullYear(),
	curHour = objToday.getHours() > 12 ? objToday.getHours() - 12 : (objToday.getHours() < 10 ? "0" + objToday.getHours() : objToday.getHours()),
	curMinute = objToday.getMinutes() < 10 ? "0" + objToday.getMinutes() : objToday.getMinutes(),
	curSeconds = objToday.getSeconds() < 10 ? "0" + objToday.getSeconds() : objToday.getSeconds(),
	curMeridiem = objToday.getHours() > 12 ? "PM" : "AM";
var today = curHour + ":" + curMinute + "." + curSeconds + curMeridiem + " " + dayOfWeek + " " + dayOfMonth + " of " + curMonth + ", " + curYear;

document.getElementsByTagName('h1')[0].textContent = today;
<h1></h1>

AKTUALIZACJA UBBERA Po długim zwlekaniu w końcu GitHubbed i zaktualizowałem to o końcowe rozwiązanie, z którego korzystałem dla siebie. Wprowadzono nawet kilka zmian w ostatniej chwili, aby był słodszy! Jeśli szukasz starego jsFiddle, zobacz to .

Ta aktualizacja jest dostępna w 2 wersjach, wciąż stosunkowo niewielkich, choć nie tak małych jak moja powyższa, oryginalna odpowiedź. Jeśli chcesz bardzo małe, idź z tym.
Uwaga: To jest nadal mniej rozdęty niż moment.js. Chociaż moment.js jest fajny, imo, ma zbyt wiele świeckich metod, które wymagają momentu nauki, jakby był językiem. Mój tutaj używa tego samego wspólnego formatu co PHP: data .

Szybkie linki

Flavor 1new Date().format(String) My Personal Fav. Znam tabu, ale świetnie działa na obiekcie Date. Po prostu bądź świadomy wszelkich innych modów, które możesz mieć w obiekcie Data.

//  use as simple as
new Date().format('m-d-Y h:i:s');   //  07-06-2016 06:38:34

Flavor 2dateFormat(Date, String) Bardziej tradycyjna metoda „wszystko w jednym”. Ma wszystkie możliwości poprzedniego, ale jest wywoływany za pomocą metody z parametrami daty.

//  use as simple as
dateFormat(new Date(), 'm-d-Y h:i:s');  //  07-06-2016 06:38:34

BONUS Flavour (wymaga jQuery)$.date(Date, String) Zawiera znacznie więcej niż tylko prostą formatopcję. Rozszerza podstawowy obiekt Date i obejmuje metody takie jak addDays. Aby uzyskać więcej informacji, zobacz Git .

W tym modzie znaki formatu są inspirowane przez PHP: date . Aby uzyskać pełną listę, zobacz mój plik README

Ten mod ma również znacznie dłuższą listę gotowych formatów. Aby użyć gotowego formatu, wystarczy wprowadzić jego nazwę klucza.dateFormat(new Date(), 'pretty-a');

  • 'złożony'
    • „commonLogFormat” == 'd / M / Y: G: i: s ”
    • „exif” == 'Y: m: d G: i: s ”
    • „isoYearWeek” == 'Y \\ WW'
    • „isoYearWeek2” == 'T - \\ WW ”
    • „isoYearWeekDay” == 'Y \\ WWj'
    • „isoYearWeekDay2” == 'T - \\ WW-j'
    • „mySQL” == 'Ymd h: i: s ”
    • „postgreSQL” == „Yz”
    • „postgreSQL2” == „Yz”
    • „mydło” == „Ymd \\ TH: i: su”
    • „soap2” == 'Ymd \\ TH: i: s.uP'
    • „unixTimestamp” == „@U”
    • „xmlrpc” == 'Ymd \\ TG: i: s'
    • „xmlrpcCompact” == 'Ymd \\ tGis'
    • „wddx” == 'Ynj \\ TG: i: s ”
  • „stałe”
    • „AMERICAN” == „F j Y”
    • „AMERICANSHORT” == „m / d / Y”
    • „AMERICANSHORTWTIME” == 'm / d / Y h: i: sA ”
    • „ATOM” == „Ymd \\ TH: i: sP”
    • „COOKIE” == 'l dMY H: i: s T ”
    • „EUROPEAN” == „j FY”
    • „EUROPEANSHORT” == „dmY”
    • „EUROPEANSHORTWTIME” == „dmY H: i: s”
    • „ISO8601” == „Ymd \\ TH: i: sO”
    • „LEGAL” == „j FY”
    • „RFC822” == 'D d M y H: i: s O ”
    • „RFC850” == 'l dMy H: i: s T ”
    • „RFC1036” == 'D d M y H: i: s O ”
    • „RFC1123” == 'D d MYH: i: s O ”
    • „RFC2822” == 'D d MYH: i: s O ”
    • „RFC3339” == 'Ymd \\ TH: i: sP ”
    • „RSS” == 'D d MYH: i: s O ”
    • „W3C” == 'Ymd \\ TH: i: sP ”
  • 'ładny'
    • „pretty-a” == 'g: i.sA l jS \\ o \\ f FY ”
    • „pretty-b” == 'g: iA l jS \\ o \\ f FY ”
    • „pretty-c” == 'n / d / Y g: iA ”
    • „pretty-d” == 'n / d / Y ”
    • „pretty-e” == 'F jS - g: ia ”
    • „pretty-f” == 'g: iA ”

Jak możesz zauważyć, możesz użyć podwójnego, \aby uciec od postaci.



14
@KamranAhmed Prawie 2 lata i ponad 40 głosów później, powiedziałbym, że wysiłek był tego wart. Lol. Od tego czasu znacznie rozszerzyłem tę klasę osobiście, ale nie przesłałem jej, ponieważ myślałem, że większość osób użyłaby tej innej wtyczki js date, którą widzę jako zalecaną, ale myślę, że powinienem uczynić ją bardziej „publiczną” i dodać ją tutaj.
SpYk3HH

14
moment.js jest teraz rzeczą, której teraz byś użył
Christian Stewart

1
Powyżej znajduje się literówka (która zajęła mi trochę czasu, aby zauważyć), używa zmiennej „Today” w wierszu: „dayOfMonth = Today +”
user1435707

„Today + (objToday.getDate () <10)? '0' + objToday.getDate () + domEnder: objToday.getDate () + domEnder” - JS to głupi język.
Alex S

211

Najkrótszy możliwy.

Aby uzyskać format taki jak „2018-08-03”:

let today = new Date().toISOString().slice(0, 10)

console.log(today)

Aby uzyskać format taki jak „8/3/2018”:

let today = new Date().toLocaleDateString()

console.log(today)

Możesz również przekazać ustawienia regionalne jako argument, na przykład toLocaleDateString("sr")itp.


3
To nadal nie udaje się z powodu przesunięcia strefy czasowej.
LStarky,

7
Dlaczego nie jest to akceptowana odpowiedź, najprostsza i wykorzystuje wbudowane funkcje
lifesoordinary

171

Jeśli chcesz tylko daty bez informacji o czasie, użyj:

var today = new Date();
    today.setHours(0, 0, 0, 0);

document.write(today);


40
To wydaje się być jedyną odpowiedzią, która faktycznie odpowiada na pytanie. Wszyscy inni odpowiadają, jak sformatować datę jako ciąg.
Inrego

1
Zgadzam się. Właściwie chciałem napisać odpowiedź podobną do tej, a potem wyskoczyło małe okno z pytaniem, czy przeczytałem wszystkie odpowiedzi. Ponieważ przeczytałem tylko najlepsze odpowiedzi, postanowiłem sprawdzić, czy są jakieś poprawne odpowiedzi i ta była pierwszą poprawną odpowiedzią.
Lajos Arpad

Ustawia godziny za pomocą UTC, co może nie działać we wszystkich przypadkach użycia.
McKay,

103

Spróbuj tego:

var currentDate = new Date()
var day = currentDate.getDate()
var month = currentDate.getMonth() + 1
var year = currentDate.getFullYear()
document.write("<b>" + day + "/" + month + "/" + year + "</b>")

Wynik będzie podobny

15/2/2012

67

Jeśli szukasz bardziej szczegółowej kontroli nad formatami dat, zdecydowanie polecam sprawdzenie momentjs. Wspaniała biblioteka - i tylko 5 KB. http://momentjs.com/


7
Obsługuje lokalizację jak urok.
Risadinha

Obecnie używamy date-fns - traktuje daty jako Niezmienne (Moment mutuje daty), jest szybszy i ma budowę modułową (wystarczy zaimportować to, czego potrzebujesz).
Freewalker

2
Sześć lat po opublikowaniu tego momentjs nabrał sporo wagi. Możesz zamiast tego zajrzeć na github.com/iamkun/dayjs - opisałem to jako „momentjs na diecie”. Ten sam prosty interfejs API.
benjamin.keen

55

Możesz użyć moment.js: http://momentjs.com/

var m = moment().format("DD/MM/YYYY");

document.write(m);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>


30
Moment to przesada, by uzyskać aktualną datę.
Dan Dascalescu

Lub moment().format("L")szanować aktualne ustawienia regionalne.
Dunc,

@DanDascalescu W rzeczywistości podstawowa specyfikacja JavaScript dla DateTime jest taka zła.
Todd

Jeśli masz już momentjs zaimportowane do twojego projektu, jest to najczystsza najprostsza odpowiedź.
Adil H. Raza

52

var d = (new Date()).toString().split(' ').splice(1,3).join(' ');

document.write(d)

Aby podzielić go na kroki:

  1. (new Date()).toString() daje „Pt 28 czerwca 2013 15:30:18 GMT-0700 (PDT)”

  2. (new Date()).toString().split(' ') dzieli powyższy ciąg na każdą spację i zwraca tablicę w następujący sposób: [„Pt”, „Jun”, „28”, „2013”, „15:31:14”, „GMT-0700”, „(PDT)” ]

  3. (new Date()).toString().split(' ').splice(1,3).join(' ') pobiera drugą, trzecią i czwartą wartość z powyższej tablicy, łączy je spacjami i zwraca ciąg „28 czerwca 2013 r.”


2
Potrzebowałem czasu w 00:00:00 i nie chciałem go odbudowywać ręcznie; krok 2 doskonale mnie tam prowadzi. Sława!
panhandel

3
Możesz zaoszczędzić kilka bajtów, wykonując następujące czynności:Date().split(' ').splice(1,3).join(' ')
hyde

47

Działa to za każdym razem:

    var now = new Date();
    var day = ("0" + now.getDate()).slice(-2);
    var month = ("0" + (now.getMonth() + 1)).slice(-2);
    var today = now.getFullYear() + "-" + (month) + "-" + (day);
    
    console.log(today);


45
var date = new Date().toLocaleDateString("en-US");

Możesz także wywołać metodę toLocaleDateStringz dwoma parametrami:

var date = new Date().toLocaleDateString("en-US", {
    "year": "numeric",
    "month": "numeric"
});

Artykuł o MSDN . Więcej o tej metodzie na MDN .


Fajnie, działa na Chrome. Niestety nie działa na PhantomJS od 22.04.2016
Chris

fajne rozwiązanie. powinien być na górze. new Date().toLocaleDateString("de-de")robi dla mnie lewę.
user3772108

29

Czystsza, prostsza wersja:

new Date().toLocaleString();

Wynik różni się w zależności od lokalizacji użytkownika :

2/27/2017, 9:15:41 AM


27

Jeśli jesteś zadowolony z formatu RRRR-MM-DD, spełni to zadanie.

new Date().toISOString().split('T')[0]

2018-03-10


Ponieważ długość jest zawsze stała, możemy również użyć podciągów. nowa data (). toISOString (). substring (0, 10); Może być trochę szybszy.
Mika Karjunen,

23

Możesz użyć biblioteki Date.js, która rozszerza obiekt Date, dzięki czemu możesz mieć metodę .today ().


11
jeśli używasz interfejsu jquery z datownikiem, możesz użyć $ .datepicker.formatDate („rr / mm / dd”, nowa data ())
Peter Munnings


16

Odpowiedź Varuna nie uwzględnia TimezoneOffset . Oto wersja, która:

var d = new Date()
new Date(d.getTime() - d.getTimezoneOffset() * 60000).toJSON().slice(0, 10) // 2015-08-11

TimezoneOffsetminuty, podczas gdy konstruktor daty zajmuje milisekundy, a zatem pomnożenie przez 60000.


15

Najkrótsza odpowiedź to: new Date().toJSON().slice(0,10)


Szukałem bardzo prostej funkcji nasion, która zmienia się regularnie. Ta odpowiedź to prawdziwa uczta.
nirazul


11

Zwróci toISOString()tylko aktualny czas UTC, a nie czas lokalny. Musimy ustalić datę za pomocą funkcji „.toString ()”, aby uzyskać datę w yyyy-MM-ddformacie podobnym do

document.write(new Date(new Date().toString().split('GMT')[0]+' UTC').toISOString().split('T')[0]);

Aby uzyskać datę i godzinę w yyyy-MM-ddTHH:mm:ssformacie

document.write(new Date(new Date().toString().split('GMT')[0]+' UTC').toISOString().split('.')[0]);

Aby uzyskać datę i godzinę w yyyy-MM-dd HH:mm:ssformacie

document.write(new Date(new Date().toString().split('GMT')[0]+' UTC').toISOString().split('.')[0].replace('T',' '));


10

Jeśli chcesz prostego DD/MM/YYYYformatu, właśnie wymyśliłem to proste rozwiązanie, chociaż nie zawiera ono poprzedzających zer.

var d = new Date();
document.write( [d.getDate(), d.getMonth()+1, d.getFullYear()].join('/') );



8

NAJNOWSZA EDYCJA: 23.08.19 Biblioteka date-fns działa podobnie jak moment.js, ale ma DUŻO mniejszą powierzchnię. Pozwala ci wybrać, które funkcje chcesz uwzględnić w projekcie, dzięki czemu nie musisz kompilować całej biblioteki, aby sformatować dzisiejszą datę. Jeśli minimalna biblioteka stron trzecich nie jest opcją dla twojego projektu, popieram zaakceptowane rozwiązanie przez Samuela Meddowsa do góry.

Zachowanie historii poniżej, ponieważ pomogło kilku osobom. Ale, dla przypomnienia, jest dość zuchwały i może złamać się bez ostrzeżenia, podobnie jak większość rozwiązań w tym poście

EDYCJA 2/7/2017 Jednowierszowe rozwiązanie JS:

tl; dr

var todaysDate = new Date(Date.now()).toLocaleString().slice(0,3).match(/[0-9]/i) ? new Date(Date.now()).toLocaleString().split(' ')[0].split(',')[0] : new Date(Date.now()).toLocaleString().split(' ')[1] + " " + new Date(Date.now()).toLocaleString().split(' ')[2] + " " + new Date(Date.now()).toLocaleString().split(' ')[3];

edge, ff latest, & chrome return todaysDate = "2/7/2017"
„działa” * w IE10 +

Wyjaśnienie

Dowiedziałem się, że IE10 i IE Edge działają nieco inaczej… idź. z new Date(Date.now()).toLocaleString()wejściem

Zwraca IE10:

"Tuesday, February 07, 2017 2:58:25 PM"

Mógłbym napisać dużą długą funkcję i FTFY. Ale naprawdę powinieneś użyć moment.js do tego. Mój skrypt po prostu to oczyszcza i daje rozwiniętą tradycyjną notację amerykańską:> todaysDate = "March 06, 2017"

Zwraca IE EDGE:

"‎2‎/‎7‎/‎2017‎ ‎2‎:‎59‎:‎27‎ ‎PM"

Oczywiście nie mogło być tak łatwo. Ciąg daty Edge ma niewidoczne znaki „•” między każdym widocznym. Więc nie tylko będziemy teraz sprawdzać, czy pierwszy znak jest liczbą, ale pierwsze 3 znaki, ponieważ okazuje się, że dowolny pojedynczy znak z całego zakresu dat będzie ostatecznie kropką lub ukośnikiem w pewnym momencie. Aby uprościć sprawę , wystarczy .slice () pierwsze trzy znaki (mały bufor dla przyszłych shenaniganów), a następnie sprawdź liczby. Należy prawdopodobnie zauważyć, że te niewidoczne kropki mogą potencjalnie pozostać w twoim kodzie. Być może skopałbym to, jeśli masz większe plany niż tylko wydrukowanie tego ciągu na swój widok.

∴ zaktualizowany one-liner:

var todaysDate = new Date(Date.now()).toLocaleString().slice(0,3).match(/[0-9]/i) ? new Date(Date.now()).toLocaleString().split(' ')[0].split(',')[0] : new Date(Date.now()).toLocaleString().split(' ')[1] + " " + new Date(Date.now()).toLocaleString().split(' ')[2] + " " + new Date(Date.now()).toLocaleString().split(' ')[3];

To do bani czytać. Co powiesz na:

var dateString = new Date(Date.now()).toLocaleString();
var todaysDate = dateString.slice(0,3).match(/[0-9]/i) ? dateString.split(' ')[0].split(',')[0] : dateString.split(' ')[1] + " " + dateString.split(' ')[2] + " " + dateString.split(' ')[3];

ORYGINALNA ODPOWIEDŹ

Mam dla ciebie liniówkę:

new Date(Date.now()).toLocaleString().split(', ')[0];

i [1]da ci porę dnia.


7

Możesz tego użyć

<script>
function my_curr_date() {      
    var currentDate = new Date()
    var day = currentDate.getDate();
    var month = currentDate.getMonth() + 1;
    var year = currentDate.getFullYear();
    var my_date = month+"-"+day+"-"+year;
    document.getElementById("dateField").value=my_date;    
}
</script>

HTML jest

<body onload='return my_curr_date();'>
    <input type='text' name='dateField' id='dateField' value='' />
</body>

6

Jeśli używasz jQuery. Wypróbuj tę jedną wkładkę:

$.datepicker.formatDate('dd/mm/yy', new Date());

Oto konwencja formatowania daty

  • d - dzień miesiąca (bez wiodącego zera)
  • dd - dzień miesiąca (dwie cyfry)
  • o - dzień roku (bez zer wiodących)
  • z oo - dzień roku (trzy cyfry)
  • D - skrót nazwy dnia
  • DD - nazwa dnia długa
  • m - miesiąc roku (bez wiodącego zera)
  • mm - miesiąc roku (dwie cyfry)
  • M - krótka nazwa miesiąca
  • MM - nazwa miesiąca
  • y - rok (dwie cyfry)
  • rr - rok (czterocyfrowy)

Oto odwołanie do jpickera datepicker


5

Prostym sposobem na osiągnięcie tego (biorąc pod uwagę bieżącą strefę czasową, korzystając z formatu ISO rrrr-mm-dd) jest:

let d = new Date().toISOString().substring(0,19).replace("T"," ") // "2020-02-18 16:41:58"

Zwykle jest to dość uniwersalny format daty i w razie potrzeby można go przekonwertować na czystą wartość daty:

Date.parse(d); // 1582044297000

4

Możesz to sprawdzić

var today = new Date();
today = parseInt(today.getMonth()+1)+'/'+today.getDate()+'/'+today.getFullYear()+"\nTime : "+today.getHours()+":"+today.getMinutes()+":"+today.getSeconds();
document.write(today);

Zobacz dokumentację konstruktora Date (). połączyć


4

O co w tym wszystkim chodzi .. Najczystszym sposobem na to jest

var currentDate=new Date().toLocaleString().slice(0,10);


1
Zwróci błędy, takie jak ten 3/4/2018, , lepiej użyć new Date().toJSON().slice(0,10).
DevonDahon

Jest to idealne rozwiązanie, aby uzyskać datę wyświetlenia lub informacje w dzienniku konsoli lub w interfejsie użytkownika. Lepiej dla mnie bez.slice(0,10)
Paul Carlton

4

To może ci pomóc

var date = new Date();
console.log(date.getDate()+'/'+(date.getMonth()+1)+'/'+date.getFullYear());

Spowoduje to wydrukowanie bieżącej daty w formacie dd / MM / rrrr



3

Myślę, że to stare pytanie, ale najprostszym sposobem byłoby:

var date = new Date();
var TimeStamp = date.toLocaleString();

function CurrentTime(){
  alert(TimeStamp);
}

Spowoduje to pobranie bieżącego czasu, przekazanie go do ciągu na podstawie lokalizacji, a następnie można wywołać funkcję CurrentTime, aby wyświetlić czas. Byłby to dla mnie najbardziej skuteczny sposób na uzyskanie znacznika czasu na coś.


Zwróci to dane + czas, np. „2018-4-6 16:20:22”, a pytanie brzmi: jak uzyskać tylko datę.
Vlad Bezden,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.