FUNCIONS PER MANEIG DEL TEMPS, DATA I HORES PHP


Sovint quan vam crear webs o apps hem de treballar amb dates i calendaris. 
Per exemple en la pàgina web d'un hotel o un restaurant és possible que treballem amb dates i hores de començament de reserva, de cap de reserva, etc. PHP disposa de funcions natives per facilitar el treball amb dates, hores i temps.

El maneig del "temps" és un aspecte controvertit en la programació. La primera dificultat i més òbvia és que hi ha centenars de dispositius electrònics i no tots manegen la mateixa data. Per exemple el meu ordinador personal pot indicar que avui és dilluns 25 gener 2048 i l'hora és les 12:35:44 mentre que el servidor al qual estic connectat, suposant que està en la meva mateixa ciutat, pot indicar que avui és dilluns 25 de gener de 2048 i l'hora és les 00:33:21. Un altre servidor, en un altre país, pot indicar que la data és diumenge 24 gener 2048 i l'hora és les 23:51:15 causa de la diferència horària entre països. Aquí, és clar, ens estaríem referint a hores locals. Per poder disposar d'hores de referència globals per a tothom es van crear estàndards com:

a) GMT o temps mitjà de Greenwich: ha estat un estàndard àmpliament usat. GMT era el temps mesurat en l'observatori britànic de Greenwich, que es va definir com a meridià zero de la terra. Així cada país podia expressar la seva hora en funció de l'hora del meridià de Greenwich. Per exemple GMT+0 indicava que l'hora era la mateixa que l'hora oficial al meridià de Greenwich, mentre que GMT+3 indicava que l'hora eren 3 hores més que en el meridià de Greenwich (és a dir, si és Greenwich eren les 09:00 en un país la hora fora GMT+3 serien les 12:00).

b) UTC o temps universal coordinat: és l'estàndard que s'ha adoptat com a referència que indica un temps únic independentment de en quin lloc del planeta ens trobem, basat en els mesuraments de rellotges atòmics distribuïts per diferents països. És l'estàndard que s'està imposant en els sistemes informàtics.

La circumferència terrestre es va dividir en 24 fusos horaris de manera que cada fus quedava referenciat a un temps comú (el que es denominava el temps de Greenwich).

fusos horaris utc javascript

Encara que des del punt de vista de la seva definició tècnica UTC i GMT no són el mateix, a efectes pràctics parlar de GMT+ 3 és el mateix que parlar de la UTC+3.

Tot i aquest gran avenç, el treball amb el temps segueix presentant grans dificultats en els sistemes informàtics, tant per la falta de sincronització entre dispositius com per la disparitat quant a com mesurar el temps i amb quin grau de precisió, existència d'horaris d'estiu i hivern, etc. Per això trobaràs que és relativament freqüent trobar que a mesura que els llenguatges de programació evolucionen vagin introduint canvis en la forma de manejar el temps.

Una qüestió a tenir en compte és que el temps oficial de Greenwich, temps GMT o UTC, no es correspon amb el temps local en Greenwich causa de l'existència de l'horari d'estiu. Per exemple, Lisboa es troba en el fus horari de Greenwich, però a l'estiu l'hora local està avançada una hora respecte al temps oficial de Greenwich per motius d'estalvi energètic. Això dóna lloc al fet que el 5 d'agost a les 21:00 a Lisboa es correspongui amb el 5 d'agost 20:00 UTC causa de l'horari d'estiu, tot i que Lisboa es trobi en el mateix fus horària que Greenwich.

 

FUNCIONS TIME I DATE

Aquestes dues funcions ens permetran mostrar o capturar la data i hora, la qual cosa té una gran quantitat d'aplicacions. Per exemple, suposa que tens una botiga on-line i per a cada operació de venda has de registrar la data i hora de la venda. Aquestes funcions resultaran útils per a això.

La funció time retorna l'hora GMT actual mesura com el nombre de segons des de l'1 gener 1970 00:00:00 GMT (hora del meridià de Greenwich) obtinguts a partir de l'hora actual local del servidor. Quan parlem de "hora actual del servidor" ens referim a una hora local, que és diferent segons el país on ens trobem. En canvi l'hora GMT és única i no depèn del país. Cal anar amb compte amb aquesta circumstància. Per exemple, si treballes amb un servidor localitzat a Estats Units el més probable és que el servidor treballi amb l'hora d'Estats Units. Si vols obtenir l'hora local del teu país, hauràs de tenir-ho en compte per a restar-li o sumar-li cert nombre d'hores a l'hora que et torni el servidor.

D'altra banda, la funció date mostra la data en el format que li indiquem.

En general, et recomanem que facis proves per comprovar que els resultats de data i hora obtinguts són les adequades, ja que la configuració de cada servidor i la versió de PHP emprada pot afectar els resultats.

Escriu ara aquest codi i guardeu amb un nom de fitxer com ejemplo2.php. A continuació, puja el fitxer al servidor i visualitza el resultat.

<? Php // Exemple curs PHP

$temps=time();

echo date("DMY(H: i: s)",$tme);

?>

En aquest exemple hem especificat com a format per mostrar la data DMY (H: i: s) (on d representa dia, m representa mes, I representa any, H representa hora, i representa minuts i s representa segons) des del valor de time o una altra data donada en segons des de l'1 gener 1970 00:00:00 GMT.

Com podem observar, la funció date dóna format a la variable en segons $time. Hi ha diferents formats per a la funció date, a continuació indicarem els més importants.

La funció time () retorna un valor numèric enter llarg, per exemple 1335169779. Aquest número representa el nombre de segons transcorreguts des de l'1 gener 1970 00:00:00 GMT.

Per transformar aquest nombre en una data "comprensible per les persones" fem servir la funció date, la sintaxi general és: date ("format de sortida", valorTimeValit)

Pel que fa a valorTimeValit, serà un nombre enter, generalment contingut en una variable.

Pel que fa a "format de sortida", disposem de les següents equivalències:

 

Per representar el dia de la setmana:

Caràcter de format

Significat

Valors que retorna

d
(minúscula)

Dia del mes, amb 2 dígits. Si és menor de 10, porta un 0 inicial.

Gener 1 31

D (majúscula)

Text representatiu del dia, amb 3 lletres i en anglès

Mon (dilluns) fins Sun (diumenge)

j
(minúscula)

Dia del mes amb un dígit (sense zeros inicials)

Gener 1 31

l
(ella lletra minúscula)

Text representatiu del dia, amb totes les lletres i en anglès

Monday (dilluns) fins Sunday (diumenge)

N (majúscula)

Representació numèrica del dia de la setmana segons ISO-8601, sent 1 el dilluns i 7 diumenge

1 (dilluns) a 7 (diumenge)

S
(majúscula)

Sufix pel dia del mes en anglès

st, nd, rd o XX

en un (minúscula)

Representació numèrica del dia de la setmana sent 0 diumenge i 6 dissabte

0 a 6

z
(minúscula)

Dia de l'any des de 0 fins 365 (un any normal anirà de 0 a 364 i 1 de traspàs de 0-365)

0-365

 

Per representar el mes:

Caràcter de format

Significat

Valors que retorna

F
(majúscula)

Text representatiu del mes, amb totes les lletres i en anglès

January (gener) a December (desembre)

m (minúscula)

Mes en format numèric amb dos dígits, incloent zero inicial si és menor de 10

01-12

M (majúscula)

Text representatiu del mes, amb tres lletres inicials en anglès

Jan (gener) fins Dec (desembre)

n
(minúscula)

Mes en format numèric amb un dígit, sense zeros inicials

1-12

t
(minúscula)

Nombre de dies que té el mes

28-31

 

 

Per representar l'any:

Caràcter de format

Significat

Valors que retorna

L
(majúscula)

Indica si un any és de traspàs o no (1 si és de traspàs, 0 si no ho és)

0 de 1

I
(majúscula)

Any en format numèric de 4 dígits

1000 al 9999

i
(minúscula)

Any en format numèric de 2 dígits (els dos últims de l'any)

El que correspongui, p.ex. 78

la
(petita)

Nombre d'any segons ISO-8601. En general retorna el mateix resultat que I majúscula

1000 al 9999

 

 

Per representar l'hora:

Caràcter de format

Significat

Valors que retorna

a
(minúscula)

Inclou am o pm en minúscules darrere de l'hora per indicar abans del meridià o passat el meridià

am o pm

A
(majúscula)

Igual que a però en majúscules

AM a o PM

B
(majúscula)

Hora internet, també anomenada Swatch Internet Time o Biel Mean Time (BMT), poc usada.

000 al 999

g
(minúscula)

Nombre d'hora des de 1 fins 12 no zeros inicials

1 1 des

G
(majúscula)

Nombre d'hora des 0-23 sense zeros inicials

0 i 23

h

(minúscula)

Nombre d'hora des de 01 fins a 12, amb zeros inicials

01 desembre 1

H

(majúscula)

Nombre d'hora des 00-23, amb zeros inicials

00-23

i

(minúscula)

Minuts des 00-59, amb zeros inicials

00-59

s

(minúscula)

Segons des 00-59, amb zeros inicials

00-59

 

 

Per representar la zona horària:

Caràcter de format

Significat aprenderaprogramar.com

Valors que retorna

i

(petita)

Representa la zona horària en anglès (p.ex. GMT, Atlantic/Açores, America/Denver)

Segons correspongui

I

(lletra i majúscula)

Indica si s'està en horari d'estiu (0 indica que no s'està en horari d'estiu, 1 que sí que s'està en horari d'estiu).

0 de 1

O

(lletra o majúscula)

Indica la diferència respecte a la zona horària de Greenwich o hora GMT, en hores amb quatre dígits i símbol.

Per exemple +0300 o -0500

P (majúscula)

Indica la diferència respecte a la zona horària de Greenwich o hora GMT, en hores amb quatre dígits amb separador dos punts i símbol.

Per exemple
+ 03: 00  o
-05: 00

T(majúscula)

Abreviatura de la zona horària (abreviatura en anglès)

Segons correspongui

Z (majúscula)

Diferència en segons entre l'hora utilitzada i l'hora UTC, amb signe positiu o negatiu

-43.200
-50.400

A més disposem de:

La lletra W majúscula per representar la setmana de l'any segons ISO-8601, considerant que les setmanes comencen en dilluns. Per exemple, un any té 52 setmanes i amb aquest format podem obtenir que estem en la setmana 24 de l'any.

La lletra c minúscula per representar la data i hora completa en format ISO-8601 (tipus 2089-03-12T12: 19: 21 + 03: 00).

La lletra r minúscula per representar la data i hora completa amb format RFC-2822 (tipus Mon, 21 Jan 2089 11:41:05 -0300).

Escriu ara aquest codi i guardeu amb un nom de fitxer com ejemplo2bis.php. A continuació, puja el fitxer al servidor i visualitza el resultat.

<? Php // Exemple curs PHP

$temps=time();

echo "<br/>" ;

echo $time;

echo "<br/>" ;

date ("DMY(H:i:s)", 3600);

echo "<br/>" ;

date ("DMY(H:i:s)",0);

echo "<br/>" ;

date ("DMY(H:i:s)",3600);

echo "<br/>" ;

date ("Ymd(H:i:s)",$temps);

echo "<br/>" ;

data ("Ymd",$temps);

echo "<br/>" ;

echo("Segons el servidor l'hora actual és:". date("H: i: s", $time));

?>

Amb aquest exemple podem comprovar algunes coses. En primer lloc, que la funció time() retorna un nombre, mentre que la funció date retorna un String o cadena de text.

En segon lloc, que per obtenir dates anteriors a l'1 gener 1970 hem de fer servir nombres negatius.

En tercer lloc, que el moment 0 que és el 01-01-1970 00:00:00 GMT, quan és mostrat per un servidor concret, és adaptat al seu horari local. Al servidor de l'exemple, l'horari local és GMT + 01:00, és a dir, la seva hora és l'hora GMT +01: 00, per això ens torna com a hora zero la una del matí de l'1 de gener de 1970. No et preocupis si et resulta una mica confús, simplement tingues en compte que has de fer proves per veure com respon el servidor amb el que estiguis treballant.

En quart lloc, que podem fer que la data es mostri en el format o ordre que vulguem, usant els termes clau "d, m, I, H, I, s" en l'ordre que vulguem.

En cinquè lloc, que podem concatenar com es mostra una data (o emmagatzemar-la en una altra variable si volguéssim) concatenant el resultat de la funció date amb una cadena de text qualsevol.

 

ALTRES FUNCIONS PER DATA, HORA I TEMPS PHP

PHP defineix altres funcions natives per a maneig de dates, hores i temps. Anem a veure algunes d'elles:

FUNCIÓ

UTILITAT

EXEMPLES aprenderaprogramar.com

mktime (hora, el meu, a dalt, mes, dia, anus)

hora: 0 i 23

mi i fins: 0 a 59

meu: 1 a 12

dia: 1 a 31

any: 4 dígits

Retorna l'hora UTC (GMT) per a una data local indicada, expressada aquesta hora GMT en segons (el nombre de segons transcorreguts des de l'1 gener 1970 00:00:00 GMT, valors negatius indiquen moments anteriors a aquesta data). Si falten un o més paràmetres es prendran els de la data local actual de dreta a esquerra. El valor obtingut depèn de l'hora local del servidor amb el qual estiguem treballant.

echo "Temps Unix per al 15-Gener-2089 a les 12h 0m 0s =". mktime (12,0,0,1,15,2089);

// Temps Unix per al 15-Gener-2089 a les 12h 0m 0s = 3753975600 (el resultat variarà segons on estigui localitzat el servidor, perquè les 12 h del 15 gener 2089 corresponen a diferents dates-hores GMT segons on es trobi el servidor.

gmmktime (hora, el meu, a dalt, mes, dia, anus)

hora: 0 i 23

mi i fins: 0 a 59

meu: 1 a 12

dia: 1 a 31

any: 4 dígits

Retorna l'hora UTC (GMT) expressada en segons per a una data GMT indicada en els arguments rebuts. El valor retornat és el nombre de segons transcorreguts des de l'1 gener 1970 00:00:00 GMT, valors negatius indiquen moments anteriors a aquesta data. Si falten un o més paràmetres es prendran els de la data GMT actual de dreta a esquerra. El valor obtingut no depèn del servidor, ja que l'hora GMT és única.

gmmktime (12,0,0,1,15,2089)

// 3756628800 independentment de l'hora local del servidor

Nota: tenir en compte que fem servir UTC o GMT com si fossin equivalents.

Per entendre com les funcions time i mktime treballen amb temps local hem realitzat la següent prova. Hem col·locat el següent codi en un servidor a Denver (USA), i en un servidor a Madrid (Espanya):

echo "Temps Unix per al 15-Gener-2089 a les 12h 0m 0s =". mktime (12,0,0,1,15,2089);

El resultat obtingut a Denver (USA) es 3 756 654 000

El resultat obtingut a Madrid (Espanya) es 3 756 625 200

Per què obtenim un resultat diferent?

La diferència entre un i altre temps és de 28800 segons, que equivalen a 8 hores.

Hem comprovat l'hora a Denver en el moment de realitzar el test i eren les 06:20:00 del matí, mentre que a Madrid eren les 14:20:00 hores. Com veiem, tenim una diferència horària de 8 hores entre Denver i Madrid.  

Quan a Madrid són les 12:00 hores del 15 gener 2089, a Denver seran les 04:00 hores del 15 de gener de 2089. Les 12:00 hores d'un dia tenen lloc en diferents instants de temps a Denver i en Madrid, per això els resultats indiquen que quan són les 12 hores a Denver ha transcorregut més temps des de les 0 hores del 1 gener 1970 GMT que quan són les 12 hores a Madrid, o dit d'una altra manera, les 12 hores d'un dia tenen lloc abans a Madrid que a Denver. El temps Unix si serà igual si demanem el valor mktime (4,0,0,1,15,2089) a Denver: obtindrem 3756625200, el mateix resultat que a Madrid a les 12 del migdia. Això indica que aquest instant de temps (4 del matí de 15 gener 2089 a Denver i 12 del matí de la mateixa data a Madrid) és el mateix instant, és a dir, podríem estar parlant per telèfon dues persones en aquest moment , sent les 4 del matí a Denver i les 12 a Madrid.

Si demanem l'hora a Madrid per l'1 de gener de 1970 a les 00:00:00 de 1970 ens torna << Temps Unix per l'1 de gener de 1970 a les 00:00:00 = -3.600 >> Què significa -3600? Aquest valor està referit al temps UTC i indica quin avenç o endarreriment (en segons) té l'hora local respecte al temps UTC. O dit d'una altra manera, quant temps ha transcorregut des de les 00:00 hores del 1 gener 1970 UTC donada una data local. Quan a Madrid són les 00:00:00 l'1 de gener de 1970 en el temps UTC de referència (podem pensar que és l'hora a Greenwich, meridià de referència, encara que això no és exacte) diem que falten 3600 segons (1 hora ) per arribar a l'1 de gener de 1970. El valor negatiu indica que la data és anterior a l'1 gener 1970 00:00:00 GMT, i en concret en aquest cas serien les 23 hores del 31 desembre 1969 GMT quan a Madrid són les 00:00:00 hores del 1 gener 1970.

Si demanem l'hora a Denver per l'1 de gener de 1970 a les 00:00:00 de 1970 ens torna << Temps Unix per l'1 de gener de 1970 a les 00:00:00 = 25200 >> Què significa 25200 ? Aquest valor està referit al temps UTC i indica que quan a Denver són les 00:00:00 l'1 de gener de 1970 el temps UTC de referència està 7 hores per davant, és a dir, a les 0 hores a Denver són les 7 hores UTC.

-3600 Segons equivalen a 1 hora per davant de GMT. A l'hivern a Madrid l'hora local és GMT + 0100

25200 segons equivalen a 7 hores per darrere de GMT. A l'hivern a Denver l'hora local és GMT-0700

Tenir en compte que l'hora UTC (GMT) és única (la indicada pels organismes internacionals encarregats), mentre que les hora locals varien segons el país, i fins i tot segons la zona d'un país en què ens trobem.

Existeixen més funcions per les dates i temps en PHP però els programadors no les solen conèixer totes, ja que algunes són per a tasques molt específiques. No et preocupis per memoritzar les funcions ni per conèixer-les totes, simplement sigues conscient de la seva existència i aprèn a buscar-les quan et resultin necearias. Si en algun moment necessites realitzar tasques molt específiques amb temps i dates en PHP pots conèixer totes les funcions existents sobre aquesta matèria acudint a la documentació oficial de PHP sobre data i hora, disponible a http://php.net/manual/es/ ref.datetime.php

 

EXERCICI

Crea un document HTML que consti d'un títol h1 amb el text << Calendari >>. A la pàgina haurà de mostrar-se el mes i any actuals (en el moment en que facis l'exercici) i per a cada dia del mes, indicar si és dilluns, dimarts, dimecres, dijous, divendres, dissabte o diumenge.

Exemple: suposant que facis l'exercici al maig de 2050, hauria de mostrar-:

Dia 1: Diumenge, Dia 2: Dilluns, Dia 3: Dimarts, Dia 4: Dimecres, ... etc. fins Dia 31: Dimarts.

Ampliació voluntària de l'exercici: si tens coneixement de maquetació amb HTML i CSS et proposem que canviïs l'aspecte perquè en lloc de mostrar-se com text, el calendari es mostri amb aspecte de calendari habitual. Per a la maquetació pots utilitzar una taula de 7 columnes per 7 files (total 49 cel·les) amb ample de taula 300 píxels i grandària de font en la taula 24 píxels. La primera columna correspon a dilluns i l'última a diumenge com mostrem en el següent exemple.

L'aspecte, suposant que et trobes en el mes de maig de 2050, seria el següent:

MAIG DE 2050

Llegir

Però

El meu

La

Nosaltres

La seva

Fer

 

 

 

 

 

 

 1

 2

 3

 4

 5

 6

 7

 8

 9

 10

 11

 12

 13

 14

 15

 16

 17

 18

 19

 20

 21

 22

 23

 24

 25

 26

 27

 28

 29

 30

 31

 

 

 

 

 

 

Tingues en compte que s'ha de generar el calendari del mes en què et trobis segons l'hora local del sistema (del teu servidor).