diff --git a/docs/en/framework/infrastructure/timing.md b/docs/en/framework/infrastructure/timing.md index 7ddf1b730a..fe8a04d179 100644 --- a/docs/en/framework/infrastructure/timing.md +++ b/docs/en/framework/infrastructure/timing.md @@ -89,6 +89,61 @@ var normalizedDateTime = Clock.Normalize(dateTime) `DisableDateTimeNormalization` attribute can be used to disable the normalization operation for desired classes or properties. +### DateTime Converter Between UTC and User's Time Zone + +#### Convert given UTC to user's time zone. + +`DateTime ConvertTo(DateTime dateTime)` and `DateTimeOffset ConvertTo(DateTimeOffset dateTimeOffset)` methods convert given UTC `DateTime` or `DateTimeOffset` to the user's time zone. + +> If `SupportsMultipleTimezone` is `false` or `dateTime.Kind` is not `Utc` or these is no timezone setting, it returns the given `DateTime` or `DateTimeOffset` without any changes. + +**Example:** + +If user's `TimeZone Setting` is `Europe/Istanbul` + +````csharp +// 2025-03-01T05:30:00Z +var utcTime = new DateTime(2025, 3, 1, 5, 30, 0, DateTimeKind.Utc); + +var userTime = Clock.ConvertTo(utcTime); + +// Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. +userTime.Kind.ShouldBe(DateTimeKind.Unspecified); +userTime.ToString("O").ShouldBe("2025-03-01T08:30:00"); +```` + +````csharp +// 2025-03-01T05:30:00Z +var utcTime = new DateTimeOffset(new DateTime(2025, 3, 1, 5, 30, 0, DateTimeKind.Utc), TimeSpan.Zero); + +var userTime = Clock.ConvertTo(utcTime); + +// Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. +userTime.Offset.ShouldBe(TimeSpan.FromHours(3)); +userTime.ToString("O").ShouldBe("2025-03-01T08:30:00.0000000+03:00"); +```` + +#### Converts given user's DateTime to UTC + +`DateTime ConvertFrom(DateTime dateTime)` method convert given user's `DateTime` to UTC. + +> If `SupportsMultipleTimezone` is `false` or `dateTime.Kind` is `Utc` or these is no timezone setting, it returns the given `DateTime` without any changes. + +**Example:** + +If user's `TimeZone Setting` is `Europe/Istanbul` + +````csharp +// 2025-03-01T05:30:00 +var userTime = new DateTime(2025, 3, 1, 5, 30, 0, DateTimeKind.Unspecified); //Same as Local + +var utcTime = Clock.ConvertFrom(userTime); + +// Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours earlier. +utcTime.Kind.ShouldBe(DateTimeKind.Utc); +utcTime.ToString("O").ShouldBe("2025-03-01T02:30:00.0000000Z"); +```` + ### Other IClock Properties In addition to the `Now`, `IClock` service has the following properties: diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs index c68190b0be..99c48b3373 100644 --- a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Clock.cs @@ -94,19 +94,14 @@ public class Clock : IClock, ITransientDependency public DateTime ConvertFrom(DateTime dateTime) { if (!SupportsMultipleTimezone || + dateTime.Kind == DateTimeKind.Utc || CurrentTimezoneProvider.TimeZone.IsNullOrWhiteSpace()) { return dateTime; } var timezoneInfo = TimezoneProvider.GetTimeZoneInfo(CurrentTimezoneProvider.TimeZone); - var targetDateTime = dateTime; - if (dateTime.Kind == DateTimeKind.Utc) - { - return dateTime; - } - - targetDateTime = DateTime.SpecifyKind(targetDateTime, DateTimeKind.Unspecified); - return TimeZoneInfo.ConvertTimeToUtc(targetDateTime, timezoneInfo); + dateTime = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); + return TimeZoneInfo.ConvertTimeToUtc(dateTime, timezoneInfo); } }