Uso de las estructuras DateOnly y TimeOnly
Las estructuras DateOnly y TimeOnly se incluyeron por primera vez con .NET 6 y representan una fecha específica o la hora del día, respectivamente. Antes de .NET 6, y siempre en .NET Framework, los desarrolladores usaban el tipo DateTime (o alguna otra alternativa) para representar una de las siguientes opciones:
- Una fecha y hora completas.
- Una fecha, sin tener en cuenta la hora.
- Una hora, sin tener en cuenta la fecha.
DateOnly
y TimeOnly
son tipos que representan esas partes concretas de un tipo DateTime
.
Estructura DateOnly
La estructura DateOnly representa una fecha específica, sin hora. Como no tiene ningún componente de hora, representa una fecha desde el inicio hasta el final del día. Esta estructura es ideal para almacenar fechas específicas, como una fecha de nacimiento, de aniversario o fechas relacionadas con la empresa.
Aunque puede usar DateTime
y omitir el componente de hora, hay algunas ventajas al usar DateOnly
en vez de DateTime
:
La estructura
DateTime
puede pasar al día anterior o al día siguiente si se desplaza por una zona horaria.DateOnly
no se puede desplazar por una zona horaria y siempre representa la fecha establecida.Serializar una estructura
DateTime
incluye el componente de hora, que puede ocultar la intención de los datos. Además,DateOnly
serializa menos datos.Cuando el código interactúa con una base de datos, como SQL Server, las fechas completas se almacenan generalmente como el tipo de datos
date
, que no incluye una hora.DateOnly
coincide mejor con el tipo de base de datos.
DateOnly
tiene un intervalo entre 0001-01-01 y 9999-12-31, igual que DateTime
. Puede especificar un calendario específico en el constructor DateOnly
. Sin embargo, un objeto DateOnly
siempre representa una fecha en el calendario gregoriano proléptico, independientemente del calendario que se haya utilizado para crearlo. Por ejemplo, puede construir la fecha a partir de un calendario hebreo, pero la fecha se convierte al gregoriano:
var hebrewCalendar = new System.Globalization.HebrewCalendar();
var theDate = new DateOnly(5776, 2, 8, hebrewCalendar); // 8 Cheshvan 5776
Console.WriteLine(theDate);
/* This example produces the following output:
*
* 10/21/2015
*/
Dim hebrewCalendar = New System.Globalization.HebrewCalendar()
Dim theDate = New DateOnly(5776, 2, 8, hebrewCalendar) ' 8 Cheshvan 5776
Console.WriteLine(theDate)
' This example produces the following output
'
' 10/21/2015
Ejemplos de DateOnly
Use los ejemplos siguientes para obtener información sobre DateOnly
:
- Convertir DateTime a DateOnly
- Agregar o restar días, meses, años
- Analizar DateOnly y darle formato
- Comparar DateOnly
Convertir DateTime a DateOnly
Use el método estático DateOnly.FromDateTime para crear un tipo DateOnly
a partir de un tipo DateTime
, como se muestra en el código siguiente:
var today = DateOnly.FromDateTime(DateTime.Now);
Console.WriteLine($"Today is {today}");
/* This example produces output similar to the following:
*
* Today is 12/28/2022
*/
Dim today = DateOnly.FromDateTime(DateTime.Now)
Console.WriteLine($"Today is {today}")
' This example produces output similar to the following
'
' Today is 12/28/2022
Agregar o restar días, meses, años
Hay tres métodos que se usan para ajustar una estructura DateOnly: AddDays, AddMonths y AddYears. Cada método toma un parámetro entero y aumenta la fecha por esa medida. Si se proporciona un número negativo, la fecha se reduce en esa medida. Los métodos devuelven una nueva instancia de DateOnly
, ya que la estructura es inmutable.
var theDate = new DateOnly(2015, 10, 21);
var nextDay = theDate.AddDays(1);
var previousDay = theDate.AddDays(-1);
var decadeLater = theDate.AddYears(10);
var lastMonth = theDate.AddMonths(-1);
Console.WriteLine($"Date: {theDate}");
Console.WriteLine($" Next day: {nextDay}");
Console.WriteLine($" Previous day: {previousDay}");
Console.WriteLine($" Decade later: {decadeLater}");
Console.WriteLine($" Last month: {lastMonth}");
/* This example produces the following output:
*
* Date: 10/21/2015
* Next day: 10/22/2015
* Previous day: 10/20/2015
* Decade later: 10/21/2025
* Last month: 9/21/2015
*/
Dim theDate = New DateOnly(2015, 10, 21)
Dim nextDay = theDate.AddDays(1)
Dim previousDay = theDate.AddDays(-1)
Dim decadeLater = theDate.AddYears(10)
Dim lastMonth = theDate.AddMonths(-1)
Console.WriteLine($"Date: {theDate}")
Console.WriteLine($" Next day: {nextDay}")
Console.WriteLine($" Previous day: {previousDay}")
Console.WriteLine($" Decade later: {decadeLater}")
Console.WriteLine($" Last month: {lastMonth}")
' This example produces the following output
'
' Date: 10/21/2015
' Next day: 10/22/2015
' Previous day: 10/20/2015
' Decade later: 10/21/2025
' Last month: 9/21/2015
Analizar DateOnly y darle formato
DateOnly se puede analizar desde una cadena, al igual que la estructura DateTime. Todos los tokens de análisis basados en fechas de .NET estándar funcionan con DateOnly
. Al convertir un tipo DateOnly
en una cadena, también puede usar patrones de formato estándar basados en fechas de .NET. Para obtener más información sobre el formato de cadenas, vea Cadenas con formato de fecha y hora estándar.
var theDate = DateOnly.ParseExact("21 Oct 2015", "dd MMM yyyy", CultureInfo.InvariantCulture); // Custom format
var theDate2 = DateOnly.Parse("October 21, 2015", CultureInfo.InvariantCulture);
Console.WriteLine(theDate.ToString("m", CultureInfo.InvariantCulture)); // Month day pattern
Console.WriteLine(theDate2.ToString("o", CultureInfo.InvariantCulture)); // ISO 8601 format
Console.WriteLine(theDate2.ToLongDateString());
/* This example produces the following output:
*
* October 21
* 2015-10-21
* Wednesday, October 21, 2015
*/
Dim theDate = DateOnly.ParseExact("21 Oct 2015", "dd MMM yyyy", CultureInfo.InvariantCulture) ' Custom format
Dim theDate2 = DateOnly.Parse("October 21, 2015", CultureInfo.InvariantCulture)
Console.WriteLine(theDate.ToString("m", CultureInfo.InvariantCulture)) ' Month day pattern
Console.WriteLine(theDate2.ToString("o", CultureInfo.InvariantCulture)) ' ISO 8601 format
Console.WriteLine(theDate2.ToLongDateString())
' This example produces the following output
'
' October 21
' 2015-10-21
' Wednesday, October 21, 2015
Comparar DateOnly
DateOnly se puede comparar con otras instancias. Por ejemplo, puede comprobar si una fecha es anterior o posterior a otra, o si una fecha de hoy coincide con una fecha específica.
var theDate = DateOnly.ParseExact("21 Oct 2015", "dd MMM yyyy", CultureInfo.InvariantCulture); // Custom format
var theDate2 = DateOnly.Parse("October 21, 2015", CultureInfo.InvariantCulture);
var dateLater = theDate.AddMonths(6);
var dateBefore = theDate.AddDays(-10);
Console.WriteLine($"Consider {theDate}...");
Console.WriteLine($" Is '{nameof(theDate2)}' equal? {theDate == theDate2}");
Console.WriteLine($" Is {dateLater} after? {dateLater > theDate} ");
Console.WriteLine($" Is {dateLater} before? {dateLater < theDate} ");
Console.WriteLine($" Is {dateBefore} after? {dateBefore > theDate} ");
Console.WriteLine($" Is {dateBefore} before? {dateBefore < theDate} ");
/* This example produces the following output:
*
* Consider 10/21/2015
* Is 'theDate2' equal? True
* Is 4/21/2016 after? True
* Is 4/21/2016 before? False
* Is 10/11/2015 after? False
* Is 10/11/2015 before? True
*/
Dim theDate = DateOnly.ParseExact("21 Oct 2015", "dd MMM yyyy", CultureInfo.InvariantCulture) ' Custom format
Dim theDate2 = DateOnly.Parse("October 21, 2015", CultureInfo.InvariantCulture)
Dim dateLater = theDate.AddMonths(6)
Dim dateBefore = theDate.AddDays(-10)
Console.WriteLine($"Consider {theDate}...")
Console.WriteLine($" Is '{NameOf(theDate2)}' equal? {theDate = theDate2}")
Console.WriteLine($" Is {dateLater} after? {dateLater > theDate} ")
Console.WriteLine($" Is {dateLater} before? {dateLater < theDate} ")
Console.WriteLine($" Is {dateBefore} after? {dateBefore > theDate} ")
Console.WriteLine($" Is {dateBefore} before? {dateBefore < theDate} ")
' This example produces the following output
'
' Consider 10/21/2015
' Is 'theDate2' equal? True
' Is 4/21/2016 after? True
' Is 4/21/2016 before? False
' Is 10/11/2015 after? False
' Is 10/11/2015 before? True
Estructura TimeOnly
La estructura TimeOnly representa un valor de momento del día, como un reloj de alarma diario o la hora de comer cada día. TimeOnly
se limita al intervalo de 00:00:00.0000000 - 23:59:59.9999999, una hora específica del día.
Antes de introducir el tipo TimeOnly
, los programadores solían usar el tipo DateTime o el TimeSpan para representar una hora específica. Pero el uso de estas estructuras para simular una hora sin una fecha puede presentar algunos problemas, que TimeOnly
resuelve:
TimeSpan
representa el tiempo transcurrido, como el tiempo medido con un cronómetro. El rango superior es de más de 29 000 años, y su valor puede ser negativo para indicar que se mueve hacia atrás. UnTimeSpan
negativo no indica una hora específica del día.Si
TimeSpan
se usa como hora del día, existe el riesgo de que se pueda manipular en un valor fuera del día de 24 horas.TimeOnly
no tiene este riesgo. Por ejemplo, si el turno de trabajo de un empleado comienza a las 18:00 y dura 8 horas, la adición de 8 horas a la estructuraTimeOnly
pasa a las 2:00El uso de
DateTime
para una hora del día requiere que se asocie una fecha arbitraria a la hora y se omita más adelante. Es habitual elegirDateTime.MinValue
(0001-01-01-01) como fecha, pero si las horas se restan del valorDateTime
, podría producirse una excepciónOutOfRange
.TimeOnly
no tiene este problema, ya que el tiempo se avanza y retrocede alrededor del marco de tiempo de 24 horas.Serializar una estructura
DateTime
incluye el componente de fecha, que puede ocultar la intención de los datos. Además,TimeOnly
serializa menos datos.
Ejemplos de TimeOnly
Use los ejemplos siguientes para obtener información sobre TimeOnly
:
- Convertir DateTime a TimeOnly
- Agregar o restar tiempo
- Analizar TimeOnly y darle formato
- Trabajar con TimeSpan y DateTime
- Operadores aritméticos y comparación de TimeOnly
Convertir DateTime a TimeOnly
Use el método estático TimeOnly.FromDateTime para crear un tipo TimeOnly
a partir de un tipo DateTime
, como se muestra en el código siguiente:
var now = TimeOnly.FromDateTime(DateTime.Now);
Console.WriteLine($"It is {now} right now");
/* This example produces output similar to the following:
*
* It is 2:01 PM right now
*/
Dim now = TimeOnly.FromDateTime(DateTime.Now)
Console.WriteLine($"It is {now} right now")
' This example produces output similar to the following
'
' It is 2:01 PM right now
Agregar o restar tiempo
Hay tres métodos que se usan para ajustar una estructura TimeOnly: AddHours, AddMinutesy Add. Tanto AddHours
como AddMinutes
toman un parámetro entero y ajustan el valor en consecuencia. Puede usar un valor negativo para restar y un valor positivo que se va a agregar. Los métodos devuelven una nueva instancia de TimeOnly
, ya que la estructura es inmutable. El método Add
toma un parámetro TimeSpan y agrega o resta el valor de TimeOnly
.
Dado que TimeOnly
solo representa un período de 24 horas, se desplaza hacia delante o hacia atrás de la forma correspondiente al sumar los valores suministrados a esos tres métodos. Por ejemplo, si se utiliza un valor de 01:30:00
para representar la 1:30 AM, y luego agrega -4 a partir de ese periodo, se retrocede hasta 21:30:00
, que son las 9:30 PM. Hay sobrecargas de método para AddHours
, AddMinutes
y Add
que capturan el número de días prorrogados.
var theTime = new TimeOnly(7, 23, 11);
var hourLater = theTime.AddHours(1);
var minutesBefore = theTime.AddMinutes(-12);
var secondsAfter = theTime.Add(TimeSpan.FromSeconds(10));
var daysLater = theTime.Add(new TimeSpan(hours: 21, minutes: 200, seconds: 83), out int wrappedDays);
var daysBehind = theTime.AddHours(-222, out int wrappedDaysFromHours);
Console.WriteLine($"Time: {theTime}");
Console.WriteLine($" Hours later: {hourLater}");
Console.WriteLine($" Minutes before: {minutesBefore}");
Console.WriteLine($" Seconds after: {secondsAfter}");
Console.WriteLine($" {daysLater} is the time, which is {wrappedDays} days later");
Console.WriteLine($" {daysBehind} is the time, which is {wrappedDaysFromHours} days prior");
/* This example produces the following output:
*
* Time: 7:23 AM
* Hours later: 8:23 AM
* Minutes before: 7:11 AM
* Seconds after: 7:23 AM
* 7:44 AM is the time, which is 1 days later
* 1:23 AM is the time, which is -9 days prior
*/
Dim wrappedDays As Integer
Dim wrappedDaysFromHours As Integer
Dim theTime = New TimeOnly(7, 23, 11)
Dim hourLater = theTime.AddHours(1)
Dim minutesBefore = theTime.AddMinutes(-12)
Dim secondsAfter = theTime.Add(TimeSpan.FromSeconds(10))
Dim daysLater = theTime.Add(New TimeSpan(hours:=21, minutes:=200, seconds:=83), wrappedDays)
Dim daysBehind = theTime.AddHours(-222, wrappedDaysFromHours)
Console.WriteLine($"Time: {theTime}")
Console.WriteLine($" Hours later: {hourLater}")
Console.WriteLine($" Minutes before: {minutesBefore}")
Console.WriteLine($" Seconds after: {secondsAfter}")
Console.WriteLine($" {daysLater} is the time, which is {wrappedDays} days later")
Console.WriteLine($" {daysBehind} is the time, which is {wrappedDaysFromHours} days prior")
' This example produces the following output
'
' Time: 7:23 AM
' Hours later: 8:23 AM
' Minutes before: 7:11 AM
' Seconds after: 7:23 AM
' 7:44 AM is the time, which is 1 days later
' 1:23 AM is the time, which is -9 days prior
Analizar TimeOnly y darle formato
TimeOnly se puede analizar desde una cadena, al igual que la estructura DateTime. Todos los tokens de análisis basados en horas de .NET estándar funcionan con TimeOnly
. Al convertir un tipo TimeOnly
en una cadena, también puede usar patrones de formato estándar basados en fechas de .NET. Para obtener más información sobre el formato de cadenas, vea Cadenas con formato de fecha y hora estándar.
var theTime = TimeOnly.ParseExact("5:00 pm", "h:mm tt", CultureInfo.InvariantCulture); // Custom format
var theTime2 = TimeOnly.Parse("17:30:25", CultureInfo.InvariantCulture);
Console.WriteLine(theTime.ToString("o", CultureInfo.InvariantCulture)); // Round-trip pattern.
Console.WriteLine(theTime2.ToString("t", CultureInfo.InvariantCulture)); // Long time format
Console.WriteLine(theTime2.ToLongTimeString());
/* This example produces the following output:
*
* 17:00:00.0000000
* 17:30
* 5:30:25 PM
*/
Dim theTime = TimeOnly.ParseExact("5:00 pm", "h:mm tt", CultureInfo.InvariantCulture) ' Custom format
Dim theTime2 = TimeOnly.Parse("17:30:25", CultureInfo.InvariantCulture)
Console.WriteLine(theTime.ToString("o", CultureInfo.InvariantCulture)) ' Round-trip pattern.
Console.WriteLine(theTime2.ToString("t", CultureInfo.InvariantCulture)) ' Long time format
Console.WriteLine(theTime2.ToLongTimeString())
' This example produces the following output
'
' 17:00:00.0000000
' 17:30
' 5:30:25 PM
Serializar tipos DateOnly y TimeOnly
Con .NET 7 y versiones posteriores, System.Text.Json
admite la serialización y deserialización de tipos DateOnly y TimeOnly. Tenga en cuenta el siguiente objeto:
sealed file record Appointment(
Guid Id,
string Description,
DateOnly Date,
TimeOnly StartTime,
TimeOnly EndTime);
Public NotInheritable Class Appointment
Public Property Id As Guid
Public Property Description As String
Public Property DateValue As DateOnly?
Public Property StartTime As TimeOnly?
Public Property EndTime As TimeOnly?
End Class
En el ejemplo siguiente se serializa un objeto Appointment
, se muestra el código JSON resultante y, luego, se deserializa en una nueva instancia del tipo Appointment
. Por último, las instancias originales y recién deserializadas se comparan para ver si son iguales y los resultados se escriben en la consola:
Appointment originalAppointment = new(
Id: Guid.NewGuid(),
Description: "Take dog to veterinarian.",
Date: new DateOnly(2002, 1, 13),
StartTime: new TimeOnly(5,15),
EndTime: new TimeOnly(5, 45));
string serialized = JsonSerializer.Serialize(originalAppointment);
Console.WriteLine($"Resulting JSON: {serialized}");
Appointment deserializedAppointment =
JsonSerializer.Deserialize<Appointment>(serialized)!;
bool valuesAreTheSame = originalAppointment == deserializedAppointment;
Console.WriteLine($"""
Original record has the same values as the deserialized record: {valuesAreTheSame}
""");
Dim originalAppointment As New Appointment With {
.Id = Guid.NewGuid(),
.Description = "Take dog to veterinarian.",
.DateValue = New DateOnly(2002, 1, 13),
.StartTime = New TimeOnly(5, 3, 1),
.EndTime = New TimeOnly(5, 3, 1)
}
Dim serialized As String = JsonSerializer.Serialize(originalAppointment)
Console.WriteLine($"Resulting JSON: {serialized}")
Dim deserializedAppointment As Appointment =
JsonSerializer.Deserialize(Of Appointment)(serialized)
Dim valuesAreTheSame As Boolean =
(originalAppointment.DateValue = deserializedAppointment.DateValue AndAlso
originalAppointment.StartTime = deserializedAppointment.StartTime AndAlso
originalAppointment.EndTime = deserializedAppointment.EndTime AndAlso
originalAppointment.Id = deserializedAppointment.Id AndAlso
originalAppointment.Description = deserializedAppointment.Description)
Console.WriteLine(
$"Original object has the same values as the deserialized object: {valuesAreTheSame}")
En el código anterior:
- Se crea una instancia de un objeto
Appointment
y se asigna a la variableappointment
. - La instancia
appointment
se serializa en JSON mediante JsonSerializer.Serialize. - El código JSON resultante se escribe en la consola.
- El código JSON se deserializa de nuevo en una nueva instancia del tipo
Appointment
mediante JsonSerializer.Deserialize. - Las instancias originales y recién deserializadas se comparan para ver si son iguales.
- El resultado de la comparación se escribe en la consola.
Para obtener más información, consulte Cómo serializar y deserializar JSON en .NET.
Trabajar con TimeSpan y DateTime
TimeOnly puede crearse a partir de TimeSpan y convertirse en ese mismo valor. Además, TimeOnly
puede utilizarse con DateTime, bien para crear la instancia TimeOnly
, bien para crear una instancia DateTime
siempre que se proporcione una fecha.
En el ejemplo siguiente se crea un objeto TimeOnly
a partir de TimeSpan
y, a continuación, se convierte de nuevo:
// TimeSpan must in the range of 00:00:00.0000000 to 23:59:59.9999999
var theTime = TimeOnly.FromTimeSpan(new TimeSpan(23, 59, 59));
var theTimeSpan = theTime.ToTimeSpan();
Console.WriteLine($"Variable '{nameof(theTime)}' is {theTime}");
Console.WriteLine($"Variable '{nameof(theTimeSpan)}' is {theTimeSpan}");
/* This example produces the following output:
*
* Variable 'theTime' is 11:59 PM
* Variable 'theTimeSpan' is 23:59:59
*/
' TimeSpan must in the range of 00:00:00.0000000 to 23:59:59.9999999
Dim theTime = TimeOnly.FromTimeSpan(New TimeSpan(23, 59, 59))
Dim theTimeSpan = theTime.ToTimeSpan()
Console.WriteLine($"Variable '{NameOf(theTime)}' is {theTime}")
Console.WriteLine($"Variable '{NameOf(theTimeSpan)}' is {theTimeSpan}")
' This example produces the following output
'
' Variable 'theTime' is 11:59 PM
' Variable 'theTimeSpan' is 23:59:59
En el ejemplo siguiente se crea un objeto DateTime
a partir de un objeto TimeOnly
, con una fecha arbitraria elegida:
var theTime = new TimeOnly(11, 25, 46); // 11:25 AM and 46 seconds
var theDate = new DateOnly(2015, 10, 21); // October 21, 2015
var theDateTime = theDate.ToDateTime(theTime);
var reverseTime = TimeOnly.FromDateTime(theDateTime);
Console.WriteLine($"Date only is {theDate}");
Console.WriteLine($"Time only is {theTime}");
Console.WriteLine();
Console.WriteLine($"Combined to a DateTime type, the value is {theDateTime}");
Console.WriteLine($"Converted back from DateTime, the time is {reverseTime}");
/* This example produces the following output:
*
* Date only is 10/21/2015
* Time only is 11:25 AM
*
* Combined to a DateTime type, the value is 10/21/2015 11:25:46 AM
* Converted back from DateTime, the time is 11:25 AM
*/
Dim theTime = New TimeOnly(11, 25, 46) ' 11: 25 PM And 46 seconds
Dim theDate = New DateOnly(2015, 10, 21) ' October 21, 2015
Dim theDateTime = theDate.ToDateTime(theTime)
Dim reverseTime = TimeOnly.FromDateTime(theDateTime)
Console.WriteLine($"Date only is {theDate}")
Console.WriteLine($"Time only is {theTime}")
Console.WriteLine()
Console.WriteLine($"Combined to a DateTime type, the value is {theDateTime}")
Console.WriteLine($"Converted back from DateTime, the time is {reverseTime}")
' This example produces the following output
'
' Date only is 10/21/2015
' Time only is 11:25 AM
'
' Combined to a DateTime type, the value is 10/21/2015 11:25:46 AM
' Converted back from DateTime, the time is 11:25 AM
Operadores aritméticos y comparación de TimeOnly
Se pueden comparar dos instancias TimeOnly entre sí y puede usar el método IsBetween para comprobar si una hora está entre dos otras. Cuando se usa un operador de suma o resta en TimeOnly
, se devuelve TimeSpan, que representa una duración de tiempo.
var start = new TimeOnly(10, 12, 01); // 10:12:01 AM
var end = new TimeOnly(14, 00, 53); // 02:00:53 PM
var outside = start.AddMinutes(-3);
var inside = start.AddMinutes(120);
Console.WriteLine($"Time starts at {start} and ends at {end}");
Console.WriteLine($" Is {outside} between the start and end? {outside.IsBetween(start, end)}");
Console.WriteLine($" Is {inside} between the start and end? {inside.IsBetween(start, end)}");
Console.WriteLine($" Is {start} less than {end}? {start < end}");
Console.WriteLine($" Is {start} greater than {end}? {start > end}");
Console.WriteLine($" Does {start} equal {end}? {start == end}");
Console.WriteLine($" The time between {start} and {end} is {end - start}");
/* This example produces the following output:
*
* Time starts at 10:12 AM and ends at 2:00 PM
* Is 10:09 AM between the start and end? False
* Is 12:12 PM between the start and end? True
* Is 10:12 AM less than 2:00 PM? True
* Is 10:12 AM greater than 2:00 PM? False
* Does 10:12 AM equal 2:00 PM? False
* The time between 10:12 AM and 2:00 PM is 03:48:52
*/
Dim startDate = New TimeOnly(10, 12, 1) ' 10:12:01 AM
Dim endDate = New TimeOnly(14, 0, 53) ' 02:00:53 PM
Dim outside = startDate.AddMinutes(-3)
Dim inside = startDate.AddMinutes(120)
Console.WriteLine($"Time starts at {startDate} and ends at {endDate}")
Console.WriteLine($" Is {outside} between the start and end? {outside.IsBetween(startDate, endDate)}")
Console.WriteLine($" Is {inside} between the start and end? {inside.IsBetween(startDate, endDate)}")
Console.WriteLine($" Is {startDate} less than {endDate}? {startDate < endDate}")
Console.WriteLine($" Is {startDate} greater than {endDate}? {startDate > endDate}")
Console.WriteLine($" Does {startDate} equal {endDate}? {startDate = endDate}")
Console.WriteLine($" The time between {startDate} and {endDate} is {endDate - startDate}")
' This example produces the following output
'
' Time starts at 10:12 AM And ends at 2:00 PM
' Is 10:09 AM between the start And end? False
' Is 12:12 PM between the start And end? True
' Is 10:12 AM less than 2:00 PM? True
' Is 10:12 AM greater than 2:00 PM? False
' Does 10:12 AM equal 2:00 PM? False
' The time between 10:12 AM and 2:00 PM is 03:48:52