MySQL funktsioonid kuupäeva ja kellaajaga töötamiseks. MySQL-i kalendriandmete tüübid: kasutusfunktsioonid


selle artikli avaldamine on lubatud ainult koos lingiga artikli autori veebisaidile

Nagu teate, salvestatakse kõik kuupäevad mysql-is vastupidises järjekorras aasta-kuu-päev (2008-10-18), mõnikord isegi ilma eraldajata (20081018).
Kuupäeva kuvamiseks peate selle teisendama tavalisele loetavale kujule.

Konversiooniks on kaks meetodit, tõhusad ja mitte eriti tõhusad.
Ebaefektiivne viis on see, kui mysql-i kuupäev teisendatakse php-ga.
Mina isiklikult tegin seda väga pikka aega. Enne kuvamist muutsin iga kuupäeva php funktsiooni abil ümber.
Kui teisenduste arv ei ole suur, siis saab PHP-ga kuupäeva ümber pöörata, selles pole midagi halba, aga kui on vaja välja tõmmata kümneid või sadu tuhandeid kirjeid ja kuupäev igas konverteerida, siis loomulikult teisendada kuupäevad kasutades mysql on palju kiirem.

Mysql-il on suurepärane funktsioon DATE_FORMAT(), see on väga sarnane funktsiooniga php date().
Siin on näide kasutamisest

SELECT DATE_FORMAT("2008-11-19","%d.%m.%Y");
tulemus

Kõik on väga lihtne ja kiire, php abil pole vaja kuupäevi muuta.
Siin on selle funktsiooni definitsioonide loend

Determinant Kirjeldus
%M Kuu nimi (jaanuar...detsember)
%W Nädalapäeva nimi (pühapäev...laupäev)
%D Kuupäev ingliskeelse järelliitega (0st, 1st, 2nd, 3rd jne)
%Y Aasta, kuupäev, 4 numbrit
%y Aasta, kuupäev, 2 numbrit
%X Aasta nädala jaoks, kus pühapäeva peetakse nädala esimeseks päevaks, number, 4 numbrit, kasutatakse koos "%V"
%x Aasta nädala jaoks, kus pühapäeva peetakse nädala esimeseks päevaks, number, 4 numbrit, kasutatakse koos "%v"
%a Nädalapäeva lühendatud nimi (p...la)
%d Kuu päev, number (00..31)
%e Kuu päev, number (0..31)
%m Kuu, kuupäev (00..12)
%c Kuu, kuupäev (0..12)
%b Kuu lühendatud nimi (jaan...dets)
%j Aasta päev (001..366)
%H Tund (00..23)
%k Tund (0...23)
%h Tund (01..12)
% I Tund (01..12)
%l Tund (1...12)
%i Minutid, arv (00..59)
%r Kellaaeg, 12-tunnine vorming (hh:mm:ss M)
%T Kellaaeg, 24-tunnine vorming (hh:mm:ss)
%S Sekundid (00..59)
%s Sekundid (00..59)
%p AM või PM
% w Nädalapäev (0=pühapäev..6=laupäev)
%U Nädal (00..53), kus nädala esimeseks päevaks loetakse pühapäeva
%u Nädal (00..53), kus nädala esimeseks päevaks loetakse esmaspäeva
%V Nädal (01..53), kus nädala esimeseks päevaks loetakse pühapäeva. Kasutatakse koos "%X"
%v Nädal (01..53), kus nädala esimeseks päevaks loetakse esmaspäeva. Kasutatakse koos "%x"
%% Sõnasõnaline "%".

Kommentaarid

27.11.2008 ----
Hei shaitan!!!
Ise olen php ja mysql kallal töötanud viis aastat ja kogu aeg muutsin php-s kuupäeva...
Mulle isegi ei tulnud pähe, et sisseehitatud mysql-funktsiooni oleks lihtsam kasutada

28.11.2008 Zheka
Samamoodi! Olen alati kasutanud oma php funktsiooni

03.12.2008 Sergei
Noh, üldiselt, kas keegi isegi kasutab seda lähenemisviisi?
Või kasutavad kõik kuupäeva ümberpööramiseks php-d?
Mina isiklikult pole kunagi mysqlis kuupäeva ümber pööranud, teen ikka kõike php-s

28.06.2009 Ilja
Kahjuks midagi ei töötanud :(

08.07.2009 Vitali
Lahe, täname funktsiooni eest. Huvitav, mis vingerpussi seal veel on?

14.07.2009 DSaint
Aitäh, see aitas palju. Jääb vaid kuvada kuu nimi vene keeles)

28.07.2009 Vlad
mysql=>PHP
valige unix_timestamp(alguskuupäev) kui alguskuupäev_php
php-kood
kuupäev("d.m.Y",$row["alguskuupäev_php"])

PHP=>MySQL
värskenda tabeli komplekt algus_kuupäev=DATE_FORMAT(STR_TO_DATE("19/12/2009 18:35:22 PM","%d.%m.%Y %H:%i"),"%Y.%m.%d % Tere")

18.08.2009 Külaline
2:DSaint
Seal on selline suurepärane funktsioon:
ELT(KUU("2004-04-10"), "jaan.","veebr."märts","aprill."mai","juuni","juuli","aug."," sept.""okt.","nov.""dets.")

Kasuta seda. :-)

29.10.2009 Vladimir
Aitäh, ELT kohta(KUU("2004-04-10"), "jaan.","veebr."märts","aprill."mai","juuni","juuli","aug." . ","sept.","oktoober.","dets.")
ma pole kuulnud.

07.10.2010 Jevgeni
Mis töötab kiiremini? Teisendus päringus või PHP funktsiooni tulemusena?

07.10.2010 kaitsja
Vähemalt vähem mälu, mida töödelda, vähem funktsioonikutseid, vähem mälueraldisi... Ma kasutan midagi sellist pidevalt, aga mitte mysql-is, vaid postgresqlis.

08.10.2010 Admin
Kaitsja Jevgeni ütles õigesti, et see teisendus peaks andmebaasi kaudu ilusamini toimima, kuid muidugi, kui me räägime tohutu hulga andmete ekstraheerimisest.
Kui tõmmata 10-20 kirjet, siis pole vahet, kuidas kuupäev teisendada, võrreldes teiste koormustega, see on tühiasi.

27.01.2011 pcemma
uhh tänud afftorile (: pole enam vaja kasutada minu mega lahedat funktsiooni teisendamiseks (:

13.04.2011 Xes
KUIDAS SEDA PHP-s KASUTADA
while ($sqlr=mysql_fetch_array($sql))
{
echo ($sqlr["comadd"]." ".$sqlr["kommentaar"]."

");

$sqlr["comadd"] – kas peate selle esitama tavavormis?
}

14.04.2011 Vitali
Mul on andmebaasis kuupäev vormingus 19.11.2008, tabelitüüp VARCHAR, kuidas saan selle andmebaasi ümber kirjutada vormingus 2008-11-19?
Käed lihtsalt väga pikka aega...
Aitäh.

15.04.2011 admin
Xes on MySQL-i funktsioon, peate seda kasutama sql-päringus, mis teie koodi järgi otsustades asub kuskil ülal. Seda ei saa selles koodiosas kasutada.

15.04.2011 admin
Vitali, muuda lihtsalt lahtri tüübiks DATE, mysql teisendab kõik selles lahtris olevad andmed automaatselt vormingusse 2008-11-19.
Aga igaks juhuks enne lahtritüübi muutmist tee sellest tabelist dump, sest äkki teeb andmebaas midagi valesti ja tabel läheb üldse katki.

Kui teil on oluline jätta välja tüüp varchariks, siis pärast DATE tüübi määramist seadke see tagasi varchar...

See on kõige lihtsam variant, kuid mitte täiesti õige, kuid kontrollisin, et see töötab.

14.05.2011 DDD
date("d-m-Y",strtotime("$myrow"));

24.05.2011 Konstantin
ja ma võtan alati SELECT *,UNIX_TIMESTAMP(created) NAGU loodud FROM...
Aga mootoriga saan hakkama igas formaadis. Kasvõi ainult päev, isegi ainult üks aeg...
ja võrrelge, kumb on suurem kui 14.05.2011 või 14.05.2010...
Ja ma kirjutan selle nii:
...date=".gmdate("Y-m-d H:i:s",$created)...
ja üldiselt ei näe ma põhjust harjumusi muuta

24.05.2011 Sergei
Konstantin, ma ise kasutan väljundiks php date(), aga siin kaalume võimalust teisendada kuupäev mitte läbi php, vaid läbi mysql.

Ma ütleks, et see on lihtsalt ülevaade mysql funktsioonist ja sellel on kindlasti õigus eksisteerida...

Need funktsioonid on loodud töötama ka kalendri andmetüüpidega. Vaatame neid lähemalt.

  • DATE_FORMAT(kuupäev, vorming) vormindab kuupäeva vastavalt valitud vormingule. Seda funktsiooni kasutatakse väga sageli. Näiteks MySQL-is on kuupäevavorming AAAA-KK-PP (aasta-kuu-päev), samas kui meile on rohkem tuttav vorming PP-KK-AAAA (kuupäev-kuu-aasta). Seetõttu tuleb kuupäeva tavapäraseks kuvamiseks see ümber vormindada. Esitame esmalt päringu ja seejärel mõtleme välja, kuidas vormingut määrata:

    SELECT DATE_FORMAT(CURDATE(), "%d.%m.%Y");

    Nüüd tundub kuupäev meile tuttav. Kuupäevavormingu määramiseks kasutatakse spetsiaalseid määrajaid. Mugavuse huvides loetleme need tabelis.

    Defred Kirjeldus
    %a Nädalapäeva lühendatud nimetus (E - Esmaspäev, T - Teisipäev, K - Kolmapäev, N - Neljapäev, P - Reede, L - Laupäev, P - Pühapäev).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%a");

    Tulemus:

    %b Kuude lühendatud nimetused (jaan - jaanuar, veebr - veebruar, märts - märts, aprill - aprill, mai - mai, juuni - juuni, juuli - juuli, aug - august, sept - september, okt - oktoober, nov - november, detsember - detsember).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%b");

    Tulemus:

    %c Kuu numbrilises vormis (1 - 12).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%s");

    Tulemus:

    %d Kuupäev numbrilises vormis nulliga (01 - 31).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%d");

    Tulemus:

    %D Kuu päev inglise keeles (1., 2....).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%D");

    Tulemus:

    %e Kuupäev numbrilises vormis ilma nullita (1 - 31).

    Näide:

    SELECT DATE_FORMAT(CURDATE(), "%e");

    Tulemus:

    %H Tunnid eesoleva nulliga vahemikus 00 kuni 23.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 23:03:20", "%H");

    Tulemus:

    %h Kell nulliga 00 kuni 12.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 23:03:20", "%h");

    Tulemus:

    %i Minutid 00 kuni 59.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 23:03:20", "%i");

    Tulemus:

    %j Aasta päev 001 kuni 366.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 23:03:20", "%j");

    Tulemus:

    %k Kell nulliga 0 kuni 23.

    Näide:

    SELECT DATE_FORMAT("2011-12-31 01:03:20", "%k");

    Tulemus:

    %l Kell ilma eesnullita 1 kuni 12.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%l");

    Tulemus:

    %M

    Näide:

    Tulemus:

    %M Kuu nimi ilma lühendita.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%M");

    Tulemus:

    %m Kuu numbrilises vormis alguses nulliga (01 - 12).

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%m");

    Tulemus:

    %p AM või PM 12-tunnise vormingu jaoks.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%p");

    Tulemus:

    %r Aeg 12-tunnises formaadis.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%r");

    Tulemus:

    %s Sekundid vahemikus 00 kuni 59.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 00:03:20", "%s");

    Tulemus:

    %T Aeg 24-tunnises formaadis.

    Näide:

    SELECT DATE_FORMAT("2011-04-15 21:03:20", "%T");

    Tulemus:

    %u Nädal (00 - 52), kus nädala esimene päev on esmaspäev.

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%u");

    Tulemus:

    %U Nädal (00 - 52), kus nädala esimene päev on pühapäev.

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%U");

    Tulemus:

    %W Nädalapäeva nimi ilma lühendita.

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%W");

    Tulemus:

    % w Nädalapäeva number (0 - pühapäev, 6 - laupäev).

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%w");

    Tulemus:

    %Y Aasta, 4 kategooriat.

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%Y");

    Tulemus:

    %y Aasta, 2 kategooriat.

    Näide:

    SELECT DATE_FORMAT("2011-04-17 21:03:20", "%y");

    Tulemus:


  • STR_TO_DATE(kuupäev, formaat) on eelmise pöördfunktsioon, see võtab kuupäeva vormingus ja tagastab kuupäeva MySQL-vormingus.

    SELECT STR_TO_DATE("04/17/2011 23:50", "%d.%m.%Y %H:%i");



  • Funktsioon TIME_FORMAT(aeg, vorming) on ​​sarnane funktsiooniga DATE_FORMAT(), kuid seda kasutatakse ainult aja jaoks:

    SELECT TIME_FORMAT("22:38:15", "%H-%i-%s");



  • Funktsioon GET_FORMAT(kuupäev, vorming) tagastab vormingustringi, mis vastab ühele viiest ajavormingust:

    EUR – Euroopa standard
    USA – Ameerika standard
    JIS – Jaapani tööstusstandard
    ISO – ISO standard (Rahvusvaheline Standardiorganisatsioon)
    INTERNAL – rahvusvaheline standard

    Seda funktsiooni on hea kasutada koos eelmisega – DATE_FORMAT(). Vaatame näidet:

    SELECT GET_FORMAT(DATE, "EUR"), DATE_FORMAT("2011-04-17", GET_FORMAT(DATE, "EUR"));


    Nagu näete, tagastab funktsioon GET_FORMAT() ise esitlusvormingu ja koos funktsiooniga DATE_FORMAT() toodab kuupäeva vajalikus vormingus. Tehke oma päringud kõigi viie standardiga ja vaadake erinevust.

Noh, nüüd teate peaaegu kõike MySQL-is kuupäevade ja kellaaegadega töötamise kohta. See on teile erinevate veebirakenduste arendamisel väga kasulik. Näiteks kui kasutaja sisestab veebisaidil olevale vormile kuupäeva talle tuttavas vormingus, ei ole teil keeruline rakendada vajalikku funktsiooni, et kuupäev ilmuks andmebaasi vajalikus vormingus.

Väärtused nendes vormingutes:

    Stringina vormingus "AAAA-KK-PP" või "AA-KK-PP" . Leebe süntaks on lubatud: kuupäevaosade eraldajana võib kasutada mis tahes kirjavahemärki. Näiteks "2012-12-31" , "2012/12/31" , "2012^12^31" ja "2012@12@31" on samaväärsed.

    Eraldajateta stringina vormingus "YYYYMMDD" või "YYMMDD" tingimusel, et string on kuupäevana mõistlik. Näiteks "20070523" ja "070523" tõlgendatakse kui "2007-05-23", kuid "071332" on ebaseaduslik (selles on mõttetud kuu- ja päevaosad) ja muutub "0000-00-00".

    Numbrina vormingus YYYYMMDD või YYMMDD , kui see arv on kuupäevana mõistlik. Näiteks 19830905 ja 830905 tõlgendatakse kui "1983-09-05" .

Seetõttu ei ole string "25/08/2012" kehtiv MySQL-i kuupäevaliteraal. Teil on neli võimalust (mingis ebamäärases eelistuse järjekorras, ilma teie vajaduste kohta täiendava teabeta):

    Seadistage kuupäevavalija pakkuma kuupäevi toetatud vormingus, kasutades altField koos altFormatiga:

    $("selector").datepicker(( altField: "#actualDate" altFormaat: "yyyy-mm-dd" ));

    Või kui olete rahul, et kasutajad näevad kuupäeva vormingus AAAA-KK-PP, määrake selle asemel lihtsalt parameeter dateFormat:

    $("valija").datepicker(( dateFormat: "yyyy-mm-dd" ));

  • $dt = \DateTime::createFromFormat("m/d/Y", $_POST["kuupäev"]);

    ja siis kas:

      hankige sobiv vormindatud string:

      $kuupäev = $dt->formaat("Y-m-d");

      hankige UNIX-i ajatempel:

      $timestamp = $dt->getTimestamp();

      mis seejärel edastatakse otse MySQL-ile FROM_UNIXTIME() :

      INSERT INTO user_date VALUES ("", "$name", FROM_UNIXTIME($timestamp))

  • Sisestage string käsitsi kehtivasse literaali:

    $osad = explode("/", $_POST["kuupäev"]); $date = "$osad-$osad-$osad";

Hoiatus

    Teie kood on SQL-i süstimise suhtes haavatav. Peaksite tõesti kasutama ettevalmistatud avaldusi, kus edastate parameetritena oma muutujad, mida SQL-ile ei hinnata. Kui te ei tea, millest ma räägin või kuidas seda parandada, lugege Bobby Tablesi lugu.

  • Tüüpi DATE kasutatakse väärtuste jaoks, millel on kuupäevaosa, kuid mitte ajaosa. MySQL hangib ja kuvab DATE väärtused vormingus "AAAA-KK-PP". Toetatud vahemik on "1000-01-01" kuni "9999-12-31".

    Tüüpi DateTime kasutatakse väärtuste jaoks, mis sisaldavad nii kuupäeva kui ka kellaaega. MySQL hangib ja kuvab DateTime väärtused vormingus "AAAA-KK-PP HH:MM:SS" . Toetatud vahemik on "1000-01-01 00:00:00" kuni "9999-12-31 23:59:59".

Seega on kõiki kalendriandmete tüüpe üksikasjalikult kirjeldatud jaotises “10.3. Kuupäeva ja kellaaja tüübid » MySQL-i õpetused. Oluline teave ajavööndite DBMS-i toe kohta on kirjeldatud jaotises „9.7. MySQL serveri ajavööndi tugi". Kõik järgnev põhineb käsiraamatu uurimisel. Samal ajal on siin välja toodud ainult ühe või teise tüübi kasuks valimise nüansid, nii et see materjal ei asenda juhendit mingil moel, vaid täiendab seda.

Esiteks iga tüübi lühikirjeldus:

  • TIMESTAMP – andmetüüp kuupäeva ja kellaaja salvestamiseks. Andmed salvestatakse sekundite arvuna, mis on möödunud Unixi ajastu algusest. Väärtuste vahemik: 1970-01-01 00:00:00 - 2038-12-31 00:00:00. Mahutab 4 baiti.
  • YEAR – andmetüüp aasta salvestamiseks. Väärtuste vahemik: 1901–2155. Mahutab 1 baiti.
  • DATE on andmetüüp kuupäevade salvestamiseks. Väärtuste vahemik: 1000-01-01 - 9999-12-31. Mahutab 3 baiti.
  • AEG on andmetüüp aja salvestamiseks. Väärtuste vahemik: −828:59:59 - 828:59:59. Mahutab 3 baiti.
  • DATETIME on andmetüüp kuupäeva ja kellaaja salvestamiseks. Väärtuste vahemik: 1000-01-01 00:00:00 - 9999-12-31 00:00:00. Mahutab 8 baiti.
Märkus perenaisele. Huvitav on see, et enamik programmeerijaid usub, et ajatempli mõiste on Unixi aeg. Tegelikult on ajatempel märk, mis on tähemärkide jada, mis näitab kuupäeva ja/või kellaaega, millal teatud sündmus toimus. Ja Unixi aeg (Unixi aeg) või POSIX-aeg on sekundite arv, mis on möödunud 1. jaanuari 1970 UTC keskööst. Ajatempli mõiste on laiem kui Unixi aeg.

Pärast ülaltoodud tüüpide kirjelduse analüüsimist saate teha peaaegu kõik järeldused teatud tüüpide eeliste ja puuduste kohta. Kõik on üsna lihtne ja ilmne.

Kuid enne nende tüüpide kasutamisest rääkimist tahan märkida, et praktikas kasutatakse kuupäeva ja kellaaja salvestamiseks sageli teist tüüpi: täisarvu (kuupäeva salvestamiseks - INT (4 baiti), kuupäev ja kellaaeg - BIGINT (8). baiti)). Ainus erinevus täisarvu tüüpide ning DATE ja DATETIME kasutamise vahel on see, et väljastamisel andmeid ei vormindata ning kuupäevade ja kellaaegadega arvutustes tuleb täisarvud teisendada sobivasse kalendritüüpi. Lisaks ei kontrollita enne salvestamist esitatud väärtuse kehtivust. Sorteerimisvõimalused säilivad. Seetõttu on mõttekas kasutada INT ja BIGINT samadel juhtudel nagu DATE ja DATETIME, et maksimeerida teisaldatavust ja sõltumatust DBMS-ist. Ma ei näe muid eeliseid, kui neid on, soovitan teil need kommentaarides märkida.

Kalendri andmetüüpide kasutamine MySQL-is

Alustame kõige lihtsamast – tüübist AASTA. Selle ainus eelis on väiksus - ainult 1 bait. Kuid seetõttu on kehtivate väärtuste vahemik rangelt piiratud (tüüp suudab salvestada ainult 255 erinevat väärtust). Mul on raske ette kujutada praktilist olukorda, kus võiks soovida salvestada aastaid rangelt vahemikus 1901 kuni 2155. Lisaks annab tüüp SMALLINT (2 baiti) vahemiku, mis on enamikul juhtudel piisav aasta salvestamiseks. Ja 1 baidi salvestamine andmebaasi tabelisse rea kohta pole meie ajal mõtet.

Tüübid KUUPÄEV Ja KUUPÄEV KELLAAEG saab ühendada üheks rühmaks. Nad salvestavad kuupäeva või kuupäeva ja kellaaega üsna suure hulga kehtivate väärtustega, sõltumata serveris seatud ajavööndist. Nende kasutamine on kindlasti praktiline. Kuid kui soovite salvestada kuupäevi ajalooliste sündmuste jaoks, mis ulatuvad kaugemale kui tavaline ajastu, peate valima muud andmetüübid. Need tüübid sobivad ideaalselt teatud sündmuste kuupäevade salvestamiseks, mis võivad jääda väljapoole TIMESTAMP tüüpi (sünnipäevad, toote väljalaskekuupäevad, presidendivalimised, kosmoserakettide stardid jne). Nende tüüpide kasutamisel peate arvestama ühe olulise nüansiga, kuid sellest allpool.

Tüüp AEG saab kasutada ajaperioodide salvestamiseks, mil täpsust alla 1 sekundi pole vaja, ja ajavahemikke, mis on lühemad kui 829 tundi. Rohkem pole siia midagi lisada.

Kõige huvitavam tüüp jääb - TIMESTAMP. Seda tuleks kaaluda võrreldes DATE ja DATETIME: TIMESTAMP on loodud ka teatud sündmuste toimumise kuupäeva ja/või kellaaja salvestamiseks. Oluline erinevus nende vahel on väärtusvahemikes: ilmselgelt ei sobi TIMESTAMP ajalooliste sündmuste (isegi näiteks sünnipäevade) salvestamiseks, küll aga suurepäraselt jooksvate (logimine, artiklite postitamise kuupäevad, toodete lisamine, tellimuste esitamine) salvestamiseks. ja lähitulevikus toimuvad sündmused (uute versioonide väljalasked, kalendrid ja planeerijad jne).

Tüübi TIMESTAMP kasutamise peamine mugavus seisneb selles, et seda tüüpi tabelite veergudele saate määrata vaikeväärtuse praeguse kellaaja asendamise vormis, samuti praeguse aja määramise kirje värskendamisel. Kui vajate neid funktsioone, siis on 99% tõenäosus, et TIMESTAMP on täpselt see, mida vajate. (Kuidas seda teha, vaadake juhendit.)

Ärge kartke, et teie tarkvara lakkab töötamast 2038. aasta lähenedes. Esiteks, enne seda aega teie tarkvara (eriti praegu kirjutatavate versioonide) kasutamine suure tõenäosusega lihtsalt lõpetatakse. Teiseks mõtlevad MySQL-i arendajad selle kuupäeva lähenedes kindlasti midagi välja, et teie tarkvara funktsionaalsust säilitada. Kõik laheneb nagu ka Y2K probleem.

Seega kasutame tüüpi TIMESTAMP meie aja sündmuste kuupäevade ja kellaaegade salvestamiseks ning DATETIME ja DATE ajaloosündmuste või sügava tuleviku sündmuste kuupäevade ja kellaaegade salvestamiseks.

Väärtuste vahemikud on oluline erinevus tüüpide TIMESTAMP, DATETIME ja DATE vahel, kuid need ei ole peamine erinevus. Peamine et TIMESTAMP salvestab väärtuse UTC. Väärtuse salvestamisel tõlgitakse see praegusest ajavööndist UTC-sse ja lugemisel praegusest ajavööndist UTC-st. DATETIME ja DATE salvestavad ja kuvavad alati sama kellaaega, olenemata ajavöönditest.

Ajavööndid määratakse globaalselt MySQL DBMS-is või praeguse ühenduse jaoks Viimast saab kasutada erinevate kasutajate töö tagamiseks erinevates ajavööndites DBMS-i tasemel. Kõik ajaväärtused salvestatakse füüsiliselt UTC-s ning saadakse kliendilt ja antakse kliendile - tema ajavööndi väärtustes. Kuid ainult siis, kui kasutate andmetüüpi TIMESTAMP. DATE ja DATETIME saavad, salvestavad ja tagastavad alati sama väärtuse.

Funktsioon NOW() ja selle sünonüümid tagastavad ajaväärtuse kasutaja praeguses ajavööndis.

Arvestades kõiki neid asjaolusid, peate serveriga ühenduses ajavööndi muutmisel ja tüüpide DATE ja DATETIME kasutamisel olema äärmiselt ettevaatlik. Kui peate salvestama kuupäeva (näiteks sünnikuupäeva), siis probleeme ei teki. Sünnikuupäev on igas tsoonis sama. Need. kui olete sündinud 1. jaanuaril kell 0:00 UTC/GMT+0, siis see Mitte tähendab, et Ameerikas tähistavad nad sinu sünnipäeva 31. detsembril. Aga kui otsustate salvestada aega sündmused veerus DATETIME, siis ei ole lihtsalt võimalik töötada kasutaja ajavöönditega DBMS-i tasemel. Lubage mul selgitada näitega:

Kasutaja X töötab UTC/GMT+2 tsoonis, Y - UTC/GMT+3 tsoonis. Kasutajaühenduste jaoks MySQL-iga määratakse vastav (igaühel oma) ajavöönd. Kasutaja postitab foorumisse sõnumi, meid huvitab sõnumi kirjutamise kuupäev.

1. valik: DATETIME. Kasutaja X kirjutab sõnumi kell 14:00 UTC/GMT+2. Sõnumi väljal “kuupäev” olev väärtus asendatakse funktsiooni NOW() täitmise tulemusena - 14:00. Kasutaja Y loeb sõnumi kirjutamise aega ja näeb sama kella 14:00. Kuid tema seaded on seatud UTC/GMT+3 peale ja ta arvab, et sõnum ei kirjutatud mitte just nüüd, vaid tund aega tagasi.

2. valik: TIMESTAMP. Kasutaja X kirjutab sõnumi kell 14:00 UTC/GMT+2. Väli "kuupäev" sisaldab funktsiooni NOW() käivitamise tulemust - antud juhul - 12:00 UTC/GMT+0. UserY loeb sõnumi kirjutamise ja vastuvõtmise aja (UTC/GMT+3)(12:00 UTC/GMT+0) = 15:00 UTC/GMT+3. Kõik tuleb täpselt nii, nagu me tahame. Ja mis kõige tähtsam, seda on äärmiselt mugav kasutada: kohandatud ajavööndite toetamiseks ei pea te kirjutama ühtegi aja teisenduskoodi.

Praeguse kellaaja asendamise ja ajavöönditega töötamise võimalused TIMESTAMP tüübis on nii võimsad, et kui teatud logisse on vaja salvestada kuupäev ilma kellaajata, siis tuleks siiski DATE asemel kasutada TIMESTAMP, ilma 1 baiti erinevusest salvestamata. nende vahel. Sel juhul lihtsalt ignoreerige "00:00:00".

Kui te ei saa kasutada TIMESTAMP-i selle väärtuste suhteliselt väikese vahemiku tõttu (tavaliselt 1-2 juhtumit versus 10-15 saidi andmebaasis), peate kasutama DATETIME ja kohandama selle väärtusi hoolikalt õigetes kohtades ( st sellele väljale kirjutades teisendage kuupäev UTC-ks ja lugemisel - lugemise kasutaja tsooni kellaajaks). Kui salvestate ainult kuupäeva, pole tõenäoliselt vahet, milline ajavöönd teil on: kõik tähistavad uut aastat kohaliku aja järgi 1. jaanuaril, nii et te ei pea siin midagi tõlkima.

Alustuseks tahan puudutada teemat, millises vormingus on kõige parem kuupäevi andmebaasi salvestada: TIMESTAMP või KUUPÄEV KELLAAEG. Seda küsimust on korduvalt tõstatatud ja tõstatatakse foorumites, blogides jne. Kuid selleks, et mitte kohe otsingumootoritesse saata, proovin erinevust näidata lihtsate sõnade ja näitega. Tüüp KUUPÄEV KELLAAEG- salvestab kuupäeva väärtuse vormingus "AAAA-KK-PP HH:MM:SS" ja ei sõltu ajavööndist. TIMESTAMP- salvestab ajatempli, st. sekundite arv, mis on möödunud 1. jaanuarist 1970. MySQL teisendab need väärtused, võttes arvesse praegust ajavööndit nii andmebaasi kirjutades kui ka sealt väljastades. Mida see tähendab...
Näiteks lisasite just artikli andmebaasi, teie kalendris on 2014. aasta esimene jaanuar ja kell on kell 01:00. Kui kuupäevaväli on tüübiga DATETIME, siis näevad kõik saidi külastajad täpselt seda kuupäeva ja kellaaega, olenemata nende elukohast. Kõik näib olevat korras, kuid kasutaja ( nimetagem teda "Bill G"), elab kuskil New Yorgis, esimene jaanuar pole veel kätte jõudnud - tema jaoks on 31. detsember 2013 ja kell näitab 19:00. Ta on kergelt hämmeldunud, sest... Ta ei ole veel uut aastat tähistama hakanud, aga ta kujutab juba ette "artiklit tulevikust" ;) TIMESTAMP tüübiga seda ei juhtu, sest Väljastamisel võetakse arvesse selle ajavööndit.
"Kõik on selge!", ütlete ja muudate kiiresti kõik kuupäevaväljad TIMESTAMP-tüüpi ning Bill G hingab kergendatult, kuid mitte kauaks. Teie saidil registreerudes märkis Bill oma sünnikuupäeva ja -kellaaja. Maailmas ringi reisides vaatab ta alati teie veebisaiti ja avastab õudusega, et tema sünniaeg ja mõnikord ka kuupäev on alati erinev, sest... kuvatakse, võttes arvesse ajavööndit, kus ta praegu asub. Jah, antud juhul tegi TIMESTAMP tüüp julma nalja.
Järeldame, et teatud ülesannete jaoks peate sõltuvalt soovitud tulemusest valima sobiva väljatüübi või juhtima salvestamist/väljundit.

Liigume edasi populaarsete probleemide ja nende lahendamise võimaluste juurde. Valige kirjed määratud kuupäevavahemikus, st. teatud aja jooksul.

SELECT * FROM `tabeli_nimi` WHERE `kuupäeva_väli` VAHEL "2014-07-05" JA "2014-07-15" ORDER BY "kuupäeva_väli";

Valitakse kõik kirjed, kus väljal "date_field" olevad kuupäevad jäävad vahemikku 5. juuli 2014 kuni 15. juuli 2014, sealhulgas määratud kuupäevad. Me ei tohi unustada, et vaikimisi salvestatakse MySQL-i kuupäevad vormingus "AAAA-KK-PP HH:MM:SS" ja vastavalt sellele on vormingu mask "%Y-%m-%d %H:%i: %s" (standard ISO). Kuidas probleemi lahendada, kui kuupäev pole selles vormingus? Loobume PHP valikutest ja vaatame, kuidas seda saab teha taotluses endas. Ja sellistel eesmärkidel vajame funktsiooni STR_TO_DATE(). Süntaks: STR_TO_DATE(str, vorming), kus" str" - kuupäeva string ja " vormingus" on sellele vastav formaat. Testime:

SELECT STR_TO_DATE("31/12/2013", "%d.%m.%Y"); /* "2013-12-31" */ SELECT STR_TO_DATE("31/12/13 13:50", "%d/%m/%y %H:%i"); /* "2013-12-31 13:50:00" */

Täitmise tulemuseks on kuupäev vormingus, mida MySQL-is vaikimisi kasutatakse. See tähendab, et me peame määrama mitte vormingu, milles soovime väljundkuupäeva saada, vaid vormingu, milles me töötlemiskuupäeva esitame. Seda meetodit kasutades võiks meie ülaltoodud kirje isegi välja näha selline:

SELECT * FROM `tabeli_nimi` WHERE `kuupäeva_väli` BETWEEN STR_TO_DATE("07/05/2014", "%d.%m.%Y") AND STR_TO_DATE("15. juuli 2014", "%M %d,%Y" ") ORDER `kuupäeva_väli`;

Kuna me puudutasime kuupäevade vormindamise küsimust, siis vaatame, kuidas saada kuupäev proovide võtmisel meile vajalikus vormingus, sest Paljud inimesed on palju rohkem harjunud nägema "31.12.2014" või "31.detsember 2014" kui "2014-12-31". Nendel eesmärkidel kasutage funktsiooni KUUPÄEVAVORMING(). Süntaks: DATE_FORMAT(kuupäev, vorming), kus" kuupäeva" - kuupäeva string ja " vormingus" - vorming, millesse teisendatakse " kuupäeva". Erinevalt funktsioonist STR_TO_DATE() näitame ise soovitud väljundvormingut, kuid kuupäev tuleb määrata ISO-vormingus, st "AAAA-KK-PP HH:MM:SS". Kontrollime:

SELECT DATE_FORMAT("2014-12-31", "%d.%m.%Y"); // 31.12.2014 SELECT DATE_FORMAT("2014-12-31", "%d %M %Y"); // 31. detsember 2014

Kui me suhtleksime teiega reaalajas, siis sel hetkel järgneks tõenäoliselt kohe küsimus: " Kuidas aga kuu kuvada teises keeles: ukraina, vene või hiina, lõppude lõpuks?"See on väga lihtne – määrake vajalik lokaat. Seda saab teha kas MySQL-i konfiguratsioonifailis (my.cnf) või lihtsalt PHP-lt päringuga, pärast andmebaasiga ühenduse loomist ja enne põhipäringuid:

SET lc_time_names = ru_RU; SELECT DATE_FORMAT("2014-12-31", "%d %M %Y"); // tulemus: 31. detsember 2014 // soovi korral võib lisada ka "g." või "year" SELECT DATE_FORMAT("2014-12-31", "%d %M %Y year"); // tulemus: 31. detsember 2014

Ilu! ;) Ja veel paar näidet palvetest, mida samuti tihti vaja läheb, aga algajates segadust tekitavad.

// Vali praeguse päeva kirjed SELECT * FROM `tabeli_nimi` WHERE `kuupäeva_väli` >= CURDATE(); // Kõik eilsed kirjed SELECT * FROM `tabeli_nimi` WHERE `kuupäeva_väli` >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND `kuupäeva_väli` NOW() - INTERVALL 30 DAY; // Valige kõik jooksva aasta konkreetse kuu kohta (näiteks maikuu) SELECT * FROM `tabeli_nimi` WHERE YEAR(`kuupäeva_väli`) = YEAR(NOW()) AND MONTH(`kuupäeva_väli`) = 5 ; // või maikuu kohta, kuid 2009. aastal SELECT * FROM `tabeli_nimi` WHERE YEAR(`kuupäeva_väli`) = 2009 AND MONTH(`kuupäeva_väli`) = 5;

Ma ei näe mõtet näidetes kasutatud MySQL-i funktsioone üksikasjalikult kirjeldada, sest... need on intuitiivsed ja vähemalt vähese inglise keele oskusega inimesel ei ole raske mõista, et näiteks funktsioon KUU() tagastab kuupäeva kuu, YEAR()- tema aasta ja PÄEV() (või sünonüüm KUU PÄEV()) - päev. Märksõna INTERVAL- kasutatakse aritmeetilisi tehteid kuupäevade ja nende muutuste kohta.

VALI "2014-07-07 23:59:59" + INTERVALL 1 SEKUND; // tulemus: 2014-07-08 00:00:00 VALI "2014-07-07 23:59:59" + INTERVALL 1 PÄEV; // tulemus: 2014-07-08 23:59:59 // sama asi. kuid kasutades funktsiooni DATE_ADD() SELECT DATE_ADD("2014-07-07 23:59:59", INTERVAL 1 DAY); // 2014-07-08 23:59:59 // Kui peate liitmise asemel lahutama SELECT DATE_SUB("2014-07-07 23:59:59", INTERVAL 1 DAY); // 2014-07-06 23:59:59 // või lihtsalt VALI "2014-07-07 23:59:59" - INTERVALL 1 PÄEV; // 2014-07-06 23:59:59

Need ei ole kõik kuupäevadega töötamise funktsioonid ja soovitaksin teil need ametlikul veebisaidil informatiivsel eesmärgil läbi vaadata, et mittestandardse olukorra ilmnemisel nende olemasolust teada saada. Kuid ma tahan loota, et isegi selline väike ülevaade MySQL-i funktsioonidest kuupäevadega töötamiseks selles artiklis aitab teil olukorras navigeerida ja teha õige otsuse. Kui raskused siiski ilmnevad, esitage küsimusi selles teemas või jaotises "Teie küsimus". Koos saame selle välja ;)