Antes de nada, os aviso de que no voy a denostar por completo el uso de DateTime.Now
, ni de las estructuras similares que existen en cada lenguaje. Obviamente, cada vez que tengamos que mostrar a los usuarios un dato horario, lo ideal es dárselo en su formato local, aquél que conocen y saben interpretar de forma inmediata sin necesidad de realizar cálculos mentales.
Sin embargo, todas las operaciones internas en las que intervenga una hora deberían hacerse con horas en Tiempo Universal Coordinado, más conocido como UTC. Aunque a algunos pueda parecerles un capricho o un formalismo innecesario, son varias las situaciones en que agradeceremos usar UTC, y no solamente por su invariabilidad, sino también por su eficiencia.
Menos operaciones, menos incertidumbre
Antes de ver los casos caóticos, conviene saber qué tiene de provechoso usar UTC en el día a día. Por ejemplo, en el típico caso en el que queremos medir un lapso de tiempo ocurrido entre dos eventos (normalmente el principio y el final de una operación cuya eficiencia nos interesa especialmente).
DateTime comienzo = DateTime.Now; // Operaciones cuya duración queremos medir DateTime fin = DateTime.Now; TimeSpan duracion = fin - comienzo;
Nuestro objetivo debe ser introducir el menor ruido posible en la medición, por lo que toda operación que no sea parte del conjunto a medir, debería ser lo más rápida posible. Dependiendo de la precisión deseada, puede ser fundamental conocer el funcionamiento interno de DateTime.Now
: en primer lugar llama a DateTime.UtcNow
, a continuación calcula el desfase horario en función de la zona establecida, y por último verifica si hay que aplicar la corrección por horario de verano. En resumen, DateTime.UtcNow
es un par de órdenes de magnitud más rápido que DateTime.Now
.
De hecho, en C# es incluso más rápido que la clase Stopwatch
, creada ex profeso para este tipo de mediciones de precisión, pero que obviamente aporta más herramientas destinadas a dicho fin. Podemos verlo en este gráfico, obtenido a partir de un benchmarking realizado por Keyvan Nayyeri:
Trabajar con usuarios de todo el mundo sin volverse loco
Si ganar algunos milisegundos no es tu finalidad, no te preocupes, hay más motivos para utilizar UTC. Uno bastante importante es que tu aplicación sea utilizada por usuarios de distintas zonas horarias. Y ni siquiera es necesario que sean de países distintos.
Imagina: tu base de datos tiene un registro del usuario A, que utilizó la aplicación en Las Palmas de Gran Canaria, con hora 09:10; mientras que hay otro registro del usuario B, que utilizó la aplicación en su PC de Córdoba, a las 10:05. Si no recuerdas si la hora guardada se tomó en los clientes o en el servidor, puedes dudar acerca de cuál de los dos es anterior.
Pero es más, puedes encontrarte con este mismo problema con usuarios de una misma zona horaria. Es tan simple como que tu servidor pase a alojarse en un hosting de otro país, y si lo tienes configurado conforme a su información regional, las horas guardadas en él pueden dejar de significar lo que tú crees que significan.
Fatalidad, ocurre lo que no debería ocurrir cuando no debería ocurrir
Pero cuando de verdad se ve lo necesario que es usar datos invariables es en las situaciones excepcionales, aquellas en las que nunca solemos pensar, entre las que cabe destacar los cambios de hora debidos al ahorro energético.
Y es que el destino caprichoso puede querer que uno de tus usuarios comience una operación a las 2:59 CET del último sábado de marzo… ¡y la termine a las 2:00 CEST de ese mismo día por culpa del cambio al horario de verano! Es poco probable, pero puede ocurrir y fastidiarte contadores con tiempos negativos (o enormes por culpa de un desbordamiento). O que te pase como en Samoa, donde el gobierno decidió suprimir el 30 de diciembre de 2011 para mejorar sus relaciones económicas internacionales.
En definitiva, más vale pensar que lo peor puede pasar, y que no nos pille desprevenidos.
Vía | MSDN – DateTime.UtcNow is generally preferable to DateTime.Now