FECHA Y HORA

unciones Básicas

Para el manejo de fechas hay tres funciones básicas en PHP que harán la mayoría del trabajo necesario en la manipulación de fechas.

  • time(): devuelve la fecha y hora actual expresada en segundos (desde el 1 de enero de 1970 – llamada timestamp). Como devuelva la fecha en un entero se puede utilizar para sumar o restar fechas así como guardarla en base de datos.
  • date(): devuelve la fecha de acuerdo al formato que definamos (Mas información de como formatear la fecha en PHP: date – Manual). Esta función sirve para imprimir las fechas en formatos legibles para los visitantes.
  • strtotime(): convierte una texto en fecha expresada en timestamp.

Entonces, resumiendo la time() devolverá la fecha para poder manipularla posteriormente ydate() dará formato legible para los usuarios.

Veamos unos ejemplos de uso de la función time:

// imprimir la hora actual echo time(); // 1270966374 // imprimir dos horas antes de la hora actual echo (time()-2*60*60); // 1270959174 // imprimir la fecha de hace una semana echo (time()-7*24*60*60); // 1270361574

Ahora veamos como utilizar la función date:

// imprimir la fecha actual echo date("d/m/Y"); // 10/04/2010 // imprimir la hora actual echo date("h:m:s a"); // 10:04:52 pm // imprimir dos horas antes de la hora actual echo date("h:m:s a", time()-2*60*60); // 08:04:52 pm

Las fechas y el Timezone

El timezone o zona horaria es la hora de cada localidad de acuerdo a su ubicación en la tierra respecto a una hora universal. Pueden conocer el timezone de su localidad en World Time Zone, por ejemplo si estamos en Lima – Perú, el timezone es -5.

Ahora, si imprimimos una fecha utilizando directamente la función date(), esta lo hará pero basado en la zona horaria de mi proveedor de hosting. Para corregir esto es necesario hacer un ajuste de acuerdo al timezone nuestro y de nuestro servidor de hosting.

Creamos una función llamada dateZone que recibe dos parámetros: primero el formado que deseamos imprimir basado en la documentación (PHP: date – Manual) y el segundo parámetro es el timezone de nuestra ciudad.

function dateZone($fmt, $zone = 0) { return date($format, time() - date("Z") + $zone*3600); }

Veamos un ejemplo de uso de esta función comparada con la función date y otra utilizando la zona horaria de Lima.

echo date("h:i:s a - d/m/Y"); // 11:40:22 pm - 10/04/2010 echo dateZone("h:i:s a - d/m/Y", -5); // 01:40:22 am - 11/04/2010

Representaciones del tiempo

Como cadena de texto

Históricamente, el ser humano representa el tiempo en unidades de años, meses, día del mes, horas, minutos y segundos. Además, cada uno de los meses del año tiene un nombre, de modo que una fecha y hora determinadas se representan habitualmente como una cadena de texto: “17 de Marzo de 2012, 15:35:07″

Un programa de ordenador puede utilizar el mismo esquema, haciendo uso de una variable que contiene dicha cadena de texto:

$fecha = "17 de Marzo de 2012, 15:35:07";

Naturalmente, esta representación es muy ineficiente, porque ocupa mucho espacio y no permite la manipulación aritmética de las fechas.

Como un conjunto de componentes

Otra posibilidad es definir una variable numérica para cada uno de los elementos. En el caso de los meses, utilizamos una variable numérica con valores 1 a 12 para representar los doce meses del año:

$anno = 2012;

$mes = 3; // 3 => Marzo

$dia = 17

$hora = 15

$minuto = 35

$segundo = 7;

De esta manera podemos trabajar mejor, pero la aritmética de fechas todavía es complicada, y estamos utilizando seis valores enteros, que son 24 bytes en una arquitectura de 32 bit).

Unix timestamp

Cuando comenzó a desarrollarse el sistema unix a comienzos de los años 70 del pasado siglo, se adoptó la representación de las fechas como un único valor entero, conteniendo los segundos transcurridos desde al 1 de Enero de 1970 a las cero horas, cero minutos y cero segudos (las fechas anteriores se representan simplemente como valores negativos).

Esta representación, conocida como “unix timestamp” es la más compacta, y permite comparar fechas, y realizar todo tipo de operaciones aritméticas con ellas. Además sólo consume cuatro bytes para almacenar un valor entero en una arquitectura de 32 bit.

Obtener la fecha y hora actuales

La función ‘time‘ devuelve la fecha y hora actuales como un valor entero en formato “unix timestamp”. La sentencia:

devuelve como resultado:

<?php

$ahora = time();

print "La fecha actual es: " . $ahora . "n";

$hora = ($ahora % (24*60*60)) / (60*60);

$minuto = (($ahora % (24*60*60)) / 60) % 60;

print "La hora actual es: " . floor($hora) . ":" . floor($minuto) . "n";

?>
La fecha actual es: 1350561514
La hora actual es: 11:58

Convertir el formato “unix timestamp” en una cadena de texto

Con la función ‘date()‘ podemos transformar el valor entero que devuelve la función ‘time()’ en una cadena de texto legible por un ser humano. El formato concreto se le pasa en forma de una cadena de texto que contiene una especificación de formato.Si añadimos al script del ejemplo la sentencia:

print "La fecha completa es: " . date("d/m/Y H:i",$ahora) . "n";

Obtenemos como resultado:

La fecha actual es: 1350562038

La hora actual es: 12:7

La fecha completa es: 18/10/2012 13:07

Como vemos, la hora que devuelve la función date() en el ejemplo es posterior en una hora a la que hemos calculado nosotros. Esto se debe a que la función ‘date()’ devuelve la hora local, que depende de la zona horaria en la que nos encontramos, y del cambio horario que se aplica en algunos países en verano (DST, Daylight Saving Time’) para ahorrar en el consumo de energía. Por el contrario la función time siempre devuelve el tiempo GMT (Greenwich Meridian Time).

Convertir una fecha contenida en una cadena de texto a formato “unix timestamp”

PHP también dispone de una función ‘strtotime()’, que convierte una cadena de texto en un entero en formato “unix timestamp”.

A continuación podemos ver algunos ejemplos:

1

2

3

4

5

6

7

8

9

10

print date("d/m/Y H:i",strtotime("6 Feb 2012")) . "n";

print date("d/m/Y H:i",strtotime("2012-02-06")) . "n";

print date("d/m/Y H:i",strtotime("6/2/2012")) . "n";

print date("d/m/Y H:i",strtotime("2012-08-06 17:20")) . "n";

print date("d M Y H:i",strtotime("2012-08-06 17:20")) . "n";

print date("d M Y H:i",strtotime("Aug 6 2012 17:20")) . "n";

print date("d M Y H:i",strtotime("Ago 6 2012 17:20")) . "n";

if (strtotime("Ago 6 2012 17:20") == 0) {

print "Error en formato de fechan";

}

Estas sentencias producen el siguiente resultado:

1

2

3

4

5

6

7

8

06/02/2012 00:00

06/02/2012 00:00

02/06/2012 00:00

06/08/2012 17:20

06 Aug 2012 17:20
06 Aug 2012 17:20
01 Jan 1970 01:00
Error en formato de fecha

Como vemos, las primeras dos sentencias producen el resultado esperado. Sin embargo, la tercera intercambia los valores de día y mes, porque strtotime espera el formato americano “MM/DD/YYYY”.

De nuevo, las sentencias 4, 5 y 6 reconocen correctamente una fecha con hora y minuto. Pero en las sentencias 5 y 6, vemos que tanto strtotime() como date() utilizan el nombre del mes en inglés. Si nuestra fecha está en otro idioma, tendremos que hacer previamente la conversión.

Por último, la séptima sentencia imprime la fecha “01 Jan 1970 01:00″ ! Lo que ha ocurrido es que la función strtotime no ha podido interpretar la fecha, porque el mes no está en inglés, y ha devuelto un cero. Si convertimos un valor cero con la función date, devuelve la hora local correspondiente a la fecha “01 Jan 1970 00:00″, que en nuestro caso es “01 Jan 1970 01:00″.

La última línea corresponde a la sentencia en donde comprobamos el valor devuelto, e imprimimos un mensaje de error si es cero.

Extraer los componentes de una fecha

Si lo que queremos es obtener los distintos componentes año, mes, dia,… de una fecha, podemos utilizar la función date con las adecuadas especificaciones de formato:

$ahora= time();

$anno = date("Y",$ahora);

$mes = date("m",$ahora);

$dia = date("d",$ahora);

Crear una fecha a partir de sus componentes

Para crear una fecha en formato “unix timestamp” a partir de sus componentes, PHP dispone de la función‘mktime()‘:

int mktime ( [int hora[, int minuto[, int segundo [, int mes [, int dia [, int año [, int es_dst]]]]]]])

Como vemos, el orden de los argumentos es al estilo americano, con el mes antes que el día.

Por otra parte, todos los valores son opcionales, y los que no se especifican se toman de la fecha en curso (incluido el flag que indica si se aplica la corrección DST).

Ejemplo. Las sentencias:

producen el resultado:

print date("d/m/Y H:i",mktime(17)) . "n";

print date("d/m/Y H:i",mktime(17,20)) . "n";

print date("d/m/Y H:i",mktime(17,20,0,8)) . "n";

print date("d/m/Y H:i",mktime(17,20,0,8,6,2012)) . "n";

print date("d/m/Y H:i",mktime(17,20,0,8,6,2012,1)) . "n";

print date("d/m/Y H:i",mktime(17,20,0,8,6,2012,0)) . "n";

18/10/2012 17:13
18/10/2012 17:20
18/08/2012 17:20
06/08/2012 17:20
06/08/2012 17:20
06/08/2012 18:20

Como vemos, en donde no se especifican, se asumen el minuto, dia, mes y año correspondientes al momento en que se ejecuta el script.