Delen via


De structuren DateOnly en TimeOnly gebruiken

De DateOnly en TimeOnly structuren werden geïntroduceerd met .NET 6 en vertegenwoordigen respectievelijk een specifieke datum of tijd van de dag. Vóór .NET 6 en altijd in .NET Framework gebruikten ontwikkelaars het DateTime type (of een ander alternatief) om een van de volgende opties weer te geven:

  • Een hele datum en tijd.
  • Een datum, waarbij de tijd wordt genegeerd.
  • Een tijd, waarbij de datum wordt genegeerd.

DateOnly en TimeOnly zijn typen die deze specifieke delen van een DateTime type vertegenwoordigen.

Belangrijk

DateOnly en TimeOnly typen zijn niet beschikbaar in .NET Framework.

De DateOnly-structuur

De DateOnly structuur vertegenwoordigt een specifieke datum, zonder tijd. Omdat het geen tijdcomponent heeft, vertegenwoordigt het een datum vanaf het begin van de dag tot het einde van de dag. Deze structuur is ideaal voor het opslaan van specifieke datums, zoals een geboortedatum, een jubileumdatum of zakelijke datums.

Hoewel u het tijdonderdeel kunt negeren DateTime , zijn er enkele voordelen voor het gebruik DateOnlyDateTimevan:

  • De DateTime structuur kan in de vorige of volgende dag worden geïmplementeerd als deze wordt verschoven door een tijdzone. DateOnly kan niet worden verschoven door een tijdzone en vertegenwoordigt altijd de datum die is ingesteld.

  • Het serialiseren van een DateTime structuur omvat het tijdonderdeel, waardoor de intentie van de gegevens mogelijk wordt verborgen. DateOnly Serialiseert ook minder gegevens.

  • Wanneer code communiceert met een database, zoals SQL Server, worden hele datums meestal opgeslagen als het date gegevenstype, dat geen tijd bevat. DateOnly komt beter overeen met het databasetype.

DateOnly heeft een bereik van 0001-01-01 tot en met 9999-12-31, net als DateTime. U kunt een specifieke kalender opgeven in de DateOnly constructor. Een DateOnly object vertegenwoordigt echter altijd een datum in de proleptische Gregoriaanse kalender, ongeacht welke kalender is gebruikt om het te maken. U kunt bijvoorbeeld de datum bouwen vanuit een Hebreeuwse kalender, maar de datum wordt geconverteerd naar Gregoriaanse:

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

DateOnly-voorbeelden

Gebruik de volgende voorbeelden voor meer informatie over DateOnly:

DateTime converteren naar DateOnly

Gebruik de DateOnly.FromDateTime statische methode om een DateOnly type te maken op basis van een DateTime type, zoals wordt weergegeven in de volgende code:

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

Dagen, maanden, jaren optellen of aftrekken

Er zijn drie methoden voor het aanpassen van een DateOnly structuur: AddDays, AddMonthsen AddYears. Elke methode gebruikt een geheel getalparameter en verhoogt de datum door die meting. Als er een negatief getal wordt opgegeven, wordt de datum afgenomen door die meting. De methoden retourneren een nieuw exemplaar van DateOnly, omdat de structuur onveranderbaar is.

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

DateOnly parseren en opmaken

DateOnly kan worden geparseerd uit een tekenreeks, net zoals de DateTime structuur. Alle standaard .NET-datumgebaseerde parseringstokens werken met DateOnly. Wanneer u een DateOnly type converteert naar een tekenreeks, kunt u ook standaard .NET-opmaakpatronen op basis van datums gebruiken. Zie Standaardtekenreeksen voor datum- en tijdnotatie voor meer informatie over het opmaken van tekenreeksen.

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

DateOnly vergelijken

DateOnly kan worden vergeleken met andere exemplaren. U kunt bijvoorbeeld controleren of een datum vóór of na een andere datum valt, of als een datum vandaag overeenkomt met een specifieke datum.

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

De TimeOnly-structuur

De TimeOnly structuur vertegenwoordigt een tijd-van-dag-waarde, zoals een dagelijkse wekker of hoe laat u elke dag luncht. TimeOnlyis beperkt tot het bereik van 00:00:00.0000000 - 23:59:59.999999999, een specifiek tijdstip van de dag.

Voordat het TimeOnly type werd geïntroduceerd, gebruikten programmeurs meestal het DateTime type of het TimeSpan type om een specifieke tijd aan te geven. Het gebruik van deze structuren om een tijd zonder datum te simuleren, kan echter enkele problemen veroorzaken, waardoor TimeOnly het volgende wordt opgelost:

  • TimeSpan vertegenwoordigt verstreken tijd, zoals de tijd die wordt gemeten met een stopwatch. Het bovenste bereik is meer dan 29.000 jaar en de waarde ervan kan negatief zijn om achteruit te gaan in de tijd. Een negatief TimeSpan geeft geen specifiek tijdstip van de dag aan.

  • Als TimeSpan wordt gebruikt als een tijdstip van de dag, is er een risico dat het kan worden gemanipuleerd naar een waarde buiten de 24-uurs dag. TimeOnly heeft dit risico niet. Als de werkdienst van een werknemer bijvoorbeeld begint om 18:00 uur en 8 uur duurt, wordt het toevoegen van 8 uur aan de TimeOnly structuur overgedraaid tot 2:00 uur

  • Als DateTime u een tijd van de dag gebruikt, moet een willekeurige datum worden gekoppeld aan de tijd en later genegeerd. Het is gebruikelijk om (0001-01-01) te kiezen DateTime.MinValue als de datum, maar als uren worden afgetrokken van de DateTime waarde, kan er een OutOfRange uitzondering optreden. TimeOnly heeft dit probleem niet omdat de tijd rond de periode van 24 uur vooruit en achteruit rolt.

  • Het serialiseren van een DateTime structuur omvat het datumonderdeel, waardoor de intentie van de gegevens mogelijk wordt verborgen. TimeOnly Serialiseert ook minder gegevens.

TimeOnly-voorbeelden

Gebruik de volgende voorbeelden voor meer informatie over TimeOnly:

DateTime converteren naar TimeOnly

Gebruik de TimeOnly.FromDateTime statische methode om een TimeOnly type te maken op basis van een DateTime type, zoals wordt weergegeven in de volgende code:

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

Tijd optellen of aftrekken

Er zijn drie methoden voor het aanpassen van een TimeOnly structuur: AddHours, AddMinutesen Add. Zowel AddHours als AddMinutes een geheel getalparameter, en pas de waarde dienovereenkomstig aan. U kunt een negatieve waarde gebruiken om af te trekken en een positieve waarde toe te voegen. De methoden retourneren een nieuw exemplaar van TimeOnly wordt geretourneerd, omdat de structuur onveranderbaar is. De Add methode gebruikt een TimeSpan parameter en telt de waarde van de TimeOnly waarde op of trekt deze af.

Omdat TimeOnly dit slechts een periode van 24 uur vertegenwoordigt, wordt deze naar voren of achteruit gerold wanneer u waarden toevoegt die aan deze drie methoden zijn opgegeven. Als u bijvoorbeeld een waarde van 01:30:00 1:30 uur gebruikt en vervolgens -4 uur uit die periode toevoegt, wordt deze teruggedraaid naar 21:30:00, wat 19:30 uur is. Er zijn overbelastingen van methoden voor AddHours, AddMinutesen Add die het aantal dagen vastleggen dat is overgerold.

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

TimeOnly parseren en opmaken

TimeOnly kan worden geparseerd uit een tekenreeks, net zoals de DateTime structuur. Alle standaard .NET-op tijd gebaseerde parseringstokens werken met TimeOnly. Wanneer u een TimeOnly type converteert naar een tekenreeks, kunt u ook standaard .NET-opmaakpatronen op basis van datums gebruiken. Zie Standaardtekenreeksen voor datum- en tijdnotatie voor meer informatie over het opmaken van tekenreeksen.

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

DateOnly- en TimeOnly-typen serialiseren

Met .NET 7+ System.Text.Json ondersteunt serialiseren en deserialiseren DateOnly en TimeOnly typen. Houd rekening met het volgende object:

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

In het volgende voorbeeld wordt een Appointment object geserialiseerd, wordt de resulterende JSON weergegeven en wordt het vervolgens weer gedeserialiseerd in een nieuw exemplaar van het Appointment type. Ten slotte worden de oorspronkelijke en nieuw gedeserialiseerde exemplaren vergeleken voor gelijkheid en worden de resultaten naar de console geschreven:

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}")

In de voorgaande code:

  • Een Appointment object wordt geïnstantieerd en toegewezen aan de appointment variabele.
  • Het appointment exemplaar wordt geserialiseerd naar JSON met behulp van JsonSerializer.Serialize.
  • De resulterende JSON wordt naar de console geschreven.
  • De JSON wordt gedeserialiseerd in een nieuw exemplaar van het Appointment type met behulp van JsonSerializer.Deserialize.
  • De oorspronkelijke en nieuw gedeserialiseerde instanties worden vergeleken voor gelijkheid.
  • Het resultaat van de vergelijking wordt naar de console geschreven.

Zie JSON serialiseren en deserialiseren in .NET voor meer informatie.

Werken met TimeSpan en DateTime

TimeOnly kan worden gemaakt van en geconverteerd naar een TimeSpan. TimeOnly Kan ook worden gebruikt met een DateTime, ofwel om het TimeOnly exemplaar te maken of om een DateTime exemplaar te maken zolang er een datum is opgegeven.

In het volgende voorbeeld wordt een TimeOnly object gemaakt op basis van een TimeSpanobject en wordt het vervolgens weer geconverteerd:

// 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

In het volgende voorbeeld wordt een DateTimeTimeOnly object gemaakt met een willekeurige datum gekozen:

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

Rekenkundige operatoren en het vergelijken van TimeOnly

Twee TimeOnly exemplaren kunnen met elkaar worden vergeleken en u kunt de IsBetween methode gebruiken om te controleren of een tijd tussen twee andere tijden ligt. Wanneer een operator voor optellen of aftrekken wordt gebruikt op een TimeOnly, wordt een TimeSpan geretourneerde operator, die een duur van de tijd aangeeft.

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