diff --git a/TimeKeeping/DotNetThoughts.TimeKeeping.App/Pages/Timer.razor b/TimeKeeping/DotNetThoughts.TimeKeeping.App/Pages/Timer.razor index b8397d1..21f3c4c 100644 --- a/TimeKeeping/DotNetThoughts.TimeKeeping.App/Pages/Timer.razor +++ b/TimeKeeping/DotNetThoughts.TimeKeeping.App/Pages/Timer.razor @@ -2,31 +2,60 @@ Timing -

System Time

-

@systemTime.ToString("O")

+

UTC Real Time

+

@realTime.ToString("O")

+
- - -

Real Time

-

@realTime.ToString("O")

+
+
+ + + +
+
+ + + +
+

UTC System Time

+

@systemTime.ToString("O")

+ +

Local System Time

+

@localSystemTime.ToString("O")

+ +

+ +

+

@nairobiLocalSystemTime.ToString("O")

@code { private int currentCount = 0; private TimeTravelersClock clock = new TimeTravelersClock(); - private DateTimeOffset systemTime = DateTimeOffset.UtcNow; private DateTimeOffset realTime = DateTimeOffset.UtcNow; + private DateTimeOffset systemTime = DateTimeOffset.UtcNow; + private DateTimeOffset localSystemTime = DateTimeOffset.UtcNow; + private DateTimeOffset nairobiLocalSystemTime = DateTimeOffset.UtcNow; + private string selectedTimeZone = TimeZoneInfo.GetSystemTimeZones().First().Id; System.Threading.Timer? timer; private void UpdateUI() { systemTime = clock.UtcNow(); realTime = DateTimeOffset.UtcNow; + localSystemTime = new LocalDateTime(systemTime.DateTime, TimeZoneInfo.Utc).ToTimeZone(TimeZoneInfo.Local).ToDateTimeOffsetLocal(); + nairobiLocalSystemTime = new LocalDateTime(systemTime.DateTime, TimeZoneInfo.Utc).ToTimeZone(TimeZoneInfo.FindSystemTimeZoneById(selectedTimeZone)).ToDateTimeOffsetLocal(); + } protected override void OnInitialized() { @@ -38,6 +67,11 @@ await InvokeAsync(StateHasChanged); }, null, 0, 10); } + + private void OnTimeZoneChange(ChangeEventArgs args) + { + selectedTimeZone = ((string)args.Value); + } private void AdvanceOneHour() { clock.Advance(TimeSpan.FromHours(1)); @@ -45,11 +79,36 @@ } + private void AdvanceOneDay() + { + clock.Advance(TimeSpan.FromDays(1)); + UpdateUI(); + + } + + private void AdvanceOneWeek() + { + clock.Advance(TimeSpan.FromDays(7)); + UpdateUI(); + + } + private void SubtractOneHour() { clock.Advance(TimeSpan.FromHours(-1)); UpdateUI(); + } + + private void SubtractOneDay() + { + clock.Advance(TimeSpan.FromDays(-1)); + UpdateUI(); + } + private void SubtractOneWeek() + { + clock.Advance(TimeSpan.FromDays(-7)); + UpdateUI(); } private void Freeze() diff --git a/TimeKeeping/DotNetThoughts.TimeKeeping.Tests/LocalDateTimeTests.cs b/TimeKeeping/DotNetThoughts.TimeKeeping.Tests/LocalDateTimeTests.cs index 9cc45b4..22988cb 100644 --- a/TimeKeeping/DotNetThoughts.TimeKeeping.Tests/LocalDateTimeTests.cs +++ b/TimeKeeping/DotNetThoughts.TimeKeeping.Tests/LocalDateTimeTests.cs @@ -12,6 +12,51 @@ public void TestLocalDateTimeOffset() ldt.ToDateTimeOffsetLocal().Should().Be(expectedDateTimeOffset); } + [Fact] + public void ConvertBetweenTimeZones_Utc() + { + var t = new DateTime(2024, 06, 06, 0, 0, 0, DateTimeKind.Unspecified); + var tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + var ldt = new LocalDateTime(t, tz); + var utc = ldt.ToTimeZone(TimeZoneInfo.Utc); + utc.DateTime.Kind.Should().Be(DateTimeKind.Utc); + utc.ToDateTimeOffsetUtc().Should().Be(ldt.ToDateTimeOffsetUtc()); + } + + [Fact] + public void UtcIsLocalUtc() + { + var t = new DateTime(2024, 06, 06, 0, 0, 0, DateTimeKind.Utc); + var tz = TimeZoneInfo.FindSystemTimeZoneById("UTC"); + var ldt = new LocalDateTime(t, tz); + ldt.ToDateTimeOffsetLocal().Should().Be(ldt.ToDateTimeOffsetUtc()); + } + + [Fact] + public void ConvertBetweenTimeZones_Hawaii1() + { + var t = new DateTime(2024, 06, 17, 22, 24, 0, DateTimeKind.Unspecified); + var tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + var ldt = new LocalDateTime(t, tz); + var hawaii = ldt.ToTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")); + hawaii.DateTime.Kind.Should().Be(DateTimeKind.Unspecified); + hawaii.ToDateTimeOffsetUtc().Should().Be(ldt.ToDateTimeOffsetUtc()); + hawaii.ToDateTimeOffsetLocal().ToString("yyyy-MM-ddTHH:mm:ssK").Should().Be("2024-06-17T10:24:00-10:00"); + } + + [Fact] + public void ConvertBetweenTimeZones_Hawaii2() + { + var t = new DateTime(2024, 02, 17, 22, 24, 0, DateTimeKind.Unspecified); + var tz = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time"); + var ldt = new LocalDateTime(t, tz); + var hawaii = ldt.ToTimeZone(TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")); + hawaii.DateTime.Kind.Should().Be(DateTimeKind.Unspecified); + hawaii.ToDateTimeOffsetUtc().Should().Be(ldt.ToDateTimeOffsetUtc()); + hawaii.ToDateTimeOffsetLocal().ToString("yyyy-MM-ddTHH:mm:ssK").Should().Be("2024-02-17T11:24:00-10:00"); + } + + // [Fact] public void TestDateConstructor() { diff --git a/TimeKeeping/DotNetThoughts.TimeKeeping/LocalDateTime.cs b/TimeKeeping/DotNetThoughts.TimeKeeping/LocalDateTime.cs index d46b9fc..cc86d9b 100644 --- a/TimeKeeping/DotNetThoughts.TimeKeeping/LocalDateTime.cs +++ b/TimeKeeping/DotNetThoughts.TimeKeeping/LocalDateTime.cs @@ -34,6 +34,11 @@ public LocalDateTime(DateTime dateTime, TimeZoneInfo timeZoneInfo) public DateTime DateTime { get; } public TimeZoneInfo TimeZoneInfo { get; } + public LocalDateTime ToTimeZone(TimeZoneInfo newTz) + { + return new LocalDateTime(TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo, newTz), newTz); + } + public LocalDateTime ToMidnight() { return new LocalDateTime(DateTime.Date, TimeZoneInfo);