En algún momento nos va a tocar manipular datos de fechas, ya sea para calcular la edad de un cliente, para generar un cronograma de pagos, para saber si estamos en cierto rango de edades y muchas cosas más. C# nos facilita estas tareas a través de la clase DateTime. Esta clase, al igual que las anteriores que hemos estudiado, posee varios métodos y propiedades que nos van a ayudar a lo largo de nuestro código. Y para usarlos, basta con declarar una variable de tipo DateTime.
// Declaramos nuestra variable tipo fecha.
DateTime dtToday = DateTime.Now;
Console.WriteLine(dtToday);
// Output > 01/07/2021 17:51:15
En el ejemplo anterior, hemos declarado nuestra variable tipo fecha llamada dtToday, a la cual le hemos asignado una propiedad de la clase DateTime, Now, el cual nos trae la fecha y la hora del momento en que se ejecuta el programa .
¿De dónde saca el sistema la información de la fecha y hora? Es importante saber que lo obtiene de tu computadora, o, mejor dicho, de la computadora desde donde estás ejecutando el programa, así que si tienes configurado mal dicha información, C# también lo mostrará de forma incorrecta. Para saber si nuestra computadora está sincronizada con la hora correcta, basta con verificar el reloj de la esquina inferior derecha. En programas complejos, C# nos permite trabajar con horarios de diferentes lugares, así como obtener el formato adecuado para mostrar la información de la fecha. Por ejemplo, los formatos de fecha de Estados Unidos y Perú son diferentes, ya sea por el lenguaje o por otros factores.
Ahora comenzaremos a repasar algunos métodos que nos servirán para programar algoritmos relacionados a fechas.
Add Months (int value), AddYears (int value), AddDays (double value), AddHours (double value), AddMinutes (double value), AddSeconds (double value)
Pongo todos estos métodos juntos porque funcionalmente son lo mismo, simplemente se diferencian porque uno agrega (o quita, si le mandas un valor negativo) valores a la fecha, estos valores pueden ser meses, años, días, horas, minutos y segundos, aunque hay dos métodos más para agregar milisegundos y nanosegundos. Otra diferencia es que para agregar meses y años, te pide un valor de tipo entero, mientras que para los otros métodos, le puedes enviar valores decimales.
DateTime exampleDate = DateTime.Now;
Console.WriteLine(exampleDate);
// Output > Fecha actual: 02/07/2021 00:00:00
DateTime exampleMonths;
DateTime exampleYears;
DateTime exampleDays;
DateTime exampleHours;
DateTime exampleMinutes;
DateTime exampleSeconds;
// AddMonths (int value)
exampleMonths = exampleDate.AddMonths(3); // Le agregamos tres meses a la fecha actual.
Console.WriteLine("AddMonths (3): " + exampleMonths);
// Output > AddMonths (3): 02/10/2021 00:00:00
// AddYears (int value)
exampleYears = exampleDate.AddYears(-10); // Le quitamos 10 años a la fecha actual.
Console.WriteLine("AddYears (-10): " + exampleYears);
// Output > AddYears (-10): 02/07/2011 00:00:00
// AddDays (double value)
exampleDays = exampleDate.AddDays(1.5); // Le agregamos 1 día y 12 horas a la fecha actual.
Console.WriteLine("AddDays (1.5): " + exampleDays);
// Output > AddDays (1.5): 03/07/2021 12:00:00
// AddHours (double value)
exampleHours = exampleDate.AddHours(-10.5); // Le quitamos 10 horas y 30 minutos a la fecha actual.
Console.WriteLine("AddHours (-10.5): " + exampleHours);
// Output > AddHours (-10.5): 01/07/2021 13:30:00
// AddMinutes (double value)
exampleMinutes = exampleDate.AddMinutes(45.5); // Le agregamos 45 minutos y 30 segundos a la fecha actual.
Console.WriteLine("AddMinutes (45.5): " + exampleMinutes);
// Output > AddMinutes (45.5): 02/07/2021 00:45:30
// AddSeconds (double value)
exampleSeconds = exampleDate.AddSeconds(10); // Le agregamos 10 segundos a la fecha actual.
Console.WriteLine("AddSeconds (10): " + exampleSeconds);
// Output > AddSeconds (10): 02/07/2021 00:00:10
ToLongDateString(), ToShortDateString(), ToLongTimeString(), ToShortTimeString()
Estos métodos sirven para transformar la fecha en un formato de texto, ya sea formato largo o formato corto. Estos métodos no reciben ningún parámetro y el resultado debe almacenarse en una variable de tipo string.
DateTime exampleDate = DateTime.Now;
Console.WriteLine(exampleDate);
// Output > 02/07/2021 00:55:06
String longStringDate, shortStringDate;
string longStringTime, shortStringTime;
longStringDate = exampleDate.ToLongDateString();
Console.WriteLine(longStringDate);
// Output > viernes, 2 de julio de 2021
shortStringDate = exampleDate.ToShortDateString();
Console.WriteLine(shortStringDate);
// Output > 02/07/2021
longStringTime = exampleDate.ToLongTimeString();
Console.WriteLine(longStringTime);
// Output > 00:55:06
shortStringTime = exampleDate.ToShortTimeString();
Console.WriteLine(shortStringTime);
// Output > 00:55
IsLeapYear(int year), DaysInMonth(int year, int month)
Estos dos métodos de la clase DateTime nos ayudan a identificar si un año es bisiesto (es decir, si tiene 366 días) y los días que tiene un mes de un año en específico.
bool isLeap = DateTime.IsLeapYear(2020);
int daysInMonth = DateTime.DaysInMonth(2020, 2);
Console.WriteLine("¿El 2020 es año bisiesto?: " + isLeap);
// Output > ¿El 2020 es año bisiesto?: True
Console.WriteLine("El mes 02 del año 2020 tiene " + daysInMonth + " días.");
// Output > El mes 02 del año 2020 tiene 29 días.
TryParse(string dateString, out DateTime dateConvert), Parse(string dateString)
Estos dos métodos nos ayudan a convertir un texto a fecha. Ambos reciben un string de una fecha en un formato cualquiera, y los dos tratarán de convertir el texto a DateTime. La diferencia entre ambos es que, si tratas de convertir un texto con formato incorrecto a fecha, TryParse te devolverá una variable booleana donde te indicará que no se pudo convertir el texto enviado. Sin embargo, Parse, no validará si el formato es correcto, por lo tanto, si envías un texto erróneo, tu programa se caerá. Mi recomendación es que siempre traten de usar TryParse.
Tener en cuenta también que el segundo parámetro de TryParse tiene una palabrita que he marcado en verde: «out«. Esta palabra indica que el segundo parámetro es de salida, por lo tanto, debemos enviarle una variable vacía, para que el método (en este caso TryParse) lo llene con algún dato. Aparte de out, hay otros tipos de parámetros que estudiaremos más adelante.
Por último, si la conversión de string a DateTime es errónea, el parámetro out dateConvert, será llenado, pero con los valores predeterminados de una fecha vacía, como esta: 01/01/0001 00:00:00
DateTime outConvert;
bool isDate = DateTime.TryParse("01/06/13", out outConvert);
Console.WriteLine("¿Se puede convertir 01/06/13 a DateTime?: " + isDate);
// Output > ¿Se puede convertir 01/06/13 a DateTime?: True
bool isDateTwo = DateTime.TryParse("01/06/2013 12.32", out outConvert);
Console.WriteLine("¿Se puede convertir 01/06/2013 12.32 a DateTime?: " + isDateTwo);
// Output > ¿Se puede convertir 01/06/2013 12.32 a DateTime?: False
bool isDateThree = DateTime.TryParse("1 de junio de 2013", out outConvert);
Console.WriteLine("¿Se puede convertir 1 de junio de 2013 a DateTime?: " + isDateThree);
// Output > ¿Se puede convertir 1 de junio de 2013 a DateTime?: True
DateTime exampleDate = DateTime.Parse("1 de junio de 2013");
Console.WriteLine(exampleDate);
// Output > 01/06/2013 00:00:00
También podemos crear una variable de tipo fecha usando el constructor de la clase DateTime. ¿Qué es un constructor? Es un método que se ejecuta automáticamente cada vez que creamos una instancia de la clase y la utilizamos. No te preocupes, que este tema también lo veremos a detalle más adelante, por ahora te dejo el ejemplo de como usar el constructor para crear una fecha.
DateTime exampleDateTwo = new DateTime(2021, 5, 28);
Console.WriteLine(exampleDateTwo);
// Output > 28/05/2021 00:00:00
DateTime exampleDateThree = new DateTime(2021, 4, 15, 18, 30, 00);
Console.WriteLine(exampleDateThree);
// Output > 15/04/2021 18:30:00
Equals (DateTime value1, DateTime value2), Compare (DateTime value1, DateTime value2)
Con ambos métodos podemos comparar fechas, la única diferencia entre ambos es que equals te devuelve verdadero o falso si son iguales o diferentes respectivamente, mientras que compare, te devuelve -1 si la primera fecha es menor que la segunda, 0 si ambas fechas son iguales, y 1 si la primera fecha es mayor que la segunda.
DateTime dtExample = DateTime.Now;
DateTime dtExampleTwo = DateTime.UtcNow;
DateTime dtExampleThree = dtExample;
bool isEqual = DateTime.Equals(dtExample,dtExampleTwo);
Console.WriteLine("¿Las fechas " + dtExample + " y " + dtExampleTwo + " son iguales?:" + isEqual);
// Output > ¿Las fechas 02/07/2021 04:19:31 y 02/07/2021 09:19:31 son iguales?:False
bool isEqualTwo = DateTime.Equals(dtExample, dtExampleThree);
Console.WriteLine("¿Las fechas " + dtExample + " y " + dtExampleThree + " son iguales?:" + isEqualTwo);
// Output > ¿Las fechas 02/07/2021 04:19:31 y 02/07/2021 04:19:31 son iguales?:True
/* Usando Compare */
dtExampleTwo = DateTime.Now.AddYears(1);
DateTime dtExampleFour = DateTime.Now.AddYears(-1);
int valueComparissonOne;
int valueComparissonTwo;
int valueComparissonThree;
// -1 Primera fecha es menor que la segunda
// 0 Ambas fechas son iguales
// 1 Primera fecha es mayor que la segunda.
valueComparissonOne = DateTime.Compare(dtExample, dtExampleFour);
Console.WriteLine(dtExample + " es mayor que " + dtExampleFour + ". Compare result: " + valueComparissonOne);
// Output > 02/07/2021 04:33:58 es mayor que 02/07/2020 04:33:58. Compare result: 1
valueComparissonTwo = DateTime.Compare(dtExample, dtExampleThree);
Console.WriteLine(dtExample + " es igual que " + dtExampleThree + ". Compare result: " + valueComparissonTwo);
// Output > 02/07/2021 04:33:58 es igual que 02/07/2021 04:33:58. Compare result: 0
valueComparissonThree = DateTime.Compare(dtExample, dtExampleTwo);
Console.WriteLine(dtExample + " es menor que " + dtExampleTwo + ". Compare result: " + valueComparissonThree);
// Output > 02/07/2021 04:33:58 es menor que 02/07/2022 04:33:58. Compare result: -1
Subtract (DateTime value)
Con este método podemos restar dos fechas y el resultado se debe almacenar en una variable de tipo TimeSpan. TimeSpan es una tipo de variable y clase que representa el intervalo de tiempo entre dos fechas. Así mismo, también podemos usar el signo de resta «-» (guion en medio) para realizar la resta entre dos fechas.
DateTime exampleDate = DateTime.Now;
DateTime exampleDateTwo = DateTime.Now.AddDays(10);
TimeSpan diffOne = exampleDate.Subtract(exampleDateTwo);
Console.WriteLine(diffOne);
// Output > -10.00:00:00.0009099
Console.WriteLine("Diferencia de días: " + diffOne.Days);
// Output > Diferencia de días: -10
Console.WriteLine("Diferencia de horas: " + diffOne.Hours);
// Output > Diferencia de horas: 0
Propiedades de la clase DateTime
Las propiedades de una clase son elementos informativos que podemos usar a lo largo de nuestro código, cuando hagamos uso de la clase en cuestión. Por ejemplo, una propiedad de la clase Math es el valor PI, el cual podemos usar para hallar el área de un círculo. Mientras que las propiedades de la clase DateTime, son todas las que he listado a continuación. Sé que el concepto de la propiedad de una clase es más amplio, pero eso lo veremos más adelante.
DateTime dtNow = DateTime.Now; // Obtiene la fecha y hora del momento.
Console.WriteLine(dtNow);
// Output > 03/07/2021 04:11:55
DateTime dtToday = DateTime.Today; // Obtiene solo la fecha del momento.
Console.WriteLine(dtToday);
// Output > 03/07/2021 00:00:00
DateTime dtDate = dtNow.Date; // Obtiene solo la fecha de una variable DateTime.
Console.WriteLine (dtDate);
// Output > 03/07/2021 00:00:00
int day = dtNow.Day; // Obtiene el día de una variable DateTime.
int month = dtNow.Month; // Obtiene el mes de una variable DateTime.
int year = dtNow.Year; //Obtiene el año de una variable DateTime.
Console.WriteLine("El día de la fecha " + dtNow + " es: " + day);
Console.WriteLine("El mes de la fecha " + dtNow + " es: " + month);
Console.WriteLine("El año de la fecha " + dtNow + " es: " + year);
// Output > El día de la fecha 03/07/2021 04:11:55 es: 3
// Output > El mes de la fecha 03/07/2021 04:11:55 es: 7
// Output > El año de la fecha 03/07/2021 04:11:55 es: 2021
int hour = dtNow.Hour; // Obtiene la hora de una variable DateTime.
int minute = dtNow.Minute; // Obtiene el minuto de una variable DateTime.
int second = dtNow.Second; // Obtiene el segundo de una variable DateTime.
Console.WriteLine("La hora de la fecha " + dtNow + " es: " + hour);
Console.WriteLine("El minuto de la fecha " + dtNow + " es: " + minute);
Console.WriteLine("El segundo de la fecha " + dtNow + " es: " + second);
// Output > La hora de la fecha 03/07/2021 04:11:55 es: 4
// Output > El minuto de la fecha 03/07/2021 04:11:55 es: 11
// Output > El segundo de la fecha 03/07/2021 04:11:55 es: 55
DayOfWeek dayOfWeek = dtNow.DayOfWeek; // Obtiene el día de la semana de una variable DateTime, aunque en inglés, por lo que no nos sirve de mucho.
Console.WriteLine(dayOfWeek);
// Output > Saturday
int dayOfYear = dtNow.DayOfYear; // Obtiene el día del año de una variable DateTime.
Console.WriteLine("Estamos en el día número " + dayOfYear + " del año " + year);
// Output > Estamos en el día número 184 del año 2021
TimeSpan dtInterval = dtNow.TimeOfDay; // Obtiene la cantidad de tiempo que ha pasado desde la medianoche, en base a la fecha de una variable DateTime.
Console.WriteLine(dtInterval);
// 04:11:55.2033002 (Es decir, ha pasado 4 horas y 11 minutos)
Ya hemos terminado de estudiar los métodos y propiedades más importantes de la clase DateTime, ahora vamos a comenzar a utilizarlos para resolver ejercicios relacionados a fechas.
Ejercicio 1. Crea un programa que genere un cronograma de pagos de una compra y muestre cuánto va a pagar por cada cuota. Considerar 06 cuotas.
using System;
namespace Fechas2
{
class Program
{
static void Main(string[] args)
{
// Declaramos nuestras variables
double price;
const int fee = 6;
double amountFee;
DateTime today = DateTime.Now;
// Solicitamos el precio del producto al usuario
Console.WriteLine("Ingrese precio del producto:");
price = double.Parse(Console.ReadLine());
// Dividimos entre el número de cuotas
amountFee = price / fee;
// Redondeamos
amountFee = Math.Round(amountFee,2);
// Generamos la fecha de nuestras 6 cuotas.
DateTime oneFee = today.AddMonths(1);
DateTime twoFee = today.AddMonths(2);
DateTime threeFee = today.AddMonths(3);
DateTime fourFee = today.AddMonths(4);
DateTime fiveFee = today.AddMonths(5);
DateTime sixFee = today.AddMonths(6);
// Imprimimos
Console.WriteLine("La cuota 1 vence el " + oneFee.ToShortDateString() + " y el monto es: " + amountFee);
Console.WriteLine("La cuota 2 vence el " + twoFee.ToShortDateString() + " y el monto es: " + amountFee);
Console.WriteLine("La cuota 3 vence el " + threeFee.ToShortDateString() + " y el monto es: " + amountFee);
Console.WriteLine("La cuota 4 vence el " + fourFee.ToShortDateString() + " y el monto es: " + amountFee);
Console.WriteLine("La cuota 5 vence el " + fiveFee.ToShortDateString() + " y el monto es: " + amountFee);
Console.WriteLine("La cuota 6 vence el " + sixFee.ToShortDateString() + " y el monto es: " + amountFee);
}
}
}
El resultado de la ejecución sería el siguiente:
Ejercicio 2. Crea un programa que le indique al usuario cuantos días faltan para su próximo cumpleaños.
using System;
namespace Fechas3
{
class Program
{
static void Main(string[] args)
{
// Declaramos nuestras variables.
DateTime nextBirthday;
DateTime today = DateTime.Today;
// Le recomendé usar tryParse para convertir un texto a fecha.
// Sin embargo, Tryparse funciona mejor con el condicional IF
// Pero eso aún no lo hemos estudiado.
// Por lo tanto, por esta vez usaremos Parse.
Console.WriteLine("Ingrese la fecha de su próximo cumpleaños:");
nextBirthday = DateTime.Parse(Console.ReadLine());
TimeSpan diff = nextBirthday.Subtract(today);
// Imprimimos el resultado
Console.WriteLine("Faltan " + diff.Days + " días para tu próximo cumpleaños.");
}
}
}
Ejecutamos, y el resultado sería el siguiente.
¡Ahora te toca a ti!
Ejercicio 3. Crea un programa que solicite al usuario la fecha de vencimiento de un producto y le indique cuantos días le faltan para que alcance dicha fecha.
Ejercicio 4. Crea un programa que solicite al usuario un año y le indique si ese año fue bisiesto.
Espero que el contenido de esta clase te haya servido de mucho, y si aún tienes dudas, o algo no está claro, déjanos tu comentario para tenerlo en cuenta y explayarnos un poco más (o corregir) en caso sea necesario.
Nos sería de mucha ayuda que compartas el contenido si te ha gustado y te invitamos a seguirnos en nuestras redes sociales de Clase13, estamos en Facebook, Instagram y Twitter como @Clase13lat, de esa manera te enterarás de las últimas novedades de manera rápida. También te invito a seguirme en Instagram como @rodolfopenia donde estaré subiendo contenido adicional para complementar la clase.