Skip to content

System.TimeZoneInfo F# snippets #7898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
module program

open System
open System.Globalization

let createCustomTimeZone () =
// <Snippet1>
// Create alternate Central Standard Time to include historical time zone information
let delta = TimeSpan(1, 0, 0)
let adjustmentList = ResizeArray()

// Define end rule (for 1976-2006)
let transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 10, 5, DayOfWeek.Sunday)
// Define rule (1976-1986)
let transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday)
TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(DateTime(1976, 1, 1), DateTime(1986, 12, 31), delta, transitionRuleStart, transitionRuleEnd)
|> adjustmentList.Add
// Define rule (1987-2006)
let transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 04, 01, DayOfWeek.Sunday)
TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(DateTime(1987, 1, 1), DateTime(2006, 12, 31), delta, transitionRuleStart, transitionRuleEnd)
|> adjustmentList.Add
// Define rule (2007- )
let transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 03, 02, DayOfWeek.Sunday)
let transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 11, 01, DayOfWeek.Sunday)
TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(DateTime(2007, 01, 01), DateTime.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd)
|> adjustmentList.Add

// Create custom U.S. Central Standard Time zone
TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", TimeSpan(-6, 0, 0),
"(GMT-06:00) Central Time (US Only)", "Central Standard Time",
"Central Daylight Time", adjustmentList.ToArray())
// </Snippet1>

let compareRulesForEquality () =
// <Snippet2>
// Get CST, Canadian CST, and Mexican CST adjustment rules
let usCstAdjustments =
let timeZoneName = "Central Standard Time"
try
TimeZoneInfo.FindSystemTimeZoneById(timeZoneName).GetAdjustmentRules()
with
| :? TimeZoneNotFoundException ->
printfn $"The {timeZoneName} time zone is not defined in the registry."
null
| :? InvalidTimeZoneException ->
printfn $"Data for the {timeZoneName} time zone is invalid."
null
let canCstAdjustments =
let timeZoneName = "Canada Central Standard Time"
try
TimeZoneInfo.FindSystemTimeZoneById(timeZoneName).GetAdjustmentRules()
with
| :? TimeZoneNotFoundException ->
printfn $"The {timeZoneName} time zone is not defined in the registry."
null
| :? InvalidTimeZoneException ->
printfn $"Data for the {timeZoneName} time zone is invalid."
null
let mexCstAdjustments =
let timeZoneName = "Central Standard Time (Mexico)"
try
TimeZoneInfo.FindSystemTimeZoneById(timeZoneName).GetAdjustmentRules()
with
| :? TimeZoneNotFoundException ->
printfn $"The {timeZoneName} time zone is not defined in the registry."
null
| :? InvalidTimeZoneException ->
printfn $"Data for the {timeZoneName} time zone is invalid."
null
// Determine if CST and other time zones have the same rules
for rule in usCstAdjustments do
printfn $"Comparing Central Standard Time rule for {rule.DateStart:d} to {rule.DateEnd:d} with:"
// Compare with Canada Central Standard Time
if canCstAdjustments.Length = 0 then
printfn " Canada Central Standard Time has no adjustment rules."
else
for canRule in canCstAdjustments do
printfn $""" Canadian CST for {canRule.DateStart:d} to {canRule.DateEnd:d}: {if rule.Equals canRule then "Equal" else "Not Equal"}"""

// Compare with Mexico Central Standard Time
if mexCstAdjustments.Length = 0 then
printfn " Mexican Central Standard Time has no adjustment rules."
else
for mexRule in mexCstAdjustments do
printfn $""" Mexican CST for {mexRule.DateStart:d} to {mexRule.DateEnd:d}: {if rule.Equals mexRule then "Equal" else "Not Equal"}"""
// This code displays the following output to the console:
//
// Comparing Central Standard Time rule for 1/1/0001 to 12/31/9999 with:
// Canada Central Standard Time has no adjustment rules.
// Mexican CST for 1/1/0001 to 12/31/9999: Equal
// </Snippet2>

// <Snippet3>
type WeekOfMonth =
| First = 1
| Second = 2
| Third = 3
| Fourth = 4
| Last = 5

let showStartAndEndDates () =
// Get all time zones from system
let timeZones = TimeZoneInfo.GetSystemTimeZones()
let monthNames = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames
// Get each time zone
for timeZone in timeZones do
let adjustments = timeZone.GetAdjustmentRules()
// Display message for time zones with no adjustments
if adjustments.Length = 0 then
printfn $"{timeZone.StandardName} has no adjustment rules"
else
// Handle time zones with 1 or 2+ adjustments differently
let mutable ctr = 0
let showCount, spacer =
if adjustments.Length > 1 then
true, " "
else
false, ""
printfn $"{timeZone.StandardName} Adjustment rules"

// Iterate adjustment rules
for adjustment in adjustments do
if showCount then
printfn $" Adjustment rule #{ctr + 1}"
ctr <- ctr + 1
// Display general adjustment information
printfn $"{spacer} Start Date: {adjustment.DateStart:D}"
printfn $"{spacer} End Date: {adjustment.DateEnd:D}"
printfn $"{spacer} Time Change: {adjustment.DaylightDelta.Hours}:{adjustment.DaylightDelta.Minutes:D2} hours"
// Get transition start information
let transitionStart = adjustment.DaylightTransitionStart
printf $"{spacer} Annual Start: "
if transitionStart.IsFixedDateRule then
printfn $"On {monthNames[transitionStart.Month - 1]} {transitionStart.Day} at {transitionStart.TimeOfDay:t}"
else
printfn $"The {transitionStart.Week |> enum<WeekOfMonth>} {transitionStart.DayOfWeek} of {monthNames[transitionStart.Month - 1]} at {transitionStart.TimeOfDay:t}"
// Get transition end information
let transitionEnd = adjustment.DaylightTransitionEnd
printf $"{spacer} Annual End: "
if transitionEnd.IsFixedDateRule then
printfn $"On {monthNames[transitionEnd.Month - 1]} {transitionEnd.Day} at {transitionEnd.TimeOfDay:t}"
else
printfn $"The {enum<WeekOfMonth> transitionEnd.Week} {transitionEnd.DayOfWeek} of {monthNames[transitionEnd.Month - 1]} at {transitionEnd.TimeOfDay:t}"
Console.WriteLine()
// </Snippet3>
createCustomTimeZone () |> ignore
compareRulesForEquality ()
showStartAndEndDates ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="System.TimeZone2.AdjustmentRule.Class.fs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module ShowTimeZoneNames1

// <Snippet2>
open System

let localZone = TimeZoneInfo.Local
printfn $"Local Time Zone ID: {localZone.Id}"
printfn $" Display Name is: {localZone.DisplayName}."
printfn $" Standard name is: {localZone.StandardName}."
printfn $" Daylight saving name is: {localZone.DaylightName}."
// The example displays output like the following:
// Local Time Zone ID: Pacific Standard Time
// Display Name is: (UTC-08:00) Pacific Time (US & Canada).
// Standard name is: Pacific Standard Time.
// Daylight saving name is: Pacific Daylight Time.
// </Snippet2>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module TimeZone2

open System

do
// <Snippet1>
let localZone = TimeZoneInfo.Local
printfn $"""The {localZone.DisplayName} time zone is {abs localZone.BaseUtcOffset.Hours}:{abs localZone.BaseUtcOffset.Minutes} {if localZone.BaseUtcOffset >= TimeSpan.Zero then "later" else "earlier"} than Coordinated Universal Time."""
// </Snippet1>

do
let localZone = TimeZoneInfo.Local
printfn $"Local Time Zone ID: {localZone.Id}"
printfn $" Display Name is: {localZone.DisplayName}."
printfn $" Standard name is: {localZone.StandardName}."
printfn $" Daylight saving name is: {localZone.DaylightName}."

do
// <Snippet3>
let universalZone = TimeZoneInfo.Utc
printfn $"The universal time zone is {universalZone.DisplayName}."
printfn $"Its standard name is {universalZone.StandardName}."
printfn $"Its daylight savings name is {universalZone.DaylightName}."
// </Snippet3>

do
// <Snippet4>
let zones = TimeZoneInfo.GetSystemTimeZones()
for zone in zones do
if not zone.SupportsDaylightSavingTime then
Console.WriteLine zone.DisplayName
// </Snippet4>

do
// <Snippet5>
let zones = TimeZoneInfo.GetSystemTimeZones()
printfn $"The local system has the following {zones.Count} time zones"
for zone in zones do
printfn $"{zone.Id}"
// </Snippet5>

do
// <Snippet7>
let thisTimeZone = TimeZoneInfo.Local
let zone1 = TimeZoneInfo.FindSystemTimeZoneById "Pacific Standard Time"
let zone2 = TimeZoneInfo.FindSystemTimeZoneById "Eastern Standard Time"
printfn $"{thisTimeZone.Equals zone1}"
printfn $"{thisTimeZone.Equals zone2}"
// </Snippet7>

do
// <Snippet8>
// Specify DateTimeKind in Date constructor
let baseTime = DateTime(2007, 11, 4, 0, 59, 00, DateTimeKind.Unspecified)

// Get Pacific Standard Time zone
let pstZone = TimeZoneInfo.FindSystemTimeZoneById "Pacific Standard Time"

// List possible ambiguous times for 63-minute interval, from 12:59 AM to 2:01 AM
for i = 0 to 62 do
// Because of assignment, newTime.Kind is also DateTimeKind.Unspecified
let newTime = baseTime.AddMinutes i
printfn $"{newTime} is ambiguous: {pstZone.IsAmbiguousTime newTime}"
// </Snippet8>

do
// <Snippet9>
// Specify DateTimeKind in Date constructor
let baseTime = DateTime(2007, 3, 11, 1, 59, 0, DateTimeKind.Unspecified)

// Get Pacific Standard Time zone
let pstZone = TimeZoneInfo.FindSystemTimeZoneById "Pacific Standard Time"

// List possible invalid times for a 63-minute interval, from 1:59 AM to 3:01 AM
for i = 0 to 62 do
// Because of assignment, newTime.Kind is also DateTimeKind.Unspecified
let newTime = baseTime.AddMinutes i
printfn $"{newTime} is invalid: {pstZone.IsInvalidTime newTime}"
// </Snippet9>
12 changes: 12 additions & 0 deletions snippets/fsharp/System/TimeZoneInfo/BaseUtcOffset/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="TimeZone2_Examples.fs" />
<Compile Include="ShowTimeZoneNames1.fs" />
<Compile Include="getsystemtimezones1.fs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module getsystemtimezones1

// <Snippet6>
open System
open System.Globalization
open System.IO
open System.Collections.ObjectModel

[<EntryPoint>]
let main _ =
let OUTPUTFILENAME = @"C:\Temp\TimeZoneInfo.txt"

let dateFormats = CultureInfo.CurrentCulture.DateTimeFormat
let timeZones = TimeZoneInfo.GetSystemTimeZones()
use sw = new StreamWriter(OUTPUTFILENAME, false)

for timeZone in timeZones do
let hasDST = timeZone.SupportsDaylightSavingTime
let offsetFromUtc = timeZone.BaseUtcOffset

sw.WriteLine $"ID: {timeZone.Id}"
sw.WriteLine $" Display Name: {timeZone.DisplayName, 40}"
sw.WriteLine $" Standard Name: {timeZone.StandardName, 39}"
sw.Write $" Daylight Name: {timeZone.DaylightName, 39}"
sw.Write(if hasDST then " ***Has " else " ***Does Not Have ")
sw.WriteLine "Daylight Saving Time***"
let offsetString = $"{offsetFromUtc.Hours} hours, {offsetFromUtc.Minutes} minutes"
sw.WriteLine $" Offset from UTC: {offsetString, 40}"
let adjustRules = timeZone.GetAdjustmentRules()
sw.WriteLine $" Number of adjustment rules: {adjustRules.Length, 26}"
if adjustRules.Length > 0 then
sw.WriteLine " Adjustment Rules:"
for rule in adjustRules do
let transTimeStart = rule.DaylightTransitionStart
let transTimeEnd = rule.DaylightTransitionEnd

sw.WriteLine $" From {rule.DateStart} to {rule.DateEnd}"
sw.WriteLine $" Delta: {rule.DaylightDelta}"
if not transTimeStart.IsFixedDateRule then
sw.WriteLine $" Begins at {transTimeStart.TimeOfDay:t} on {transTimeStart.DayOfWeek} of week {transTimeStart.Week} of {dateFormats.MonthNames[transTimeStart.Month - 1]}"
sw.WriteLine $" Ends at {transTimeEnd.TimeOfDay:t} on {transTimeEnd.DayOfWeek} of week {transTimeEnd.Week} of {dateFormats.MonthNames[transTimeEnd.Month - 1]}"
else
sw.WriteLine $" Begins at {transTimeStart.TimeOfDay:t} on {transTimeStart.Day} {dateFormats.MonthNames[transTimeStart.Month - 1]}"
sw.WriteLine $" Ends at {transTimeEnd.TimeOfDay:t} on {transTimeEnd.Day} {dateFormats.MonthNames[transTimeEnd.Month - 1]}"
0
// </Snippet6>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module program

// <Snippet1>
open System

let cst = TimeZoneInfo.FindSystemTimeZoneById "Central Standard Time"
let local = TimeZoneInfo.Local
printfn $"{TimeZoneInfo.ConvertTime(DateTime.Now, local, cst)}"

TimeZoneInfo.ClearCachedData()
try
printfn $"{TimeZoneInfo.ConvertTime(DateTime.Now, local, cst)}"
with :? ArgumentException as e ->
printfn $"{e.GetType().Name}\n {e.Message}"
// </Snippet1>
10 changes: 10 additions & 0 deletions snippets/fsharp/System/TimeZoneInfo/ClearCachedData/fs.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="System.TimeZone2.BestPractices.fs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module TimeZone2Concepts

open System

do
// <Snippet8>
let timeUtc = DateTime.UtcNow
try
let cstZone = TimeZoneInfo.FindSystemTimeZoneById "Central Standard Time"
let cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
printfn $"The date and time are {cstTime} {if cstZone.IsDaylightSavingTime cstTime then cstZone.DaylightName else cstZone.StandardName}."
with
| :? TimeZoneNotFoundException ->
printfn "The registry does not define the Central Standard Time zone."
| :? InvalidTimeZoneException ->
printfn "Registry data on the Central Standard Time zone has been corrupted."
// </Snippet8>

do
// <Snippet9>
let hwTime = DateTime(2007, 02, 01, 08, 00, 00)
try
let hwZone = TimeZoneInfo.FindSystemTimeZoneById "Hawaiian Standard Time"
printfn $"{hwTime} {if hwZone.IsDaylightSavingTime hwTime then hwZone.DaylightName else hwZone.StandardName} is {TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local)} local time."
with
| :? TimeZoneNotFoundException ->
printfn "The registry does not define the Hawaiian Standard Time zone."
| :? InvalidTimeZoneException ->
printfn "Registry data on the Hawaiian Standard Time zone has been corrupted."
// </Snippet9>
Loading