saber desde consola como bisiestos bisiesto años año algoritmo c# design datetime

c# - desde - ¿Cómo podemos desarrollar prácticas de codificación diseñadas para proteger contra los errores del año bisiesto?



como saber si un año es bisiesto (3)

¿Cómo podemos desarrollar prácticas de codificación diseñadas para proteger contra los errores del año bisiesto? ¿Qué prácticas de codificación podrían haber evitado esto?

La unidad de prueba de fechas específicas como mencionó John es una práctica de código que ayudará sin embargo nada supera lo que defino como una ''prueba de integración manual''

cambie el reloj en su servidor de desarrollo / testbed y mire lo que sucede cuando el tiempo pasa.

No se atasque en detalles sobre si esta es una ''práctica de codificación'' - Obviamente no puede hacer esto para cada fecha en el calendario - elija las fechas que le preocupan, ya sea el 29 de febrero, a fin de mes fechas o fechas de cambio de horario de verano.

Microsoft acaba de anunciar que un error de software en el cálculo de fechas (sobre el año bisiesto) causó una interrupción importante en Windows Azure la semana pasada.

¿Fue realmente un error de juicio simple trabajar alrededor de DateTime.Now.AddYears(1) en un año bisiesto?

¿Qué prácticas de codificación podrían haber evitado esto?

EDITAR Como dcstraw señaló DateTime.Now.AddYears(1) en un año bisiesto, de hecho devuelve la fecha correcta en .NET. Por lo tanto, no es un error de framework, pero evidentemente es un error en los cálculos de fecha.


Enchufe desvergonzado:

Use una mejor API de fecha y hora

Las bibliotecas de fecha y hora incorporadas de .NET son terriblemente difíciles de usar correctamente. Te permiten hacer todo lo que necesitas, pero no puedes expresarte claramente a través del sistema de tipos. DateTime es un desastre , DateTimeOffset puede arrullarlo y hacerle creer que en realidad está conservando la información de la zona horaria cuando no lo está, y TimeZoneInfo no lo obliga a pensar en todo lo que debería considerar.

Ninguno de estos proporciona una buena manera de decir "solo una hora del día" o "solo una fecha", ni hacen una distinción clara entre "hora local" y "hora en una zona horaria particular". Y si desea usar un calendario que no sea el gregoriano, debe pasar por la clase Calendar todo el tiempo.

Todo esto es por lo que estoy construyendo Noda Time , una biblioteca de fecha y hora alternativa construida en un puerto del "motor" Joda Time pero con una API nueva (y más ligera) en la parte superior.

Algunos puntos en los que puede pensar, que son fáciles de detectar si no los conoce:

  • Asignar una fecha / hora local a una en un huso horario en particular no es tan simple como podría pensar. Se puede producir una fecha / hora local específica una vez, dos veces (ambigüedad) o cero (se omite) debido a las transiciones de horario de verano
  • Las zonas horarias varían históricamente: más de lo que TimeZoneInfo generalmente está dispuesto a revelar, francamente. (No es compatible con un huso horario cuya idea de "tiempo estándar" cambia con el tiempo o entra en el horario de verano permanente).
  • Incluso con la base de datos zoneinfo, los ID de zona horaria no son necesariamente estables. (CLDR aborda esto, algo que espero apoyar eventualmente en Noda Time).
  • Las representaciones textuales de fechas y horas son una pesadilla, no solo en términos de ordenamiento, sino también de separadores de fechas, separadores de tiempo y cosas raras como los nombres genitivos de los meses.
  • El comienzo del día no es siempre medianoche: en Brasil, por ejemplo, la transición de horario de verano de primavera mueve el reloj de pared de 11:59:59 p.m. a 1 a.m.
  • En algunos casos (bueno, uno que conozco) un huso horario puede forzar la omisión de un día completo: ¡el 30 de diciembre de 2011 no ocurrió en Samoa! Sospecho que la mayoría de los desarrolladores probablemente ignoren esta, pero ...
  • Si vas a utilizar un calendario que no sea el gregoriano, ten cuidado y asegúrate de saber realmente cómo esperas que se comporte.

En cuanto a las prácticas de desarrollo específicas:

  • Piensa en lo que realmente estás tratando de representar. Espero que el beneficio principal de Noda Time force a los desarrolladores a elegir entre varios tipos diferentes para representar sus datos. Hazlo bien, y todo lo demás es más simple.
  • Prueba de unidad todo lo que puedas pensar. Eso dependerá exactamente de lo que haga su sistema, por supuesto, pero particularmente considerará las diferentes zonas horarias, lo que sucede en las transiciones de horario de verano y, por supuesto, los años bisiestos.
  • Aconsejo que se inyecte una "interfaz tipo reloj", un servicio para indicar la hora actual, en lugar de llamar explícitamente a DateTime.Now o DateTime.UtcNow ; lo hace más fácil (¡factible!) a la prueba unitaria
  • Si está realizando varias operaciones con "ahora", obtenga esa fecha / hora una sola vez y recuérdelo, en lugar de solicitar repetidamente "ahora"; de lo contrario, el valor podría cambiar de forma desafortunada entre las llamadas.
  • "Hacer todo en UTC" tampoco es siempre la respuesta, si quiero saber "¿cuándo exactamente ''dos ​​semanas a partir de ahora'' ocurren en mi zona horaria local?" entonces necesito almacenar la fecha / hora local , así como la zona horaria.

Vale la pena señalar que probablemente el error no se debió a una línea como la que publicaste:

DateTime.Now.AddYears(1)

Eso no crea una fecha inválida. Si tu corres:

(new DateTime(2012, 2, 29)).AddYears(1)

recibes el 28 de febrero de 2013. No sé en qué está escrito el agente invitado de Azure, pero debe haber sido una llamada diferente que falló. Una mala forma de haber hecho esto en .NET hubiera sido:

new DateTime(today.Year + 1, today.Month, today.Day)

Eso arroja una excepción si today es día bisiesto. Sin embargo, el blog de Microsoft sobre el problema de Azure dijo que crearon una fecha no válida del 29 de febrero de 2013, y no estoy seguro de que sea posible hacerlo con DateTime en .NET.

No estoy diciendo que DateTime y DateTimeOffset no sean propensos a errores, solo que no creo que hayan causado este problema en particular.