Kazi za Mysql za kufanya kazi na tarehe na wakati. Aina za data za kalenda katika MySQL: vipengele vya matumizi


uchapishaji wa makala hii inaruhusiwa tu na kiungo kwa tovuti ya mwandishi wa makala

Kama unavyojua, tarehe zote zimehifadhiwa katika mysql kwa mpangilio wa siku ya mwaka wa nyuma (2008-10-18), wakati mwingine hata bila kitenganishi (20081018).
Ili kuonyesha tarehe, unahitaji kuibadilisha kuwa fomu ya kawaida inayosomeka.

Kuna njia mbili za uongofu, ufanisi na sio ufanisi sana.
Njia isiyofaa ni wakati tarehe ya pato kutoka kwa mysql inabadilishwa kwa kutumia php.
Binafsi nilifanya hivi mwenyewe kwa muda mrefu sana. Kabla ya kuonyesha, nilibadilisha kila tarehe kwa kutumia kazi ya php.
Ikiwa idadi ya mabadiliko sio kubwa, basi unaweza kubadilisha tarehe kwa kutumia PHP, hakuna kitu kibaya na hiyo, lakini ikiwa unahitaji kutoa makumi au mamia ya maelfu ya rekodi na kubadilisha tarehe katika kila moja, basi bila shaka kubadilisha. tarehe kutumia mysql itakuwa haraka sana.

Mysql ina kazi nzuri ya DATE_FORMAT() , inafanana sana na php date() kazi.
Hapa kuna mfano wa matumizi

CHAGUA DATE_FORMAT("2008-11-19","%d.%m.%Y");
matokeo

Kila kitu ni rahisi sana na haraka, hakuna haja ya kubadilisha tarehe kwa kutumia php.
Hapa kuna orodha ya ufafanuzi wa chaguo hili la kukokotoa

Kuamua Maelezo
%M Jina la mwezi (Januari...Desemba)
%W Jina la siku ya juma (Jumapili...Jumamosi)
%D Siku ya mwezi yenye kiambishi tamati cha Kiingereza (0, 1, 2, 3, nk.)
%Y Mwaka, tarehe, tarakimu 4
%y Mwaka, tarehe, tarakimu 2
%X Mwaka kwa wiki ambapo Jumapili inachukuliwa kuwa siku ya kwanza ya juma, nambari, tarakimu 4, inayotumiwa na "%V"
%x Mwaka kwa wiki ambapo Jumapili inachukuliwa kuwa siku ya kwanza ya juma, nambari, tarakimu 4, inayotumiwa na "%v"
%a Jina fupi la siku ya juma (Jua...Sat)
%d Siku ya mwezi, nambari (00..31)
%e Siku ya mwezi, nambari (0..31)
%m Mwezi, siku (00..12)
%c Mwezi, tarehe (0..12)
%b Jina la mwezi kwa kifupi (Jan...Des)
%j Siku ya mwaka (001..366)
%H Saa (00..23)
%k Saa (0..23)
%h Saa (01..12)
%I Saa (01..12)
%l Saa (1..12)
%i Dakika, nambari (00..59)
%r Muda, umbizo la saa 12 (hh:mm:ss M)
%T Saa, umbizo la saa 24 (hh:mm:ss)
%S Sekunde (00..59)
%s Sekunde (00..59)
%p AM au PM
%w Siku ya juma (0=Jumapili..6=Jumamosi)
%U Wiki (00..53), ambapo Jumapili inachukuliwa kuwa siku ya kwanza ya juma
%u Wiki (00..53), ambapo Jumatatu inachukuliwa kuwa siku ya kwanza ya juma
%V Wiki (01..53), ambapo Jumapili inachukuliwa kuwa siku ya kwanza ya juma. Inatumika na `%X"
%v Wiki (01..53), ambapo Jumatatu inachukuliwa kuwa siku ya kwanza ya juma. Inatumika na `%x"
%% halisi `%".

Maoni

27.11.2008 ----
Haya shetani!!!
Mimi mwenyewe nimekuwa nikifanya kazi kwenye php na mysql kwa miaka mitano, na wakati wote nilikuwa nikibadilisha tarehe katika php ...
Haikutokea hata kwangu kuwa itakuwa rahisi kutumia kazi ya mysql iliyojengwa

11/28/2008 Zheka
Vivyo hivyo! Nimekuwa nikitumia kazi yangu ya php kila wakati

12/03/2008 Sergey
Kweli, kwa ujumla, kuna mtu yeyote hata hutumia njia hii?
Au kila mtu hutumia php kubadili tarehe?
Binafsi sijawahi kubadilisha tarehe katika mysql, bado ninafanya kila kitu kwenye php

06/28/2009 Ilya
Kwa bahati mbaya, hakuna kilichofanya kazi :(

07/08/2009 Vitaly
Safi, asante kwa kipengele. Nashangaa kama kuna squiggles nyingine yoyote?

07/14/2009 DSaint
Asante, imesaidia sana. Kilichobaki ni kuonyesha jina la mwezi kwa Kirusi)

07/28/2009 Vlad
mysql=>PHP
chagua unix_timestamp(start_date) kama start_date_php
msimbo wa php
date("d.m.Y",$row["start_date_php"])

PHP=>MySQL
sasisho la jedwali limewekwa start_date=DATE_FORMAT(STR_TO_DATE("12/19/2009 6:35:22 PM","%d.%m.%Y %H:%i"),"%Y.%m.%d % H:% mimi")

08/18/2009 Mgeni
2:DSaint
Kuna kazi nzuri kama hii:
ELT(MWEZI("2004-04-10"), "Jan.","Feb.","Machi","Apr.","Mei","Juni","Julai", "Ago."," Septemba.","Okt.","Nov.","Desemba.")

Itumie. :-)

10/29/2009 Vladimir
Asante, kuhusu ELT(MONTH("2004-04-10"), "Jan.","Feb.","Machi","Apr.","Mei","Juni","Julai",Agosti .","Sep.","Okt.","Nov.","Desemba.")
sijasikia.

10/07/2010 Evgeniy
Ni nini kinachofanya kazi haraka? Ubadilishaji katika ombi, au kama matokeo ya kazi ya PHP?

10/07/2010 beki
Kwa uchache, kuna kumbukumbu kidogo ya kuchakata, simu chache za utendakazi, mgao mdogo wa kumbukumbu... Ninatumia kitu kama hiki wakati wote, lakini si kwa mysql, lakini katika postgresql.

10/08/2010 Msimamizi
Evgeniy, mlinzi alisema kwa usahihi kwamba mabadiliko haya yanapaswa kufanya kazi kwa uzuri zaidi kupitia hifadhidata, lakini kwa kweli, ikiwa tunazungumza juu ya kutoa idadi kubwa ya data.
Ikiwa unavuta rekodi 10-20, basi hakuna tofauti jinsi ya kubadilisha tarehe; ikilinganishwa na mizigo mingine, hii ni ndogo.

01/27/2011 pcemma
uhh asante kwa afftor (: hakuna haja tena ya kutumia kazi yangu nzuri ya mega kwa ubadilishaji (:

04/13/2011 Xes
JINSI YA KUITUMIA KATIKA PHP
wakati ($sqlr=mysql_fetch_array($sql))
{
echo ($sqlr["comadd"]." ".$sqlr["comment"]."

");

$sqlr["comadd"] - Je, unahitaji kuiwasilisha katika hali ya kawaida?
}

04/14/2011 Vitaly
Nina tarehe katika hifadhidata katika umbizo la 11/19/2008, aina ya jedwali VARCHAR, ninawezaje kuiandika tena kwenye hifadhidata katika umbizo la 2008-11-19?
Mikono kwa muda mrefu sana ...
Asante.

04/15/2011 admin
Xes ni kazi ya MySQL, unahitaji kuitumia katika hoja ya sql, ambayo, kwa kuzingatia msimbo wako, iko mahali fulani hapo juu. Haiwezi kutumika katika sehemu hii ya msimbo.

04/15/2011 admin
Vitaly, badilisha tu aina ya seli hadi DATE, mysql itabadilisha kiotomati data zote kwenye seli hii hadi umbizo la 2008-11-19.
Lakini ikiwa tu, kabla ya kubadilisha aina ya seli, fanya utupaji wa meza hii, kwa sababu ghafla database itafanya kitu kibaya na meza itavunjika kabisa.

Ikiwa ni muhimu kwako kuacha aina ya uga kama varchar, basi baada ya kuweka aina ya DATE, irejeshe kwa varchar...

Hii ndiyo chaguo rahisi zaidi, lakini si sahihi kabisa, lakini niliangalia inafanya kazi.

05/14/2011 DDD
date("d-m-Y",strtotime("$myrow"));

05/24/2011 Konstantin
na mimi huchukua SELECT *,UNIX_TIMESTAMP(iliyoundwa) AS imeundwa KUTOKA...
Lakini kwa motor naweza kuifanya kwa muundo wowote. Hata siku tu, hata muda tu...
na kulinganisha ambayo ni kubwa kuliko 05/14/2011 au 05/14/2010...
Na ninaandika kama hii:
...date=".gmdate("Y-m-d H:i:s",$created)...
na kwa ujumla sioni sababu ya kubadili tabia

05/24/2011 Sergey
Konstantin, mimi mwenyewe hutumia php date() kwa pato, lakini hapa tunazingatia chaguo la kubadilisha tarehe sio kupitia php, lakini kupitia mysql.

Ningesema kwamba huu ni muhtasari tu wa kazi ya mysql na hakika ina haki ya kuwepo ...

Vipengele hivi pia vimeundwa kufanya kazi na aina za data za kalenda. Hebu tuangalie kwa karibu zaidi.

  • DATE_FORMAT(tarehe, umbizo) hupanga tarehe kulingana na umbizo lililochaguliwa. Kazi hii hutumiwa mara nyingi sana. Kwa mfano, katika MySQL umbizo la tarehe ni YYYY-MM-DD (mwaka-mwezi-siku), huku tukifahamu zaidi umbizo la DD-MM-YYYY (tarehe-mwaka). Kwa hivyo, ili kuonyesha tarehe kama kawaida, inahitaji kubadilishwa. Wacha kwanza tutoe swali, na kisha tujue jinsi ya kuweka umbizo:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%d.%m.%Y");

    Sasa tarehe inaonekana tunaijua. Ili kutaja muundo wa tarehe, wahitimu maalum hutumiwa. Kwa urahisi, tunaorodhesha kwenye meza.

    Imeahirishwa Maelezo
    %a Jina fupi la siku ya juma (Jumatatu - Jumatatu, Jumanne - Jumanne, Jumatano - Jumatano, Alhamisi, Ijumaa - Ijumaa, Sat - Jumamosi, Jua - Jumapili).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%a");

    Matokeo:

    %b Jina fupi la miezi (Jan - Januari, Feb - Februari, Machi - Machi, Apr - Aprili, Mei - Mei, Juni - Juni, Julai - Julai, Agosti - Agosti, Sep - Septemba, Okt - Oktoba, Nov - Novemba, Desemba - Desemba).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%b");

    Matokeo:

    %c Mwezi katika fomu ya nambari (1 - 12).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%s");

    Matokeo:

    %d Siku ya mwezi katika fomu ya nambari na sifuri (01 - 31).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%d");

    Matokeo:

    %D Siku ya mwezi kwa Kiingereza (1, 2...).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%D");

    Matokeo:

    %e Siku ya mwezi kwa fomu ya nambari bila sifuri (1 - 31).

    Mfano:

    CHAGUA TAREHE_FORMAT(MAREHEMU(), "%e");

    Matokeo:

    %H Saa zenye sifuri inayoongoza kutoka 00 hadi 23.

    Mfano:

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

    Matokeo:

    %h Saa yenye sifuri inayoongoza kutoka 00 hadi 12.

    Mfano:

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

    Matokeo:

    %i Dakika kutoka 00 hadi 59.

    Mfano:

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

    Matokeo:

    %j Siku ya mwaka kutoka 001 hadi 366.

    Mfano:

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

    Matokeo:

    %k Saa yenye sifuri inayoongoza kutoka 0 hadi 23.

    Mfano:

    CHAGUA TAREHE_FORMAT("2011-12-31 01:03:20", "%k");

    Matokeo:

    %l Saa bila sifuri inayoongoza kutoka 1 hadi 12.

    Mfano:

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

    Matokeo:

    %M

    Mfano:

    Matokeo:

    %M Jina la mwezi bila kifupi.

    Mfano:

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

    Matokeo:

    %m Mwezi katika fomu ya nambari na sifuri inayoongoza (01 - 12).

    Mfano:

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

    Matokeo:

    %p AM au PM kwa umbizo la saa 12.

    Mfano:

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

    Matokeo:

    %r Muda katika umbizo la saa 12.

    Mfano:

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

    Matokeo:

    %s Sekunde kutoka 00 hadi 59.

    Mfano:

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

    Matokeo:

    %T Muda katika umbizo la saa 24.

    Mfano:

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

    Matokeo:

    %u Wiki (00 - 52), ambapo siku ya kwanza ya juma ni Jumatatu.

    Mfano:

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

    Matokeo:

    %U Wiki (00 - 52), ambapo siku ya kwanza ya juma ni Jumapili.

    Mfano:

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

    Matokeo:

    %W Jina la siku ya juma bila kifupi.

    Mfano:

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

    Matokeo:

    %w Idadi ya siku ya juma (0 - Jumapili, 6 - Jumamosi).

    Mfano:

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

    Matokeo:

    %Y Mwaka, makundi 4.

    Mfano:

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

    Matokeo:

    %y Mwaka, aina 2.

    Mfano:

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

    Matokeo:


  • STR_TO_DATE(tarehe, umbizo) ni chaguo za kukokotoa kinyume cha ile iliyotangulia, inachukua tarehe katika umbizo na kurudisha tarehe katika umbizo la MySQL.

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



  • Chaguo za kukokotoa za TIME_FORMAT(muda, umbizo) ni sawa na DATE_FORMAT(), lakini hutumika kwa muda tu:

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



  • Chaguo za kukokotoa za GET_FORMAT(tarehe, umbizo) hurejesha mfuatano wa umbizo unaolingana na mojawapo ya umbizo la wakati tano:

    EUR - kiwango cha Ulaya
    USA - kiwango cha Amerika
    JIS - Kiwango cha Viwanda cha Kijapani
    ISO - Kiwango cha ISO (Shirika la Viwango vya Kimataifa)
    NDANI - kiwango cha kimataifa

    Chaguo hili la kukokotoa ni vizuri kutumia pamoja na la awali - DATE_FORMAT(). Hebu tuangalie mfano:

    CHAGUA GET_FORMAT(TAREHE, "EUR"), DATE_FORMAT("2011-04-17", GET_FORMAT(TAREHE, "EUR"));


    Kama unavyoona, chaguo la kukokotoa la GET_FORMAT() lenyewe hurejesha umbizo la uwasilishaji, na pamoja na kitendakazi cha DATE_FORMAT() hutoa tarehe katika umbizo linalohitajika. Uliza maswali yako mwenyewe na viwango vyote vitano na uone tofauti.

Kweli, sasa unajua karibu kila kitu kuhusu kufanya kazi na tarehe na nyakati katika MySQL. Hii itakuwa muhimu sana kwako wakati wa kuunda programu mbali mbali za wavuti. Kwa mfano, ikiwa mtumiaji ataingiza tarehe katika fomu kwenye tovuti katika muundo unaojulikana kwake, haitakuwa vigumu kwako kutumia kazi muhimu ili tarehe inaonekana kwenye hifadhidata katika muundo unaohitajika.

Thamani katika miundo hii:

    Kama mfuatano katika umbizo "YYYY-MM-DD" au "YY-MM-DD" . Sintaksia tulivu inaruhusiwa: herufi yoyote ya uakifishaji inaweza kutumika kama kitenganishi kati ya sehemu za tarehe. Kwa mfano, "2012-12-31" , "2012/12/31" , "2012^12^31" na "2012@12@31" ni sawa.

    Kama mfuatano usio na vikomo katika umbizo la "YYYYMMDD" au "YYMMDD" mradi tu mfuatano huo unaeleweka kama tarehe. Kwa mfano, "20070523" na "070523" zinatafsiriwa kama "2007-05-23", lakini "071332" ni kinyume cha sheria (ina sehemu za mwezi na siku zisizo na maana) na inakuwa "0000-00-00".

    Kama nambari katika umbizo la YYYYMMDD au YYMMDD , mradi tu nambari inaeleweka kama tarehe. Kwa mfano, 19830905 na 830905 zinafasiriwa kama "1983-09-05" .

Kwa hivyo, mfuatano "08/25/2012" sio tarehe halisi ya MySQL. Una chaguzi nne (katika mpangilio usio wazi wa upendeleo, bila habari zaidi kuhusu mahitaji yako):

    Sanidi Kichagua Date ili kutoa tarehe katika umbizo linalotumika kwa kutumia altField pamoja na altFormat :

    $("selector").datepicker(( altField: "#Tarehehalisi" altFormat: "yyyy-mm-dd"));

    Au, ikiwa unafurahi kwamba watumiaji wanaona tarehe katika umbizo la YYYY-MM-DD, badala yake weka parameta ya dateFormat:

    $("kiteuzi").kichagua tarehe(( dateFormat: "yyyy-mm-dd"));

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

    na kisha ama:

      pata kamba iliyoumbizwa inayofaa:

      $date = $dt->umbizo("Y-m-d");

      pata muhuri wa wakati wa UNIX:

      $timestamp = $dt->getTimestamp();

      ambayo hupitishwa moja kwa moja kwa MySQL FROM_UNIXTIME() :

      WEKA KWENYE tarehe_ya mtumiaji VALUES ("", "$name", FROM_UNIXTIME($timestamp))

  • Ingiza mfuatano wewe mwenyewe katika neno halisi halali:

    $parts = kulipuka("/", $_POST["tarehe"]); $date = "$parts-$parts-$parts";

Onyo

    Nambari yako inaweza kuathiriwa na sindano ya SQL. Unapaswa kutumia taarifa zilizotayarishwa, ambapo unapitisha vigeu vyako kama vigezo, ambavyo havijatathminiwa kwa SQL. Ikiwa hujui ninachozungumzia, au jinsi ya kukirekebisha, soma hadithi ya Meza ya Bobby.

  • Aina ya DATE inatumika kwa thamani zilizo na sehemu ya tarehe lakini hakuna sehemu ya saa. MySQL hupata na kuonyesha thamani za DATE katika umbizo la "YYYY-MM-DD". Masafa yanayotumika ni kutoka "1000-01-01" hadi "9999-12-31".

    Aina ya Tarehe ya Muda inatumika kwa thamani zilizo na tarehe na wakati. MySQL hurejesha na kuonyesha thamani za DateTime katika umbizo "YYYY-MM-DD HH:MM:SS" . Masafa yanayotumika ni kuanzia "1000-01-01 00:00:00" hadi "9999-12-31 23:59:59" .

Kwa hivyo, aina zote za data za kalenda zimeelezewa kwa undani katika sehemu "10.3. Aina za Tarehe na Wakati » Mafunzo ya MySQL. Taarifa muhimu kuhusu usaidizi wa DBMS kwa maeneo ya saa imeelezwa katika sehemu ya “9.7. Msaada wa Eneo la Wakati wa Seva ya MySQL". Kila kitu kinachofuata kinategemea kusoma mwongozo. Wakati huo huo, nuances tu ya kuchagua kwa neema ya aina moja au nyingine imeonyeshwa hapa, kwa hivyo nyenzo hii haibadilishi mwongozo kwa njia yoyote, lakini inakamilisha.

Kwanza, maelezo mafupi ya kila aina:

  • TIMESTAMP - aina ya data ya kuhifadhi tarehe na wakati. Data huhifadhiwa kama idadi ya sekunde ambazo zimepita tangu mwanzo wa "Enzi ya Unix". Kiwango cha thamani: 1970-01-01 00:00:00 - 2038-12-31 00:00:00. Inachukua baiti 4.
  • YEAR - aina ya data ya kuhifadhi mwaka. Kiwango cha thamani: 1901 - 2155. Inachukua baiti 1.
  • DATE ni aina ya data ya tarehe za kuhifadhi. Kiwango cha thamani: 1000-01-01 - 9999-12-31. Inachukua baiti 3.
  • TIME ni aina ya data ya kuhifadhi wakati. Kiwango cha thamani: −828:59:59 - 828:59:59. Inachukua baiti 3.
  • DATETIME ni aina ya data ya kuhifadhi tarehe na saa. Kiwango cha thamani: 1000-01-01 00:00:00 - 9999-12-31 00:00:00. Inachukua baiti 8.
Kumbuka kwa mhudumu. Jambo la kufurahisha ni kwamba waandaaji wengi wa programu wanaamini kuwa wazo la "muhuri wa wakati" ni wakati wa Unix. Kwa hakika, muhuri wa muda ni alama ambayo ni mfuatano wa vibambo vinavyoonyesha tarehe na/au wakati tukio fulani lilitokea. Na "Saa moja" (saa Unix) au wakati wa POSIX ni idadi ya sekunde ambazo zimepita tangu usiku wa manane Januari 1, 1970 UTC. Wazo la muhuri wa muda ni pana kuliko wakati wa Unix.

Baada ya kuchambua maelezo ya aina zilizowasilishwa hapo juu, unaweza kuteka karibu hitimisho zote kuhusu faida na hasara za aina fulani. Kila kitu ni rahisi na dhahiri.

Lakini kabla ya kuzungumza juu ya matumizi ya aina hizi, nataka kutambua kwamba katika mazoezi, aina nyingine hutumiwa mara nyingi kuhifadhi tarehe na wakati: thamani kamili (kwa ajili ya kuhifadhi tarehe - INT (4 bytes), tarehe na wakati - BIGINT (8). baiti)). Tofauti pekee kati ya kutumia aina kamili na DATE na DATETIME ni kwamba data haijaumbizwa wakati wa kutoa, na katika hesabu zenye tarehe na saa, nambari kamili lazima zibadilishwe hadi aina inayofaa ya kalenda. Kwa kuongeza, hakuna hundi ya uhalali wa thamani iliyowasilishwa kabla ya kuhifadhi. Uwezo wa kupanga huhifadhiwa. Kwa hivyo, inaleta maana kutumia INT na BIGINT katika hali sawa na DATE na DATETIME, ili kuongeza uwezo wa kubebeka na uhuru kutoka kwa DBMS. Sioni faida zingine zozote; ikiwa zipo, ninapendekeza uwaonyeshe kwenye maoni.

Kutumia aina za data za kalenda katika MySQL

Hebu tuanze na rahisi zaidi - aina MWAKA. Faida yake pekee ni ukubwa wake mdogo - tu 1 byte. Lakini kwa sababu ya hii, kuna kizuizi kali juu ya anuwai ya maadili halali (aina inaweza tu kuhifadhi maadili 255 tofauti). Nina wakati mgumu kufikiria hali ya vitendo ambapo mtu anaweza kutaka kuhifadhi miaka madhubuti katika safu kutoka 1901 hadi 2155. Zaidi ya hayo, aina ya SMALLINT (2 byte) inatoa mbalimbali ambayo inatosha katika hali nyingi kuhifadhi mwaka. Na kuhifadhi byte 1 kwa kila safu katika jedwali la hifadhidata haina maana katika wakati wetu.

Aina TAREHE Na DATETIME inaweza kuunganishwa katika kundi moja. Huhifadhi tarehe au tarehe na wakati na anuwai pana ya thamani halali, bila ukanda wa saa uliowekwa kwenye seva. Matumizi yao hakika yana maana ya vitendo. Lakini ikiwa ungependa kuhifadhi tarehe za matukio ya kihistoria kurudi nyuma zaidi ya Enzi ya Kawaida, itabidi uchague aina nyingine za data. Aina hizi ni bora kwa kuhifadhi tarehe za matukio fulani ambayo yanaweza kuwa nje ya aina ya TIMESTAMP (siku za kuzaliwa, tarehe za kutolewa kwa bidhaa, uchaguzi wa rais, kurushwa kwa roketi, n.k.). Unapotumia aina hizi, unahitaji kuzingatia nuance moja muhimu, lakini zaidi juu ya hapo chini.

Aina MUDA inaweza kutumika kuhifadhi muda ambapo usahihi chini ya sekunde 1 hauhitajiki, na muda wa chini ya masaa 829. Hakuna cha kuongeza hapa.

Aina ya kuvutia zaidi inabaki - TIMESTAMP. Inapaswa kuzingatiwa kwa kulinganisha na DATE na DATETIME: TIMESTAMP pia imeundwa kuhifadhi tarehe na/au wakati wa kutokea kwa matukio fulani. Tofauti muhimu kati yao iko katika safu za maadili: ni wazi, TIMESTAMP haifai kwa kuhifadhi matukio ya kihistoria (hata kama siku za kuzaliwa), lakini ni bora kwa kuhifadhi za sasa (ukataji wa miti, tarehe za kuchapisha nakala, kuongeza bidhaa, kuweka maagizo) na yajayo katika matukio yajayo yanayoweza kuonekana (matoleo ya toleo jipya, kalenda na vipanga ratiba, n.k.).

Urahisi kuu wa kutumia aina ya TIMESTAMP ni kwamba kwa safu wima za aina hii kwenye jedwali unaweza kuweka thamani ya chaguo-msingi kwa njia ya uingizwaji wa wakati wa sasa, na pia kuweka wakati wa sasa wakati wa kusasisha rekodi. Ikiwa unahitaji vipengele hivi, basi kuna uwezekano wa 99% kuwa TIMESTAMP ndiyo hasa unayohitaji. (Angalia mwongozo wa jinsi ya kufanya hivyo.)

Usiogope kuwa programu yako itaacha kufanya kazi tunapokaribia 2038. Kwanza, kabla ya wakati huu, programu yako itasitishwa tu kutumiwa (haswa matoleo ambayo yanaandikwa sasa). Pili, tarehe hii inapokaribia, watengenezaji wa MySQL hakika watakuja na kitu cha kuhifadhi utendakazi wa programu yako. Kila kitu kitatatuliwa pamoja na tatizo la Y2K.

Kwa hivyo, tunatumia aina ya TIMESTAMP kuhifadhi tarehe na nyakati za matukio ya wakati wetu, na TAREHE na TAREHE ili kuhifadhi tarehe na nyakati za matukio ya kihistoria, au matukio ya wakati ujao wa kina.

Masafa ya thamani ni tofauti muhimu kati ya aina za TIMESTAMP, DATETIME na DATE, lakini sio tofauti kuu. Kuu kwamba TIMESTAMP huhifadhi thamani katika UTC. Wakati wa kuhifadhi thamani, inatafsiriwa kutoka eneo la wakati wa sasa hadi UTC, na wakati wa kuisoma, inatafsiriwa kutoka kwa eneo la wakati wa sasa kutoka kwa UTC. DATETIME na DATE huhifadhi na kuonyesha kila mara kwa wakati mmoja, bila kujali saa za eneo.

Saa za maeneo zimewekwa duniani kote katika MySQL DBMS au kwa muunganisho wa sasa Mwisho unaweza kutumika kuhakikisha kazi ya watumiaji tofauti katika maeneo tofauti ya saa katika kiwango cha DBMS. Maadili ya wakati wote yatahifadhiwa kimwili katika UTC, na kupokea kutoka kwa mteja na kupewa mteja - katika maadili ya eneo lake la saa. Lakini tu wakati wa kutumia aina ya data ya TIMESTAMP. DATE na DATETIME hupokea, kuhifadhi na kurejesha thamani sawa kila wakati.

Kazi ya NOW() na visawe vyake hurejesha thamani ya saa katika saa za eneo la sasa la mtumiaji.

Kwa kuzingatia hali hizi zote, lazima uwe mwangalifu sana unapobadilisha saa za eneo ndani ya muunganisho wa seva na kutumia aina za DATE na DATETIME. Ikiwa unahitaji kuhifadhi tarehe (kwa mfano, tarehe ya kuzaliwa), basi hakutakuwa na matatizo. Tarehe ya kuzaliwa ni sawa katika eneo lolote. Wale. ikiwa ulizaliwa Januari 1 saa 0:00 UTC/GMT+0, basi hii Sivyo inamaanisha kuwa huko Amerika watasherehekea siku yako ya kuzaliwa mnamo Desemba 31. Lakini ikiwa unaamua kuhifadhi wakati matukio katika safu wima ya DATETIME, basi haitawezekana kufanya kazi na saa za eneo la mtumiaji katika kiwango cha DBMS. Acha nieleze kwa mfano:

Mtumiaji X anafanya kazi katika eneo la UTC/GMT+2, Y - katika eneo la UTC/GMT+3. Kwa miunganisho ya watumiaji kwa MySQL, eneo la wakati linalolingana (kila moja lina yake) imewekwa. Mtumiaji huchapisha ujumbe kwenye jukwaa, tunavutiwa na tarehe ambayo ujumbe huo uliandikwa.

Chaguo la 1: DATETIME. Mtumiaji X anaandika ujumbe saa 14:00 UTC/GMT+2. Thamani katika sehemu ya "tarehe" ya ujumbe inabadilishwa kama tokeo la kutekeleza kazi ya NOW() - 14:00. Mtumiaji Y anasoma saa ambayo ujumbe uliandikwa na anaona saa 14:00 sawa. Lakini mipangilio yake imewekwa kwa UTC/GMT+3, na anafikiri kwamba ujumbe huo uliandikwa si sasa hivi, lakini saa moja iliyopita.

Chaguo la 2: TIMESTAMP. Mtumiaji X anaandika ujumbe saa 14:00 UTC/GMT+2. Sehemu ya "tarehe" ina matokeo ya kutekeleza kazi ya NOW() - katika kesi hii - 12:00 UTC/GMT+0. UserY husoma saa ambayo ujumbe uliandikwa na kupokea (UTC/GMT+3)(12:00 UTC/GMT+0) = 15:00 UTC/GMT+3. Kila kitu kinageuka jinsi tunavyotaka. Na muhimu zaidi, ni rahisi sana kutumia: kusaidia maeneo ya saa maalum, hauitaji kuandika msimbo wowote wa ubadilishaji wa wakati.

Uwezekano wa kubadilisha muda wa sasa na kufanya kazi na saa za kanda katika aina ya TIMESTAMP ni nguvu sana hivi kwamba ikiwa unahitaji kuhifadhi tarehe bila wakati kwenye logi fulani, bado unapaswa kutumia TIMESTAMP badala ya DATE, bila kuhifadhi baiti 1 ya tofauti hiyo. kati yao. Katika kesi hii, tu kupuuza "00:00:00".

Ikiwa huwezi kutumia TIMESTAMP kwa sababu ya anuwai ndogo ya maadili yake (kawaida kesi 1-2 dhidi ya 10-15 kwenye hifadhidata ya tovuti), itabidi utumie DATETIME na urekebishe kwa uangalifu maadili yake katika sehemu zinazofaa ( i.e. unapoandika katika uwanja huu, badilisha tarehe kuwa UTC, na wakati wa kusoma - hadi wakati katika eneo la mtumiaji anayesoma). Ikiwa utahifadhi tarehe tu, basi uwezekano mkubwa haujalishi ni eneo gani la wakati unao: kila mtu anaadhimisha Mwaka Mpya Januari 1, wakati wa ndani, kwa hivyo huna haja ya kutafsiri chochote hapa.

Kuanza, nataka kugusa juu ya mada ya muundo gani ni bora kuhifadhi tarehe kwenye hifadhidata: TIMESTAMP au DATETIME. Swali hili limekuwa na linaulizwa mara nyingi kwenye vikao, blogi, nk. Lakini ili si kutuma mara moja kwa injini za utafutaji, nitajaribu kuonyesha tofauti kwa maneno rahisi na kwa mfano. Aina DATETIME- huhifadhi thamani ya tarehe katika umbizo "YYYY-MM-DD HH:MM:SS" na haitegemei saa za eneo. TIMESTAMP- huhifadhi muhuri wa muda, i.e. idadi ya sekunde ambazo zimepita tangu Januari 1, 1970. MySQL inabadilisha maadili haya kwa kuzingatia eneo la wakati wa sasa wakati wa kuandika kwenye hifadhidata na wakati wa kutoa kutoka kwayo. Hii ina maana gani...
Kwa mfano, umeongeza tu makala kwenye hifadhidata, kwenye kalenda yako ni ya kwanza ya Januari 2014, na kwenye saa yako ni 01:00. Ikiwa sehemu ya tarehe ni ya aina ya DATETIME, basi kila mtu anayetembelea tovuti ataona tarehe na saa hii haswa, bila kujali mahali anapoishi. Kila kitu kinaonekana kuwa sawa, lakini mtumiaji ( tumuite "Bill G"), wanaoishi mahali fulani huko New York, Januari ya kwanza bado haijafika - kwake ni Desemba 31, 2013 na saa inaonyesha 19:00. Anachanganyikiwa kidogo, kwa sababu ... Bado hajaanza kusherehekea Mwaka Mpya, lakini tayari anafikiria "makala kutoka siku zijazo";) Hii haitatokea kwa aina ya TIMESTAMP, kwa sababu. Wakati wa kutoa, eneo la wakati wake litazingatiwa.
"Kila kitu kiko wazi!", Unasema na ubadilishe kwa haraka sehemu zote za tarehe kuwa aina ya TIMESTAMP, na Bill G atapumua, lakini si kwa muda mrefu. Wakati wa kujiandikisha kwenye tovuti yako, Bill alionyesha tarehe na wakati wa kuzaliwa kwake. Kusafiri duniani kote, yeye hutazama tovuti yako daima na kugundua kwa hofu kwamba wakati, na wakati mwingine tarehe ya kuzaliwa kwake, daima ni tofauti, kwa sababu ... zinaonyeshwa kwa kuzingatia eneo la saa ambalo yuko kwa sasa. Ndiyo, katika kesi hii, aina ya TIMESTAMP ilicheza utani wa kikatili.
Tunahitimisha kuwa kwa kazi fulani, unahitaji kuchagua aina inayofaa ya shamba au kudhibiti kurekodi / pato kulingana na matokeo yaliyohitajika.

Wacha tuendelee kwenye shida maarufu na chaguzi za kuzitatua. Chagua rekodi ndani ya safu maalum ya tarehe, i.e. kwa muda fulani.

CHAGUA * KUTOKA `Jedwali_jina` WAPI `sehemu_ya_tarehe` KATI YA "2014-07-05" NA "2014-07-15" AGIZA KWA `sehemu_ya_tarehe`;

Rekodi zote zitachaguliwa ambapo tarehe katika sehemu ya "date_field" zitakuwa kati ya Julai 5, 2014 hadi Julai 15, 2014, ikijumuisha tarehe zilizobainishwa. Hatupaswi kusahau kwamba kwa tarehe chaguo-msingi katika MySQL huhifadhiwa katika umbizo "YYYY-MM-DD HH:MM:SS" na, ipasavyo, mask ya umbizo ni "%Y-%m-%d %H:%i: %s" (kawaida ISO) Jinsi ya kutatua suala ikiwa tarehe haitoi katika muundo huu? Wacha tutupe chaguzi za PHP na tuone jinsi hii inaweza kufanywa katika ombi lenyewe. Na kwa madhumuni kama haya, tutahitaji kazi STR_TO_DATE(). Sintaksia: STR_TO_DATE(str, umbizo), wapi" str"- kamba ya tarehe na" umbizo" ni umbizo linalolingana nayo. Wacha tujaribu:

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

Matokeo ya utekelezaji ni tarehe katika umbizo ambalo linatumiwa na chaguo-msingi katika MySQL. Hiyo ni, tunahitaji kubainisha sio umbizo ambalo tunataka kupokea tarehe ya kutolewa, lakini umbizo ambalo tunatoa tarehe ya kuchakatwa. Kutumia njia hii, kiingilio chetu hapo juu kinaweza kuonekana kama hii:

CHAGUA * KUTOKA `Jedwali_jina` WAPI `sehemu_ya_tarehe` KATI YA STR_TO_DATE("07/05/2014", "%d.%m.%Y") NA STR_TO_DATE("Julai 15, 2014", "%M %d,%Y ") AGIZA KWA `sehemu_ya_tarehe`;

Kwa kuwa tumegusia suala la umbizo la tarehe, hebu tuangalie jinsi ya kupata tarehe wakati wa kuchukua sampuli katika umbizo tunalohitaji, kwa sababu Watu wengi wamezoea zaidi kuona "12/31/2014" au "Desemba 31, 2014" kuliko "2014-12-31". Kwa madhumuni hayo, tumia kazi DATE_FORMAT(). Sintaksia: DATE_FORMAT(tarehe, umbizo), wapi" tarehe"- kamba ya tarehe na" umbizo" - umbizo la kubadilishwa kuwa " tarehe". Tofauti na STR_TO_DATE() chaguo za kukokotoa, sisi wenyewe tunaonyesha umbizo la towe tunalotaka, lakini tarehe lazima ibainishwe katika umbizo la ISO, yaani "YYYY-MM-DD HH:MM:SS". Tunaangalia:

CHAGUA DATE_FORMAT("2014-12-31", "%d.%m.%Y"); // 12/31/2014 CHAGUA TAREHE_FORMAT("2014-12-31", "%d %M %Y"); // 31 Desemba 2014

Ikiwa tulikuwa tunawasiliana nawe kwa wakati halisi, basi kwa wakati huu, uwezekano mkubwa, swali lingefuata mara moja: " Lakini jinsi ya kuonyesha mwezi kwa lugha nyingine: Kiukreni, Kirusi au Kichina, baada ya yote?"Ni rahisi sana - weka eneo linalohitajika. Na hii inaweza kufanywa ama katika faili ya usanidi ya MySQL (my.cnf), au kwa ombi kutoka kwa PHP, baada ya kuunganishwa kwenye hifadhidata na kabla ya hoja kuu:

SET lc_time_names = ru_RU; CHAGUA DATE_FORMAT("2014-12-31", "%d %M %Y"); // matokeo: Desemba 31, 2014 // ikiwa inataka, unaweza pia kuongeza "g." au "mwaka" CHAGUA DATE_FORMAT("2014-12-31", "%d %M %Y mwaka"); // matokeo: Desemba 31, 2014

Uzuri! ;) Na mifano michache zaidi ya maombi ambayo pia inahitajika mara nyingi, lakini husababisha kuchanganyikiwa kati ya Kompyuta.

// Chagua rekodi za siku ya sasa CHAGUA * KUTOKA `Jedwali_jina` WAPI `tarehe_uwanja` >= TAREHE(); // Rekodi zote za jana CHAGUA * KUTOKA `Jedwali_jina` WAPI `sehemu_ya_tarehe` >= TAREHE_SUB(MAREHEMU(), MUDA SIKU 1) NA `uga_wa_tarehe` SASA() - MUDA WA SIKU 30; // Chagua kila kitu kwa mwezi mahususi wa mwaka wa sasa (kwa mfano, mwezi wa Mei) CHAGUA * KUTOKA `Jedwali_jina` WAPI MWAKA(`tarehe_uwanja`) = MWAKA(SASA()) NA MWEZI(`tarehe_uwanja`) = 5 ; // au kwa mwezi wa Mei, lakini mwaka wa 2009 CHAGUA * KUTOKA `jedwali_jina` WAPI MWAKA(` uwanja_wa_tarehe`) = 2009 NA MWEZI(` uwanja_wa_tarehe`) = 5;

Sioni maana ya kuelezea kwa undani kazi za MySQL zinazotumiwa kwenye mifano, kwa sababu ... ni angavu na kwa mtu aliye na ufahamu mdogo wa Kiingereza haitakuwa ngumu kuelewa kwamba, kwa mfano, kazi hiyo. MWEZI() inarudisha mwezi wa tarehe, MWAKA()- mwaka wake, na SIKU() (au kisawe DAYOFMONTH()) - siku. Neno muhimu KIPINDI- hutumikia shughuli za hesabu kwa tarehe na mabadiliko yao.

CHAGUA "2014-07-07 23:59:59" + MUDA SEKUNDE 1; // matokeo: 2014-07-08 00:00:00 CHAGUA "2014-07-07 23:59:59" + KIPINDI SIKU 1; // matokeo: 2014-07-08 23:59:59 // kitu kimoja. lakini kwa kutumia chaguo la kukokotoa DATE_ADD() CHAGUA DATE_ADD("2014-07-07 23:59:59", INTERVAL SIKU 1); // 2014-07-08 23:59:59 // Iwapo unahitaji kutoa badala ya kuongeza CHAGUA DATE_SUB("2014-07-07 23:59:59", INTERVAL SIKU 1); // 2014-07-06 23:59:59 // au kwa urahisi CHAGUA "2014-07-07 23:59:59" - KIPINDI SIKU 1; // 2014-07-06 23:59:59

Hizi sio kazi zote za kufanya kazi na tarehe, na ningekushauri upitie kwa madhumuni ya habari kwenye tovuti rasmi ili kujua kuhusu kuwepo kwao ikiwa hali isiyo ya kawaida hutokea. Lakini nataka kutumaini kwamba hata muhtasari mdogo wa kazi za MySQL za kufanya kazi na tarehe katika makala hii itakusaidia kuzunguka hali hiyo na kufanya uamuzi sahihi. Ikiwa shida bado zinatokea, basi uliza maswali katika mada hii au sehemu ya "Swali lako". Tutaelewa pamoja;)