Calcular la diferencia entre 2 fechas usando DateTime, Convert.ToDateTime, DateTime.Now.ToString y System.Globalization, con C# y VB
Este es un ejercicio muy sencillo que ilustra el uso de funciones de fecha para calcular el número de días existentes entre 2 fechas determinadas.
En la página aspx se crean unos elementos DropDownList (listas desplegables) para ir seleccionando día, mes y año que se compararán con la fecha actual. Por ejemplo, la lista que corresponde a los meses del año puede crearse con este código:
<asp:DropDownList ID="ListaMes" runat="server" AutoPostBack="True" Font-Size="Small" Font-Names="Verdana" OnSelectedIndexChanged="ListaMes_SelectedIndexChanged"> <asp:ListItem Value="Enero">Enero</asp:ListItem> <asp:ListItem Value="Febrero">Febrero</asp:ListItem> <asp:ListItem Value="Marzo">Marzo</asp:ListItem> <asp:ListItem Value="Abril">Abril</asp:ListItem> <asp:ListItem Value="Mayo">Mayo</asp:ListItem> <asp:ListItem Value="Junio">Junio</asp:ListItem> <asp:ListItem Value="Julio">Julio</asp:ListItem> <asp:ListItem Value="Agosto">Agosto</asp:ListItem> <asp:ListItem Value="Septiembre">Septiembre</asp:ListItem> <asp:ListItem Value="Octubre">Octubre</asp:ListItem> <asp:ListItem Value="Noviembre">Noviembre</asp:ListItem> <asp:ListItem Value="Diciembre">Diciembre</asp:ListItem> </asp:DropDownList></td>
En el archivo de código C# la fecha actual se obtiene y se muestra formateada para que su presentación se adapte a la configuración regional. La fecha se puede formatear para ser presentada de diferentes maneras:
– DateTime.Now.ToString(«dddd, d/MMMM/yyyy») produce miércoles, 12/junio/2019
– DateTime.Now.ToString(«d/MMMM/yyyy») produce 12/junio/2019
– se puede personalizar para una configuración regional determinada importando System.Globalization, inicializando una instancia de la clase CultureInfo y pasándola como parámetro de esta forma: DateTime.Now.ToString(«D», esC) produce miércoles, 12 de junio de 2019.
//declaración y asignación de fecha, Now es la fecha actual f = DateTime.Now; CultureInfo esC = new CultureInfo("es-ES"); LbHoy.Text = DateTime.Now.ToString("D", esC);
Los valores seleccionados en las listas desplegables día, mes y año han de ser convertidos al tipo DateTime que es el tipo de fecha para que DateDiff pueda actuar sobre ellas:
//crear una fecha a partir de los valores seleccionados en las listas desplegables //equivalente a escribir: Dim fa As Date = Convert.ToDateTime("día mes, año") DateTime fa = Convert.ToDateTime(ListaDia.SelectedValue + " " + ListaMes.SelectedValue + ", " + ListaYear.SelectedValue); //variable para almacenar la diferencia de fechas long fb = 0; fb = (DateTime.Today - fa).Days; //DateAndTime.DateDiff(DateInterval.Day, DateTime.Today, fa); //para evitar que la cifra salga como nº negativo cuando fa es anterior a hoy if (fb < 0) { fb = System.Convert.ToInt32(- fb); } //mostrar la diferencia en días LbDiff.Text = "<font size=2 color=black>Días que separan el día de hoy " + "de la fecha seleccionada: </font><b>" + System.Convert.ToString(fb) + "</b>";
Se comprueba si febrero es bisiesto o no y cuales son los meses que tiene 30 días para detectar errores al elegir en la lista desplegable más de 28-29-30 días según cada caso. Podemos decir que cada 4 años hay uno bisiesto, cada 100 años no lo hay y cada 400 sí lo hay, esto se pude expresar con el código
//si no es bisiesto if (!(valoraño % 4 == 0 & valoraño % 100 != 0 | valoraño % 400 == 0))
Este es el bloque completo de la comprobación.
// para avisar al seleccionar un día incorrecto según el mes elegido int ordenMes = 0; ordenMes = ListaMes.SelectedIndex; //mes seleccionado int valorDia; valorDia = int.Parse(ListaDia.SelectedValue); //día seleccionado int valoraño = 0; valoraño = int.Parse(ListaYear.SelectedValue); //año seleccionado // dependiendo del día seleccionado switch (ordenMes) { case 1: //mes febrero //si no es bisiesto if (!(valoraño % 4 == 0 & valoraño % 100 != 0 | valoraño % 400 == 0)) { if (int.Parse(ListaDia.SelectedValue) > 28) { LbDiff.Text = ""; LbAviso.Text = "ERROR: ¡Febrero tiene 28 días!"; return ; } } else //si es bisiesto { if (int.Parse(ListaDia.SelectedValue) > 29) { LbDiff.Text = ""; LbAviso.Text = "ERROR: ¡Febrero bisiesto tiene 29 días!"; return ; } } break; case 3: //meses de 30 días case 5: case 8: case 10: if (int.Parse(ListaDia.SelectedValue) > 30) { LbDiff.Text = ""; LbAviso.Text = "ERROR: ¡Este mes sólo tiene 30 días!"; return ; } break; }
Se desea que las listas desplegables contengan la fecha actual para realizar el cálculo inicial al cargar la página, se consigue con este código:
// Código para hacer que los cuadros de lista arranquen con la fecha actual // la propiedad Now devuelve el mes como entero de 1 a 12 pero así no lo captura bien // la lista desplegable de los meses de la página aspx, por ello convertimos el nº en el nombre // del mes con la primera letra en mayúsculas para que coincida exactamente con el nombre del desplegable string mes = ""; mes = f.ToString("MMMM"); mes = mes.Substring(0, 1).ToUpper() + mes.Substring(1).ToLower(); ListaDia.SelectedValue = System.Convert.ToString(f.Day); ListaMes.SelectedValue = mes; ListaYear.SelectedValue = System.Convert.ToString(f.Year);
Puedes descargar un archivo ZIP con las aplicaciones C# y VB.
Sí, existe la función DateTime.IsLeapYear que devuelve True si el año es bisiesto, en caso contrario devuelve False.
Podrías pasarle un año en número, por ej.
If (DateTime.IsLeapYear(2000))
o con la fecha actual
If (Date.IsLeapYear(Now.Year)).
Hay alguna manera de saber si el año es bisiesto dentro de las funciones del propio lenguaje visual basic? Veo que recurres a un cálculo matemático basado en las ocasiones en que el año es bisiesto pero me gustaría hacerlo por código más específico del lenguaje.