Skip to content

Commit 1165f59

Browse files
committed
Add TimeProvider overview
1 parent 6bdcecb commit 1165f59

File tree

12 files changed

+353
-12
lines changed

12 files changed

+353
-12
lines changed

docs/standard/datetime/choosing-between-datetime.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Although you could use `DateTime` while ignoring the time component, there are a
8080
For more information about `DateOnly`, see [How to use the DateOnly and TimeOnly structures](how-to-use-dateonly-timeonly.md).
8181

8282
> [!IMPORTANT]
83-
> `DateOnly` isn't available in .NET Framework.
83+
> `DateOnly` isn't available for .NET Framework.
8484
8585
## The TimeSpan structure
8686

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

117117
> [!IMPORTANT]
118-
> `TimeOnly` isn't available in .NET Framework.
118+
> `TimeOnly` isn't available for .NET Framework.
119119
120120
## The TimeZoneInfo class
121121

docs/standard/datetime/how-to-use-dateonly-timeonly.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: How to use DateOnly and TimeOnly
33
description: Learn about the DateOnly and TimeOnly structures in .NET.
4-
ms.date: 01/11/2023
4+
ms.date: 12/05/2024
55
dev_langs:
66
- "csharp"
77
- "vb"
@@ -22,7 +22,7 @@ The <xref:System.DateOnly> and <xref:System.TimeOnly> structures were introduced
2222
`DateOnly` and `TimeOnly` are types that represent those particular portions of a `DateTime` type.
2323

2424
> [!IMPORTANT]
25-
> <xref:System.DateOnly> and <xref:System.TimeOnly> types aren't available in .NET Framework.
25+
> <xref:System.DateOnly> and <xref:System.TimeOnly> types aren't available for .NET Framework.
2626
2727
## The DateOnly structure
2828

docs/standard/datetime/index.md

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: "Learn more about: Dates, times, and time zones"
33
title: "Dates, times, and time zones"
4-
ms.date: 12/07/2021
4+
ms.date: 12/05/2024
55
helpviewer_keywords:
66
- "time zone objects [.NET]"
77
- "date and time data [.NET]"
@@ -12,11 +12,9 @@ ms.assetid: 295c16e0-641b-4771-94b3-39c1ffa98c13
1212
---
1313
# Dates, times, and time zones
1414

15-
In addition to the basic <xref:System.DateTime> structure, .NET provides the following classes that support working with time zones:
16-
17-
* <xref:System.TimeZone>
15+
.NET provides types that represent dates, times, and time zones. This article describes those types.
1816

19-
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.
17+
In addition to the basic <xref:System.DateTime> structure, .NET provides the following classes that support working with time zones:
2018

2119
* <xref:System.TimeZoneInfo>
2220

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

2725
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.
2826

29-
Starting with .NET 6, the following types are available:
27+
The following classes to support working with time:
3028

31-
* <xref:System.DateOnly>
29+
* <xref:System.TimeSpan>
3230

33-
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).
31+
Use this structure to represents a time interval, such as an elapsed amount of time or the difference between two dates.
3432

3533
* <xref:System.TimeOnly>
3634

3735
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).
3836

37+
> [!IMPORTANT]
38+
> <xref:System.TimeOnly> isn't available for .NET Framework.
39+
40+
* <xref:System.TimeProvider>
41+
42+
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.
43+
44+
For more information, see [What is TimeProvider](timeprovider-overview.md).
45+
46+
The `TimeProvider` type is included in .NET.
47+
48+
For .NET Framework and .NET Standard, `TimeProvider` is provided by the [**Microsoft.Bcl.TimeProvider** NuGet package](https://www.nuget.org/packages/Microsoft.Bcl.TimeProvider/).
49+
50+
The following classes to support working with time:
51+
52+
* <xref:System.DateOnly>
53+
54+
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).
55+
56+
> [!IMPORTANT]
57+
> <xref:System.DateOnly> isn't available for .NET Framework.
58+
3959
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.
4060

4161
## In this section
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
3+
namespace myproject;
4+
5+
//<CalendarHelper>
6+
public static class CalendarHelper
7+
{
8+
static readonly DateTimeOffset MoonLandingDateTime = new(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset);
9+
10+
public static void SendGreeting(TimeProvider currentTime, string name)
11+
{
12+
DateTimeOffset localTime = currentTime.GetLocalNow();
13+
14+
Console.WriteLine($"Good morning, {name}!");
15+
Console.WriteLine($"The date is {localTime.Date:d} and the day is {localTime.Date.DayOfWeek}.");
16+
17+
if (localTime.Date.Month == MoonLandingDateTime.Date.Month
18+
&& localTime.Date.Day == MoonLandingDateTime.Date.Day)
19+
20+
Console.WriteLine("Did you know that on this day in 1969 humans landed on the Moon?");
21+
22+
Console.WriteLine($"I hope you enjoy your day!");
23+
}
24+
}
25+
//</CalendarHelper>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace myproject;
4+
5+
//<CustomProvider>
6+
public class MoonLandingTimeProviderPST: TimeProvider
7+
{
8+
// July 20, 1969, at 20:17:40 UTC
9+
private readonly DateTimeOffset _specificDateTime = new(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset);
10+
11+
public override DateTimeOffset GetUtcNow() => _specificDateTime;
12+
13+
public override TimeZoneInfo LocalTimeZone => TimeZoneInfo.FindSystemTimeZoneById("PST");
14+
}
15+
//</CustomProvider>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using myproject;
2+
3+
Console.WriteLine(@"_./-==--======- getlocal -======--==-\._");
4+
5+
//<GetLocal>
6+
Console.WriteLine($"Local: {TimeProvider.System.GetLocalNow()}");
7+
Console.WriteLine($"Utc: {TimeProvider.System.GetUtcNow()}");
8+
9+
/* This example produces output similar to the following:
10+
*
11+
* Local: 12/5/2024 10:41:14 AM -08:00
12+
* Utc: 12/5/2024 6:41:14 PM +00:00
13+
*/
14+
//</GetLocal>
15+
16+
Console.WriteLine(@"_./-==--======- timestamp -======--==-\._");
17+
18+
//<Timestamp>
19+
long stampStart = TimeProvider.System.GetTimestamp();
20+
Console.WriteLine($"Starting timestamp: {stampStart}");
21+
22+
long stampEnd = TimeProvider.System.GetTimestamp();
23+
Console.WriteLine($"Ending timestamp: {stampEnd}");
24+
25+
Console.WriteLine($"Elapsed time: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd)}");
26+
Console.WriteLine($"Nanoseconds: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd).TotalNanoseconds}");
27+
28+
/* This example produces output similar to the following:
29+
*
30+
* Starting timestamp: 55185546133
31+
* Ending timestamp: 55185549929
32+
* Elapsed time: 00:00:00.0003796
33+
* Nanoseconds: 379600
34+
*/
35+
//</Timestamp>
36+
37+
Console.WriteLine(@"_./-==--======- greeting-normal -======--==-\._");
38+
39+
//<GreetingNormal>
40+
CalendarHelper.SendGreeting(TimeProvider.System, "Eric Solomon");
41+
42+
/* This example produces output similar to the following:
43+
*
44+
* Good morning, Eric Solomon!
45+
* The date is 12/5/2024 and the day is Thursday.
46+
* I hope you enjoy your day!
47+
*/
48+
//</GreetingNormal>
49+
50+
Console.WriteLine(@"_./-==--======- greeting-moon -======--==-\._");
51+
52+
//<GreetingMoon>
53+
CalendarHelper.SendGreeting(new MoonLandingTimeProviderPST(), "Eric Solomon");
54+
55+
/* This example produces output similar to the following:
56+
*
57+
* Good morning, Eric Solomon!
58+
* The date is 7/20/1969 and the day is Sunday.
59+
* Did you know that on this day in 1969 humans landed on the Moon?
60+
* I hope you enjoy your day!
61+
*/
62+
//</GreetingMoon>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net9.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'<CalendarHelper>
2+
Public Module CalendarHelper
3+
4+
ReadOnly MoonLandingDateTime As DateTimeOffset = #7/20/1969 20:17:40#
5+
6+
Public Sub SendGreeting(currentTime As TimeProvider, name As String)
7+
8+
Dim localTime As DateTimeOffset = currentTime.GetLocalNow()
9+
10+
Console.WriteLine($"Good morning, {name}!")
11+
Console.WriteLine($"The date is {localTime.Date:d} and the day is {localTime.Date.DayOfWeek}.")
12+
13+
If (localTime.Date.Month = MoonLandingDateTime.Date.Month _
14+
And localTime.Date.Day = MoonLandingDateTime.Date.Day) Then
15+
16+
Console.WriteLine("Did you know that on this day in 1969 humans landed on the Moon?")
17+
End If
18+
19+
Console.WriteLine($"I hope you enjoy your day!")
20+
21+
End Sub
22+
23+
End Module
24+
'</CalendarHelper>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'<CustomProvider>
2+
Public Class MoonLandingTimeProviderPST
3+
Inherits TimeProvider
4+
5+
'July 20, 1969, at 20:17:40 UTC
6+
Private ReadOnly _specificDateTime As New DateTimeOffset(1969, 7, 20, 20, 17, 40, TimeZoneInfo.Utc.BaseUtcOffset)
7+
8+
Public Overrides Function GetUtcNow() As DateTimeOffset
9+
Return _specificDateTime
10+
End Function
11+
12+
Public Overrides ReadOnly Property LocalTimeZone As TimeZoneInfo
13+
Get
14+
Return TimeZoneInfo.FindSystemTimeZoneById("PST")
15+
End Get
16+
End Property
17+
18+
End Class
19+
'</CustomProvider>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
Imports System
2+
Imports System.Globalization
3+
Imports System.Text.Json
4+
5+
Module Program
6+
Sub Main(args As String())
7+
Console.WriteLine("_./-==--======- getlocal -======--==-\._")
8+
9+
'<GetLocal>
10+
Console.WriteLine($"Local: {TimeProvider.System.GetLocalNow()}")
11+
Console.WriteLine($"Utc: {TimeProvider.System.GetUtcNow()}")
12+
13+
' This example produces output similar to the following
14+
'
15+
' Local: 12/5/2024 10:41:14 AM -08:00
16+
' Utc: 12/5/2024 6:41:14 PM +00:00
17+
18+
'</GetLocal>
19+
20+
Console.WriteLine("_./-==--======- timestamp -======--==-\._")
21+
22+
'<Timestamp>
23+
Dim stampStart As Long = TimeProvider.System.GetTimestamp()
24+
Console.WriteLine($"Starting timestamp: {stampStart}")
25+
26+
Dim stampEnd As Long = TimeProvider.System.GetTimestamp()
27+
Console.WriteLine($"Ending timestamp: {stampEnd}")
28+
29+
Console.WriteLine($"Elapsed time: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd)}")
30+
Console.WriteLine($"Nanoseconds: {TimeProvider.System.GetElapsedTime(stampStart, stampEnd).TotalNanoseconds}")
31+
32+
' This example produces output similar to the following:
33+
'
34+
' Starting timestamp: 55185546133
35+
' Ending timestamp: 55185549929
36+
' Elapsed time: 00:00:00.0003796
37+
' Nanoseconds: 379600
38+
39+
'</Timestamp>
40+
41+
Console.WriteLine("_./-==--======- greeting-normal -======--==-\._")
42+
43+
'<GreetingNormal>
44+
CalendarHelper.SendGreeting(TimeProvider.System, "Eric Solomon")
45+
46+
' This example produces output similar to the following:
47+
'
48+
' Good morning, Eric Solomon!
49+
' The date is 12/5/2024 and the day is Thursday.
50+
' I hope you enjoy your day!
51+
52+
'</GreetingNormal>
53+
54+
Console.WriteLine("_./-==--======- greeting-moon -======--==-\._")
55+
56+
'<GreetingMoon>
57+
CalendarHelper.SendGreeting(New MoonLandingTimeProviderPST(), "Eric Solomon")
58+
59+
' This example produces output similar to the following:
60+
'
61+
' Good morning, Eric Solomon!
62+
' The date is 7/20/1969 and the day is Sunday.
63+
' Did you know that on this day in 1969 humans landed on the Moon?
64+
' I hope you enjoy your day!
65+
66+
'</GreetingMoon>
67+
68+
End Sub
69+
70+
End Module

0 commit comments

Comments
 (0)