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.