Skip to content

Commit ead3f1a

Browse files
authored
TimeZoneInfo.TransitionTime F# snippets (#7916)
1 parent 3e7d0ac commit ead3f1a

File tree

4 files changed

+249
-0
lines changed

4 files changed

+249
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
module Program
2+
3+
open System
4+
open System.Globalization
5+
6+
let compareForEquality () =
7+
// <Snippet1>
8+
let tt1 = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 02, 00, 00), 11, 03)
9+
let tt2 = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 02, 00, 00), 11, 03)
10+
let tt3 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 02, 00, 00), 10, 05, DayOfWeek.Sunday)
11+
let tz = TimeZoneInfo.Local
12+
printfn $"{tt1.Equals tz}" // Returns False (overload with argument of type Object)
13+
printfn $"{tt1.Equals tt1}" // Returns True (an object always equals itself)
14+
printfn $"{tt1.Equals tt2}" // Returns True (identical property values)
15+
printfn $"{tt1.Equals tt3}" // Returns False (different property values)
16+
// </Snippet1>
17+
18+
let compareTransitionTimesForEquality () =
19+
// <Snippet7>
20+
let tt1 = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 02, 00, 00), 11, 03)
21+
let tt2 = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 02, 00, 00), 11, 03)
22+
let tt3 = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 02, 00, 00), 10, 05, DayOfWeek.Sunday)
23+
printfn $"{tt1.Equals tt1}" // Returns True (an object always equals itself)
24+
printfn $"{tt1.Equals tt2}" // Returns True (identical property values)
25+
printfn $"{tt1.Equals tt3}" // Returns False (different property values)
26+
// </Snippet7>
27+
28+
let createTransitionRules () =
29+
// <Snippet2>
30+
let delta = TimeSpan(1, 0, 0)
31+
let adjustmentList = ResizeArray()
32+
33+
// Define a fictitious new time zone consisting of fixed and floating adjustment rules
34+
// Define fixed rule (for 1900-1955)
35+
let transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 2, 0, 0), 3, 15)
36+
let transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(DateTime(1, 1, 1, 3, 0, 0), 11, 15)
37+
let adjustment =
38+
TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(DateTime(1900, 1, 1), DateTime(1955, 12, 31), delta, transitionRuleStart, transitionRuleEnd)
39+
adjustmentList.Add adjustment
40+
// Define floating rule (for 1956- )
41+
let transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 2, 0, 0), 3, 5, DayOfWeek.Sunday)
42+
let transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(DateTime(1, 1, 1, 3, 0, 0), 10, 4, DayOfWeek.Sunday)
43+
let adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(DateTime(1956, 1, 1), DateTime.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd)
44+
adjustmentList.Add adjustment
45+
46+
// Create fictitious time zone
47+
let imaginaryTZ =
48+
TimeZoneInfo.CreateCustomTimeZone("Fictitious Standard Time", TimeSpan(-9, 0, 0),
49+
"(GMT-09:00) Fictitious Time", "Fictitious Standard Time",
50+
"Fictitious Daylight Time", adjustmentList.ToArray())
51+
// </Snippet2>
52+
()
53+
54+
// <Snippet3>
55+
let getFixedTransitionTimes () =
56+
let timeZones = TimeZoneInfo.GetSystemTimeZones()
57+
let dateInfo = CultureInfo.CurrentCulture.DateTimeFormat
58+
for zone in timeZones do
59+
let adjustmentRules = zone.GetAdjustmentRules()
60+
for adjustmentRule in adjustmentRules do
61+
let daylightStart = adjustmentRule.DaylightTransitionStart
62+
if daylightStart.IsFixedDateRule then
63+
printfn $"For {zone.StandardName}, daylight savings time begins at {daylightStart.TimeOfDay:t} on {dateInfo.GetMonthName daylightStart.Month} {daylightStart.Day} from {adjustmentRule.DateStart:d} to {adjustmentRule.DateEnd:d}."
64+
let daylightEnd = adjustmentRule.DaylightTransitionEnd
65+
if daylightEnd.IsFixedDateRule then
66+
printfn $"For {zone.StandardName}, daylight savings time ends at {daylightEnd.TimeOfDay:t} on {dateInfo.GetMonthName daylightEnd.Month} {daylightEnd.Day} from {adjustmentRule.DateStart:d} to {adjustmentRule.DateEnd:d}."
67+
// </Snippet3>
68+
69+
// <Snippet4>
70+
type WeekOfMonth =
71+
| First = 1
72+
| Second = 2
73+
| Third = 3
74+
| Fourth = 4
75+
| Last = 5
76+
77+
let getFloatingTransitionTimes () =
78+
let timeZones = TimeZoneInfo.GetSystemTimeZones()
79+
for zone in timeZones do
80+
let adjustmentRules = zone.GetAdjustmentRules()
81+
let dateInfo = CultureInfo.CurrentCulture.DateTimeFormat
82+
for adjustmentRule in adjustmentRules do
83+
let daylightStart = adjustmentRule.DaylightTransitionStart
84+
if not daylightStart.IsFixedDateRule then
85+
printfn $"{zone.StandardName}, {adjustmentRule.DateStart:d}-{adjustmentRule.DateEnd:d}: Begins at {daylightStart.TimeOfDay:t} on the {enum<WeekOfMonth> daylightStart.Week} {daylightStart.DayOfWeek} of {dateInfo.GetMonthName daylightStart.Month}."
86+
87+
let daylightEnd = adjustmentRule.DaylightTransitionEnd
88+
if not daylightEnd.IsFixedDateRule then
89+
printfn $"{zone.StandardName}, {adjustmentRule.DateStart:d}-{adjustmentRule.DateEnd:d}: Ends at {daylightEnd.TimeOfDay:t} on the {enum<WeekOfMonth> daylightEnd.Week} {daylightEnd.DayOfWeek} of {dateInfo.GetMonthName daylightEnd.Month}."
90+
// </Snippet4>
91+
92+
module AdditionalExamples =
93+
// <Snippet6>
94+
type WeekOfMonth =
95+
| First = 1
96+
| Second = 2
97+
| Third = 3
98+
| Fourth = 4
99+
| Last = 5
100+
101+
let getAllTransitionTimes () =
102+
let timeZones = TimeZoneInfo.GetSystemTimeZones()
103+
let dateInfo = CultureInfo.CurrentCulture.DateTimeFormat
104+
105+
for zone in timeZones do
106+
printfn $"{zone.StandardName} transition time information:"
107+
let adjustmentRules= zone.GetAdjustmentRules()
108+
109+
// Indicate that time zone has no adjustment rules
110+
if adjustmentRules.Length = 0 then
111+
printfn " No adjustment rules defined."
112+
else
113+
// Iterate adjustment rules
114+
for adjustmentRule in adjustmentRules do
115+
printfn $" Adjustment rule from {adjustmentRule.DateStart:d} to {adjustmentRule.DateEnd:d}:"
116+
117+
// Get start of transition
118+
let daylightStart = adjustmentRule.DaylightTransitionStart
119+
// Display information on fixed date rule
120+
if not daylightStart.IsFixedDateRule then
121+
printfn $" Begins at {daylightStart.TimeOfDay:t} on the {enum<WeekOfMonth> daylightStart.Week} {daylightStart.DayOfWeek} of {dateInfo.GetMonthName daylightStart.Month}."
122+
// Display information on floating date rule
123+
else
124+
printfn $" Begins at {daylightStart.TimeOfDay:t} on the {enum<WeekOfMonth> daylightStart.Week} {daylightStart.DayOfWeek} of {dateInfo.GetMonthName daylightStart.Month}."
125+
126+
// Get end of transition
127+
let daylightEnd = adjustmentRule.DaylightTransitionEnd
128+
// Display information on fixed date rule
129+
if not daylightEnd.IsFixedDateRule then
130+
printfn $" Ends at {daylightEnd.TimeOfDay:t} on the {enum<WeekOfMonth> daylightEnd.Week} {daylightEnd.DayOfWeek} of {dateInfo.GetMonthName daylightEnd.Month}."
131+
// Display information on floating date rule
132+
else
133+
printfn $" Ends at {daylightStart.TimeOfDay:t} on the {enum<WeekOfMonth> daylightStart.Week} {daylightStart.DayOfWeek} of {dateInfo.GetMonthName daylightStart.Month}."
134+
// </Snippet6>
135+
136+
compareForEquality ()
137+
printfn ""
138+
compareTransitionTimesForEquality()
139+
printfn ""
140+
createTransitionRules()
141+
printfn ""
142+
getFixedTransitionTimes ()
143+
printfn ""
144+
getFloatingTransitionTimes ()
145+
printfn ""
146+
AdditionalExamples.getAllTransitionTimes ()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
module example1
2+
3+
// <Snippet5>
4+
open System
5+
open System.Globalization
6+
7+
let displayTransitionInfo (transition: TimeZoneInfo.TransitionTime) year label =
8+
// For non-fixed date rules, get local calendar
9+
let cal = CultureInfo.CurrentCulture.Calendar
10+
// Get first day of week for transition
11+
// For example, the 3rd week starts no earlier than the 15th of the month
12+
let startOfWeek = transition.Week * 7 - 6
13+
// What day of the week does the month start on?
14+
let firstDayOfWeek = cal.GetDayOfWeek(DateTime(year, transition.Month, 1)) |> int
15+
// Determine how much start date has to be adjusted
16+
let changeDayOfWeek = int transition.DayOfWeek
17+
18+
let transitionDay =
19+
if firstDayOfWeek <= changeDayOfWeek then
20+
startOfWeek + (changeDayOfWeek - firstDayOfWeek)
21+
else
22+
startOfWeek + (7 - firstDayOfWeek + changeDayOfWeek)
23+
24+
// Adjust for months with no fifth week
25+
let transitionDay =
26+
if transitionDay > cal.GetDaysInMonth(year, transition.Month) then
27+
transitionDay - 7
28+
else
29+
transitionDay
30+
31+
printfn $" {label} {transition.DayOfWeek}, {DateTime(year, transition.Month, transitionDay):d} at {transition.TimeOfDay:t}"
32+
33+
let getAdjustment (adjustments: TimeZoneInfo.AdjustmentRule seq) year =
34+
adjustments
35+
// Iterate adjustment rules for time zone
36+
// Determine if this adjustment rule covers year desired
37+
|> Seq.tryFind (fun adjustment -> adjustment.DateStart.Year <= year && adjustment.DateEnd >= DateTime year)
38+
|> Option.defaultValue null
39+
40+
let getTransitionTimes year =
41+
// Instantiate DateTimeFormatInfo object for month names
42+
let dateFormat = CultureInfo.CurrentCulture.DateTimeFormat
43+
44+
// Get and iterate time zones on local computer
45+
let timeZones = TimeZoneInfo.GetSystemTimeZones()
46+
for timeZone in timeZones do
47+
printfn $"{timeZone.StandardName}:"
48+
let adjustments = timeZone.GetAdjustmentRules()
49+
let startYear = year
50+
let mutable endYear = startYear
51+
52+
if adjustments.Length = 0 then
53+
printfn " No adjustment rules."
54+
else
55+
let adjustment = getAdjustment adjustments year
56+
if adjustment = null then
57+
Console.WriteLine(" No adjustment rules available for this year.")
58+
else
59+
// Determine if starting transition is fixed
60+
let startTransition = adjustment.DaylightTransitionStart
61+
// Determine if starting transition is fixed and display transition info for year
62+
if startTransition.IsFixedDateRule then
63+
printfn $" Begins on {dateFormat.GetMonthName startTransition.Month} {startTransition.Day} at {startTransition.TimeOfDay:t}"
64+
else
65+
displayTransitionInfo startTransition startYear "Begins on"
66+
67+
// Determine if ending transition is fixed and display transition info for year
68+
let mutable endTransition = adjustment.DaylightTransitionEnd
69+
70+
// Does the transition back occur in an earlier month (i.e.,
71+
// the following year) than the transition to DST? If so, make
72+
// sure we have the right adjustment rule.
73+
if endTransition.Month < startTransition.Month then
74+
endTransition <- (getAdjustment adjustments (year + 1)).DaylightTransitionEnd
75+
endYear <- endYear + 1
76+
77+
if endTransition.IsFixedDateRule then
78+
printfn $" Ends on {dateFormat.GetMonthName endTransition.Month} {endTransition.Day} at {endTransition.TimeOfDay:t}"
79+
else
80+
displayTransitionInfo endTransition endYear "Ends on"
81+
82+
// </Snippet5>
83+
getTransitionTimes 2007
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+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net6.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="example1.fs" />
8+
<Compile Include="System.TimeZone2.TransitionTime.Class.fs" />
9+
</ItemGroup>
10+
</Project>

0 commit comments

Comments
 (0)