Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ items:
href: ../standard/datetime/how-to-use-dateonly-timeonly.md
- name: Perform arithmetic operations
href: ../standard/datetime/performing-arithmetic-operations.md
- name: Use TimeProvider to write predictable code
href: ../standard/datetime/timeprovider-overview.md
- name: "DateTime and DateTimeOffset support in System.Text.Json"
href: ../standard/datetime/system-text-json-support.md
- name: Time zones
Expand Down
4 changes: 2 additions & 2 deletions docs/standard/datetime/choosing-between-datetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Although you could use `DateTime` while ignoring the time component, there are a
For more information about `DateOnly`, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).

> [!IMPORTANT]
> `DateOnly` isn't available in .NET Framework.
> `DateOnly` isn't available for .NET Framework.

## The TimeSpan structure

Expand Down Expand Up @@ -115,7 +115,7 @@ Prior to the `TimeOnly` type being introduced, programmers typically used either
For more information about `TimeOnly`, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).

> [!IMPORTANT]
> `TimeOnly` isn't available in .NET Framework.
> `TimeOnly` isn't available for .NET Framework.

## The TimeZoneInfo class

Expand Down
4 changes: 2 additions & 2 deletions docs/standard/datetime/how-to-use-dateonly-timeonly.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: How to use DateOnly and TimeOnly
description: Learn about the DateOnly and TimeOnly structures in .NET.
ms.date: 01/11/2023
ms.date: 12/05/2024
dev_langs:
- "csharp"
- "vb"
Expand All @@ -22,7 +22,7 @@ The <xref:System.DateOnly> and <xref:System.TimeOnly> structures were introduced
`DateOnly` and `TimeOnly` are types that represent those particular portions of a `DateTime` type.

> [!IMPORTANT]
> <xref:System.DateOnly> and <xref:System.TimeOnly> types aren't available in .NET Framework.
> <xref:System.DateOnly> and <xref:System.TimeOnly> types aren't available for .NET Framework.

## The DateOnly structure

Expand Down
36 changes: 28 additions & 8 deletions docs/standard/datetime/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Learn more about: Dates, times, and time zones"
title: "Dates, times, and time zones"
ms.date: 12/07/2021
ms.date: 12/05/2024
helpviewer_keywords:
- "time zone objects [.NET]"
- "date and time data [.NET]"
Expand All @@ -12,11 +12,9 @@ ms.assetid: 295c16e0-641b-4771-94b3-39c1ffa98c13
---
# Dates, times, and time zones

In addition to the basic <xref:System.DateTime> structure, .NET provides the following classes that support working with time zones:

* <xref:System.TimeZone>
.NET provides types that represent dates, times, and time zones. This article describes those types.

Use this class to work with the system's local time zone and the Coordinated Universal Time (UTC) zone. The functionality of the <xref:System.TimeZone> class is largely superseded by the <xref:System.TimeZoneInfo> class.
In addition to the basic <xref:System.DateTime> structure, .NET provides the following classes that support working with time zones:

* <xref:System.TimeZoneInfo>

Expand All @@ -26,16 +24,38 @@ In addition to the basic <xref:System.DateTime> structure, .NET provides the fol

Use this structure to work with dates and times whose offset (or difference) from UTC is known. The <xref:System.DateTimeOffset> structure combines a date and time value with that time's offset from UTC. Because of its relationship to UTC, an individual date and time value unambiguously identifies a single point in time. This makes a <xref:System.DateTimeOffset> value more portable from one computer to another than a <xref:System.DateTime> value.

Starting with .NET 6, the following types are available:
The following classes to support working with time:

* <xref:System.DateOnly>
* <xref:System.TimeSpan>

Use this structure when working with a value that only represents a date. The date represents the entire day, from the start of the day to the end. `DateOnly` has a range of `0001-01-01` through `9999-12-31`. And, this type represents the month, day, and year combination without a specific time. If you previously used a `DateTime` type in your code to represent a date that disregarded the time, use this type in its place. For more information, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).
Use this structure to represents a time interval, such as an elapsed amount of time or the difference between two dates.

* <xref:System.TimeOnly>

Use this structure to represent a time without a date. The time represents the hours, minutes, and seconds of a non-specific day. `TimeOnly` has a range of `00:00:00.0000000` to `23:59:59.9999999`. This type can be used to replace `DateTime` and `TimeSpan` types in your code when you used those types to represent a time. For more information, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).

> [!IMPORTANT]
> <xref:System.TimeOnly> isn't available for .NET Framework.

* <xref:System.TimeProvider>

This is a base class that provides an abstraction of time. A common way to check the current time is by using `DateTime.UtcNow` or `DateTimeOffset.UtcNow`. However, these types don't provide any control over what's considered "now." Why would you want to control that? Testability. For example, consider you're writing an event tracking application that provides reminders 1 day before the event. The app's logic is to check the event time every hour, and alert the user once it's 24 hours before the event. As you write your tests for the app, you would provide your own type that wraps `DateTimeOffset.UtcNow` to test this logic, but now .NET provides this abstraction class for you.

For more information, see [What is TimeProvider](timeprovider-overview.md).

The `TimeProvider` type is included in .NET.

For .NET Framework and .NET Standard, `TimeProvider` is provided by the [**Microsoft.Bcl.TimeProvider** NuGet package](https://www.nuget.org/packages/Microsoft.Bcl.TimeProvider/).

The following classes to support working with time:

* <xref:System.DateOnly>

Use this structure when working with a value that only represents a date. The date represents the entire day, from the start of the day to the end. `DateOnly` has a range of `0001-01-01` through `9999-12-31`. And, this type represents the month, day, and year combination without a specific time. If you previously used a `DateTime` type in your code to represent a date that disregarded the time, use this type in its place. For more information, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).

> [!IMPORTANT]
> <xref:System.DateOnly> isn't available for .NET Framework.

The next section provides the information that you need to work with time zones and to create time zone-aware applications that can convert dates and times from one time zone to another.

## In this section
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

namespace myproject;

//<CalendarHelper>
public static class CalendarHelper
{
static readonly DateTimeOffset MoonLandingDateTime = new(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset);

public static void SendGreeting(TimeProvider currentTime, string name)
{
DateTimeOffset localTime = currentTime.GetLocalNow();

Console.WriteLine($"Good morning, {name}!");
Console.WriteLine($"The date is {localTime.Date:d} and the day is {localTime.Date.DayOfWeek}.");

if (localTime.Date.Month == MoonLandingDateTime.Date.Month
&& localTime.Date.Day == MoonLandingDateTime.Date.Day)

Console.WriteLine("Did you know that on this day in 1969 humans landed on the Moon?");

Console.WriteLine($"I hope you enjoy your day!");
}
}
//</CalendarHelper>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;

namespace myproject;

//<CustomProvider>
public class MoonLandingTimeProviderPST: TimeProvider
{
// July 20, 1969, at 20:17:40 UTC
private readonly DateTimeOffset _specificDateTime = new(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset);

public override DateTimeOffset GetUtcNow() => _specificDateTime;

public override TimeZoneInfo LocalTimeZone => TimeZoneInfo.FindSystemTimeZoneById("PST");
}
//</CustomProvider>
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using myproject;

Console.WriteLine(@"_./-==--======- getlocal -======--==-\._");

//<GetLocal>
Console.WriteLine($"Local: {TimeProvider.System.GetLocalNow()}");
Console.WriteLine($"Utc: {TimeProvider.System.GetUtcNow()}");

/* This example produces output similar to the following:
*
* Local: 12/5/2024 10:41:14 AM -08:00
* Utc: 12/5/2024 6:41:14 PM +00:00
*/
//</GetLocal>

Console.WriteLine(@"_./-==--======- timestamp -======--==-\._");

//<Timestamp>
long stampStart = TimeProvider.System.GetTimestamp();
Console.WriteLine($"Starting timestamp: {stampStart}");

long stampEnd = TimeProvider.System.GetTimestamp();
Console.WriteLine($"Ending timestamp: {stampEnd}");

Console.WriteLine($"Elapsed time: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd)}");
Console.WriteLine($"Nanoseconds: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd).TotalNanoseconds}");

/* This example produces output similar to the following:
*
* Starting timestamp: 55185546133
* Ending timestamp: 55185549929
* Elapsed time: 00:00:00.0003796
* Nanoseconds: 379600
*/
//</Timestamp>

Console.WriteLine(@"_./-==--======- greeting-normal -======--==-\._");

//<GreetingNormal>
CalendarHelper.SendGreeting(TimeProvider.System, "Eric Solomon");

/* This example produces output similar to the following:
*
* Good morning, Eric Solomon!
* The date is 12/5/2024 and the day is Thursday.
* I hope you enjoy your day!
*/
//</GreetingNormal>

Console.WriteLine(@"_./-==--======- greeting-moon -======--==-\._");

//<GreetingMoon>
CalendarHelper.SendGreeting(new MoonLandingTimeProviderPST(), "Eric Solomon");

/* This example produces output similar to the following:
*
* Good morning, Eric Solomon!
* The date is 7/20/1969 and the day is Sunday.
* Did you know that on this day in 1969 humans landed on the Moon?
* I hope you enjoy your day!
*/
//</GreetingMoon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'<CalendarHelper>
Public Module CalendarHelper

ReadOnly MoonLandingDateTime As DateTimeOffset = #7/20/1969 20:17:40#

Public Sub SendGreeting(currentTime As TimeProvider, name As String)

Dim localTime As DateTimeOffset = currentTime.GetLocalNow()

Console.WriteLine($"Good morning, {name}!")
Console.WriteLine($"The date is {localTime.Date:d} and the day is {localTime.Date.DayOfWeek}.")

If (localTime.Date.Month = MoonLandingDateTime.Date.Month _
And localTime.Date.Day = MoonLandingDateTime.Date.Day) Then

Console.WriteLine("Did you know that on this day in 1969 humans landed on the Moon?")
End If

Console.WriteLine($"I hope you enjoy your day!")

End Sub

End Module
'</CalendarHelper>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'<CustomProvider>
Public Class MoonLandingTimeProviderPST
Inherits TimeProvider

'July 20, 1969, at 20:17:40 UTC
Private ReadOnly _specificDateTime As New DateTimeOffset(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset)

Public Overrides Function GetUtcNow() As DateTimeOffset
Return _specificDateTime
End Function

Public Overrides ReadOnly Property LocalTimeZone As TimeZoneInfo
Get
Return TimeZoneInfo.FindSystemTimeZoneById("PST")
End Get
End Property

End Class
'</CustomProvider>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
Imports System
Imports System.Globalization
Imports System.Text.Json

Module Program
Sub Main(args As String())
Console.WriteLine("_./-==--======- getlocal -======--==-\._")

'<GetLocal>
Console.WriteLine($"Local: {TimeProvider.System.GetLocalNow()}")
Console.WriteLine($"Utc: {TimeProvider.System.GetUtcNow()}")

' This example produces output similar to the following
'
' Local: 12/5/2024 10:41:14 AM -08:00
' Utc: 12/5/2024 6:41:14 PM +00:00

'</GetLocal>

Console.WriteLine("_./-==--======- timestamp -======--==-\._")

'<Timestamp>
Dim stampStart As Long = TimeProvider.System.GetTimestamp()
Console.WriteLine($"Starting timestamp: {stampStart}")

Dim stampEnd As Long = TimeProvider.System.GetTimestamp()
Console.WriteLine($"Ending timestamp: {stampEnd}")

Console.WriteLine($"Elapsed time: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd)}")
Console.WriteLine($"Nanoseconds: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd).TotalNanoseconds}")

' This example produces output similar to the following:
'
' Starting timestamp: 55185546133
' Ending timestamp: 55185549929
' Elapsed time: 00:00:00.0003796
' Nanoseconds: 379600

'</Timestamp>

Console.WriteLine("_./-==--======- greeting-normal -======--==-\._")

'<GreetingNormal>
CalendarHelper.SendGreeting(TimeProvider.System, "Eric Solomon")

' This example produces output similar to the following:
'
' Good morning, Eric Solomon!
' The date is 12/5/2024 and the day is Thursday.
' I hope you enjoy your day!

'</GreetingNormal>

Console.WriteLine("_./-==--======- greeting-moon -======--==-\._")

'<GreetingMoon>
CalendarHelper.SendGreeting(New MoonLandingTimeProviderPST(), "Eric Solomon")

' This example produces output similar to the following:
'
' Good morning, Eric Solomon!
' The date is 7/20/1969 and the day is Sunday.
' Did you know that on this day in 1969 humans landed on the Moon?
' I hope you enjoy your day!

'</GreetingMoon>

End Sub

End Module
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>dateonlytimeonly</RootNamespace>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

</Project>
Loading
Loading