Datums en tijd - De OOP-weg

De PHP-extensie Datum / tijd is een reeks klassen waarmee u kunt werken met bijna alle aan datum en tijd gerelateerde taken. Het is beschikbaar sinds de release van PHP 5.2 en de extensie heeft verschillende nieuwe klassen geïntroduceerd, die allemaal zijn toegewezen aan scenario's uit het echte leven:

  • Een datum of een tijd wordt weergegeven door a Datum Tijd voorwerp.
  • Een tijdzone van de wereld wordt weergegeven door een DateTimeZone voorwerp.
  • DateInterval objecten vertegenwoordigen een interval. Als we bijvoorbeeld over twee dagen zeggen, is de "twee dagen" het interval. De DateInterval object vertrouwt niet op een specifieke datum of tijd.
  • DatePeriod objecten vertegenwoordigen een periode tussen twee datums.

Laat de laatste twee je nu niet van je afhouden, we zullen het werkelijke gebruik van deze twee in een oogwenk bekijken.


Van datum() naar Datum Tijd

Wanneer we een datum willen weergeven die we hebben gebruikt datum(), het is eenvoudig en het werkt. U hoeft alleen het datumformaat door te geven dat u nodig hebt. Maar het is echt lastig om te manipuleren, een goed voorbeeld is het opmaken van datums en tijden volgens een aangepaste tijdzone.

DateTime doet meer dan alleen een opgemaakte datum retourneren, maar voordat we verder gaan, moet u een nieuwe instellen Datum Tijd object dat uw datum en / of tijd vertegenwoordigt. Dan kunnen we er allerlei leuke dingen mee doen. Een nieuwe instantie is gemaakt net als elke andere PHP-klasse.

$ date = new DateTime ();

De constructor van DateTime accepteert een stringparameter die standaard "now", de huidige tijd en datum is. Als u een object voor een specifieke datum wilt maken, moet u de specifieke datum en tijd daarvoor opgeven. Formatteren voor de parameter is in de meeste gevallen vanzelfsprekend. Hieronder vindt u een paar verschillende voorbeelden van het samenstellen van uw Datum Tijd voorwerp:

new DateTime ('2013, 24 maart') // DateTime vertegenwoordigt 2013, 24 maart nieuwe DateTime ('2013-03-24') // DateTime vertegenwoordigt 2013, 24 maart nieuwe DateTime ('+ 2 dagen') // DateTime vertegenwoordigt 2 dagen vanaf nu. nieuwe DateTime ('morgen')

Wanneer PHP het formaat moeilijk begrijpt, geeft het een uitzondering. Een volledige lijst van de beschikbare opmaak vindt u in de documentatie

Als er geen indeling is die overeenkomt met uw behoeften, kunt u uw eigen indeling opgeven met behulp van DateTime :: createFromFormat

DateTime :: createFromFormat ('j-M-Y', '24 -Mar-2013 ');

Nu we een DateTime-object in de hand hebben, kunnen we heel veel dingen doen, vrij gemakkelijk.

Unix-tijdstempel

$ Date> getTimestamp (); // geeft een unix timestamp

Datum / tijden wijzigen

$ date-> setDate (2013, 12, 30); // jjjj, mm, dd stelt de opgegeven datum in $ datum-> setTime (12, 3, 20); // hh, mm, ss (optioneel) wijzigt de tijd $ datum-> wijzigen ('morgen'); // string-gebaseerde manipulatie $ date-> setTimestamp (1364798550); // wijzigen met behulp van een unix timestamp

Merk op dat wanneer waarden buiten het bereik zijn ingesteld, PHP de datum dienovereenkomstig zal wijzigen. Bijvoorbeeld, $ date-> setDate (2013, 12, 35); zal genereren 2014/01/04, hetzelfde geldt voor de tijd.


Werken met meerdere datums

Nu je geobsedeerd bent door DateTime, het volgende wat je weet, zullen je apps gevuld zijn met DateTime-objecten. Je zult van data en tijden houden zoals nooit tevoren. Vanaf nu heb je te maken met DateTime-objecten, niet met "strings" die je moet doorgeven aan de strtotime functie wanneer je een beetje wiskunde moet doen.

Zeg bijvoorbeeld dat je twee verjaardagen moet vergelijken:

$ sheldon = new DateTime ('20 mei 1980'); $ neo = new DateTime ('11 maart 1962'); if ($ sheldon> $ neo) echo 'Sheldon is jonger dan neo';

Een ander scenario kan twee datums vergelijken. We kunnen data vergelijken met elkaar zoals:

$ diff = $ neo-> diff ($ sheldon);

De diff call retourneert een DateInterval-object. Als we de retourwaarde weggooien:

DateInterval Object ([y] => 18 [m] => 2 [d] => 9 [h] => 0 [i] => 0 [s] => 0 [omkeren] => 0 [dagen] => 6645)

Dit zijn openbare eigendommen. U kunt wat vriendelijke uitvoer van een DateInterval-object genereren:

$ diff-> formaat ('Neo is ouder op% Y jaar en% m maanden ouder'); // Neo is 18 jaar en 2 maanden ouder

Het beste aan het DateInterval-object is dat u het interval kunt toepassen op een ander DateTime-object:

$ Neo-> toe te voegen ($ diff); // neo's verjaardag veranderde in sheldon's

Opmerking: Wijzigingen in DateTime, zoals het toevoegen, retourneert geen nieuwe DateTime-objecten, het beïnvloedt het oorspronkelijke object. Houd hier altijd rekening mee bij het doorgeven van DateTime-objecten in uw app. PHP 5.5 introduceerde een nieuwe klasse die nieuwe objecten retourneert bij wijziging.

diff is niet de enige plaats waar u een DateInterval-object kunt genereren. Omdat het een klasse is, kunnen nieuwe objecten zoals gewoonlijk worden gestart:

$ new_diff = new DateInterval ('P2Y');

Het aantal jaren / maanden / dagen enz. Wordt als tekenreeks doorgegeven aan de constructeur. Meer informatie is te vinden in de documentatie van de constructeur.


Werken met tijdzones

Bij het maken van nieuwe DateTime-objecten definieert het tweede argument van de constructor een tijdzone. Als we dit overslaan, wordt een standaardtijdzone uit de wachtrij gehaald php.ini's date.timezone. U kunt dit tijdens runtime wijzigen door te bellen date_default_timezone_set:

date_default_timezone_set ( 'America / New_York'); nieuwe DateTime ('vandaag'); // datetime-object is in de tijd van New York

Je kunt ook tijdzones veranderen tijdens de vlucht. Zoals je misschien al geraden hebt, hebben we eerst een Timezone-object nodig.

$ timezone = new DateTimeZone ('America / New_York'); $ Sheldon-> setTimezone ($ tijdzone); // Sheldon's verjaardag nu door naar New York

U kunt de tijdzone definiëren tijdens het maken van uw nieuwe DateTime-object:

$ sheldon = new DateTime ('20 mei 1980', $ timezone);

Een belangrijk ding om op te merken is echter dat setTimezone past het originele DateTime-object aan. Wat we in feite vragen is "formatteer deze datum, naar deze tijdzone" telkens wanneer we de setTimezone methode. Aan de andere kant, in het laatste voorbeeld waarin we de tijdzone doorgeven aan de constructor DateTime, zeggen we: "de datum die ik aan het maken ben in deze tijdzone".

Een lijst met geldige tijdzones is beschikbaar in de online documentatie.


DatePeriods

Ik denk dat de officiële handleiding de beste verklaring biedt:

Een dataperiode maakt herhaling mogelijk over een reeks datums en tijden, die met regelmatige tussenpozen gedurende een bepaalde periode terugkeren.

Met DatePeriod kunnen we een set DateTimes genereren met twee dagen die we definiëren tussen een interval. We geven een begindatum, een interval en een einddatum door. Voor elk interval wordt een nieuw DateTime-object gemaakt.

Laten we zeggen dat we alle geboortedata van Sheldon willen hebben, sinds zijn geboorte:

// aangezien verjaardagen elk jaar voorkomen, is het interval één jaar $ interval = new DateInterval ('P1Y'); // derde argument is de einddatum, nieuw DateTime () == nu $ period = new DatePeriod ($ sheldon, $ interval, new DateTime ()); foreach ($ periode als $ dt) // DateTime-objecten echo $ dt-> indeling ('Y-m-d - D'), "\ n"; 

Het resultaat zou zijn:

1981-05-20 - wo 1982-05-20 - do 1983-05-20 - vrij 1984-05-20 - zo 1985-05-20 - ma 1986-05-20 - di ... 

Nu is standaard de DatePeriod bevat de begindatum die we doorgeven. Het vierde argument voor de constructor staat ons echter toe om de startdatum over te slaan:

$ period = new DatePeriod ($ sheldon, $ interval, new DateTime (), DatePeriod :: EXCLUDE_START_DATE);

Laten we eens kijken hoeveel verjaardagen Neo heeft gehad voordat Sheldon werd geboren:

$ bdays = new DatePeriod ($ neo, $ interval, $ sheldon, DatePeriod :: EXCLUDE_START_DATE); echo iterator_count ($ bdays);

Het uitbreiden

Alle klassen die we vandaag hebben behandeld, kunnen worden uitgebreid om te gebruiken met uw eigen methoden. Een populair gebruik is het uitbreiden van de DateTime met een __toString methode, zodat u een DateTime-object goed kunt afdrukken zonder te bellen formaat.


Een paar gebruikscenario's

  • Een van mijn persoonlijke benaderingen voor het gebruik van DateTime-objecten, is wanneer ik te maken heb met kolommen voor datum / tijd in databases. Alle datums worden opgeslagen als UTC-tijdzonedatums. De app-code werkt alleen met DateTime-objecten, maar voordat de eindquery wordt gegenereerd, worden alle datums opgemaakt voor UTC. Dankzij deze aanpak kon ik gemakkelijk met meerdere tijdzone-ingangen werken.

    Ik kan een tijdobject in New York doorgeven en vergeet het helemaal te formatteren voordat ik naar de database ga. Ik kan op elk gewenst moment eenvoudig schakelen tussen Unix-tijdstempels en reguliere datum-tijdopmaak in mijn database, mijn app-code interesseert zich niet zolang het een DateTime-object krijgt.

  • Ik heb DateInterval ook gebruikt om de betalingslogica voor abonnementen te vereenvoudigen. Het gebruik van DateInterval-objecten om de tijd tussen het abonnement te definiëren heeft de zaken echt gemakkelijk gemaakt. Ik moet alleen het interval toepassen op de laatste betalingsdatum.

Heb je goede voorbeelden voor het gebruik van datum / tijd? Deel ze in de reacties.


Afronden

De datum tijd extensie heeft zoveel te bieden, als je op weg bent, zijn er nieuwe klassen en interfaces geïntroduceerd sinds PHP 5.5. Zorg ervoor dat je de handleiding hebt gelezen. Bedankt voor het lezen.