jueves, 9 de abril de 2015

Javascript: Jugando con fechas

A menudo ocurre que al escribir código obviamos ciertas características del lenguaje con el que se trabaja. Más todavía en Javascript dado que tenemos muchos caminos diferentes para llegar a un punto, por ejemplo, definiendo funciones[1]. En estos casos cada uno tiene sus manías para determinadas situaciones, pero al hacerlo podemos obviar ciertas especificaciones o comportamientos del lenguaje.

Debido a esto, el otro día me encontré con un problema en Javascript en el cuál se encontraban fechas, que no se habían modificado, con la fecha 1/1/1970. Las fechas venían en String por lo que era necesario transformarlas a objetos Date. Tras mucho depurar llegué a ver que en un punto (una directiva de AngularJS para fechas) estaba creando el objeto fecha de la siguiente forma: "new Date(fchEnString)" ¿Problema? Que no se comprobaba si el parámetro era null, aunque sí que existía una comprobación posterior acerca de si el objeto creado era una fecha válida. Sin embargo, existían casos en los que el parámetro no era String, era null, por lo que se estaba realizando un "new Date(null)" y esto devolvía una fecha válida: 1/1/1970. 




Por sí a alguno se le escapa el por qué del 1/1/1970: El estandar de ECMAScript[2] dice que en los objetos Date el tiempo es medido en milisegundos desde el 1 de enero de 1970 UTC.

"Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC" Mozilla Developer Network [3]

Una vez identificado y solucionado el problema me decidí a refrescar mis conocimientos de los objetos Date en javascript y preguntarme qué ocurría con otros valores para el objeto Date. Lo primero que hice fue buscar los constructores del objeto Date[4]. Encontré 4 formas de instanciar el objeto Date.
  • new Date();
  • new Date(milliseconds);
  • new Date(dateString);
  • new Date(year, month. day. hours. minutes, seconds. milliseconds);
Al ver los constructores y conociendo el por qué de 1/1/1970 pude deducir que: new Date(null) obtiene la misma fecha que new Date(0).



Lo siguiente que se me ocurrió fue utilizar undefined como parámetro en el constructor a ver si obtenía la misma fecha. Sin embargo, "new Date(undefined)" devuelve una fecha no válida.



Para probar un caso que fuese correcto, decidí escribir la siguiente cadena como parámetro: "2014/01/01".


Después busqué la forma de obtener la fecha actual (esta es fácil) con "new Date()".


A continuación, me pregunté cómo llegar a la fecha mínima en Javascript. Por lo que consulté la especificación [2]. En la especificación se establece que a partir del 1/1/1970 se pueden obtener fechas de hasta 100mil días más y 100mil días menos. 

"... The actual range of times supported by ECMAScript Date objects is slightly smaller: exactly –100,000,000 days to 100,000,000 days measured relative to midnight at the beginning of 01 January, 1970 UTC. This gives a range of 8,640,000,000,000,000 milliseconds to either side of 01 January, 1970 UTC."

Es decir, el valor mínimo de una fecha es "new Date(-8640000000000000)"

Por último, decidí hacer un par de pruebas con la función Date.parse()[5]



Referencias

[1] http://embat.es/post-tecnico/javascript-definir-funciones-ese-dolor-de-cabeza.html
[2] http://www.ecma-international.org/ecma-262/5.1/#sec-15.9
[3] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
[4] http://www.w3schools.com/jsref/jsref_obj_date.asp
[5] http://www.w3schools.com/jsref/jsref_parse.asp

No hay comentarios:

Publicar un comentario