diff --git a/docs/en/Community-Articles/2025-03-11-Developing-A-Multi-Timezone-Application-Using-The-ABP-Framework/post.md b/docs/en/Community-Articles/2025-03-11-Developing-A-Multi-Timezone-Application-Using-The-ABP-Framework/post.md index c45b705659..e34a64337e 100644 --- a/docs/en/Community-Articles/2025-03-11-Developing-A-Multi-Timezone-Application-Using-The-ABP-Framework/post.md +++ b/docs/en/Community-Articles/2025-03-11-Developing-A-Multi-Timezone-Application-Using-The-ABP-Framework/post.md @@ -64,8 +64,8 @@ We recommend using `DateTimeOffset` to store time because it has timezone inform The `IClock` service has 2 methods to convert a given `UTC` time to the user time: ```csharp -DateTime ConvertTo(DateTime dateTime) -DateTimeOffset ConvertTo(DateTimeOffset dateTimeOffset) +DateTime ConvertToUserTime(utcDateTime dateTime) +DateTimeOffset ConvertToUserTime(DateTimeOffset dateTimeOffset) ``` > If `SupportsMultipleTimezone` is `false` or `dateTime.Kind` is not `Utc` or no timezone is set, it will return the given `DateTime` or `DateTimeOffset` without any changes. @@ -78,7 +78,7 @@ If the user's timezone is `Europe/Istanbul` // 2025-03-01T05:30:00Z var utcTime = new DateTime(2025, 3, 1, 5, 30, 0, DateTimeKind.Utc); -var userTime = Clock.ConvertTo(utcTime); +var userTime = Clock.ConvertToUserTime(utcTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. userTime.Kind.ShouldBe(DateTimeKind.Unspecified); @@ -89,7 +89,7 @@ userTime.ToString("O").ShouldBe("2025-03-01T08:30:00"); // 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); +var userTime = Clock.ConvertToUserTime(utcTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. userTime.Offset.ShouldBe(TimeSpan.FromHours(3)); @@ -101,7 +101,7 @@ userTime.ToString("O").ShouldBe("2025-03-01T08:30:00.0000000+03:00"); The `IClock` service has 1 method to convert a given user time to UTC. ```csharp -DateTime ConvertFrom(DateTime dateTime) +DateTime ConvertToUtc(DateTime dateTime) ``` > If `SupportsMultipleTimezone` is `false` or `dateTime.Kind` is `Utc` or no timezone is set, it will return the given `DateTime` without any changes. @@ -114,7 +114,7 @@ If the user's timezone is `Europe/Istanbul` // 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); +var utcTime = Clock.ConvertToUtc(userTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours earlier. utcTime.Kind.ShouldBe(DateTimeKind.Utc); @@ -195,9 +195,9 @@ In the API response, we usually use the ISO 8601 format time, as you can see, af In the `AuthServer` project, we handle time conversion in a simple way: 1. First, we get the `Meeting` entities from the database using `IRepository`. At this point, all `DateTime` values are in UTC. -2. Then, when displaying the times in the view, we use `Clock.ConvertTo` to show them in the user's timezone. +2. Then, when displaying the times in the view, we use `Clock.ConvertToUserTime` to show them in the user's timezone. -> Note: The `ConvertTo` method will only convert times if multi-timezone support is enabled in the application. +> Note: The `ConvertToUserTime` method will only convert times if multi-timezone support is enabled in the application. ```csharp public class IndexModel : AbpPageModel @@ -239,11 +239,11 @@ public class IndexModel : AbpPageModel { @meeting.Subject - @Clock.ConvertTo(meeting.StartTime) ➡️ @Clock.ConvertTo(meeting.EndTime) - @Clock.ConvertTo(meeting.ActualStartTime) - @(meeting.CanceledTime.HasValue ? Clock.ConvertTo(meeting.CanceledTime.Value) : "N/A") - @Clock.ConvertTo(meeting.ReminderTime).DateTime - @(meeting.FollowUpTime.HasValue ? Clock.ConvertTo(meeting.FollowUpTime.Value).DateTime : "N/A") + @Clock.ConvertToUserTime(meeting.StartTime) ➡️ @Clock.ConvertToUserTime(meeting.EndTime) + @Clock.ConvertToUserTime(meeting.ActualStartTime) + @(meeting.CanceledTime.HasValue ? Clock.ConvertToUserTime(meeting.CanceledTime.Value) : "N/A") + @Clock.ConvertToUserTime(meeting.ReminderTime).DateTime + @(meeting.FollowUpTime.HasValue ? Clock.ConvertToUserTime(meeting.FollowUpTime.Value).DateTime : "N/A") @meeting.Description } @@ -441,7 +441,7 @@ In short, we use the `abp.clock.normalizeToLocaleString` method to display time, ### Handling Timezone in Blazor -We cannot automatically complete some work in `Blazor UI`, we need to inject `IClock` and use the `ConvertTo` and `ConvertFrom` methods to display and create/update entities. +We cannot automatically complete some work in `Blazor UI`, we need to inject `IClock` and use the `ConvertToUserTime` and `ConvertToUtc` methods to display and create/update entities. Below is a complete `Meeting` page, please refer to the usage of `Clock` in it. @@ -501,35 +501,35 @@ Below is a complete `Meeting` page, please refer to the usage of `Clock` in it. Field="@nameof(MeetingDto.StartTime)" Caption="@(L["StartTime"] + "/" + L["EndTime"])"> - @Clock.ConvertTo(context.StartTime).ToString("yyyy-MM-dd HH:mm:ss") ➡️ @Clock.ConvertTo(context.EndTime).ToString("yyyy-MM-dd HH:mm:ss") + @Clock.ConvertToUserTime(context.StartTime).ToString("yyyy-MM-dd HH:mm:ss") ➡️ @Clock.ConvertToUserTime(context.EndTime).ToString("yyyy-MM-dd HH:mm:ss") - @Clock.ConvertTo(context.ActualStartTime).ToString("yyyy-MM-dd HH:mm:ss") + @Clock.ConvertToUserTime(context.ActualStartTime).ToString("yyyy-MM-dd HH:mm:ss") - @(context.CanceledTime.HasValue ? Clock.ConvertTo(context.CanceledTime.Value).ToString("yyyy-MM-dd HH:mm:ss") : "N/A") + @(context.CanceledTime.HasValue ? Clock.ConvertToUserTime(context.CanceledTime.Value).ToString("yyyy-MM-dd HH:mm:ss") : "N/A") - @(Clock.ConvertTo(context.ReminderTime).ToString("yyyy-MM-dd HH:mm:ss") ) + @(Clock.ConvertToUserTime(context.ReminderTime).ToString("yyyy-MM-dd HH:mm:ss") ) - @(context.FollowUpTime.HasValue ? Clock.ConvertTo(context.FollowUpTime.Value).ToString("yyyy-MM-dd HH:mm:ss") : "N/A") + @(context.FollowUpTime.HasValue ? Clock.ConvertToUserTime(context.FollowUpTime.Value).ToString("yyyy-MM-dd HH:mm:ss") : "N/A") { Clock.ConvertTo(EditingEntity.StartTime), Clock.ConvertTo(EditingEntity.EndTime) }; - EditingEntity.ActualStartTime = Clock.ConvertTo(EditingEntity.ActualStartTime); - EditingEntity.CanceledTime = EditingEntity.CanceledTime.HasValue ? Clock.ConvertTo(EditingEntity.CanceledTime.Value) : null; - EditingEntity.ReminderTime = Clock.ConvertTo(EditingEntity.ReminderTime); - EditingEntity.FollowUpTime = EditingEntity.FollowUpTime.HasValue ? Clock.ConvertTo(EditingEntity.FollowUpTime.Value) : null; + SelectedDates = new List { Clock.ConvertToUserTime(EditingEntity.StartTime), Clock.ConvertToUserTime(EditingEntity.EndTime) }; + EditingEntity.ActualStartTime = Clock.ConvertToUserTime(EditingEntity.ActualStartTime); + EditingEntity.CanceledTime = EditingEntity.CanceledTime.HasValue ? Clock.ConvertToUserTime(EditingEntity.CanceledTime.Value) : null; + EditingEntity.ReminderTime = Clock.ConvertToUserTime(EditingEntity.ReminderTime); + EditingEntity.FollowUpTime = EditingEntity.FollowUpTime.HasValue ? Clock.ConvertToUserTime(EditingEntity.FollowUpTime.Value) : null; } protected override Task OnUpdatingEntityAsync() { if (SelectedDates.Count == 2 && SelectedDates[0].HasValue && SelectedDates[1].HasValue) { - EditingEntity.StartTime = Clock.ConvertFrom(SelectedDates[0]!.Value); - EditingEntity.EndTime = Clock.ConvertFrom(SelectedDates[1]!.Value); + EditingEntity.StartTime = Clock.ConvertToUtc(SelectedDates[0]!.Value); + EditingEntity.EndTime = Clock.ConvertToUtc(SelectedDates[1]!.Value); } - EditingEntity.ActualStartTime = Clock.ConvertFrom(EditingEntity.ActualStartTime); - EditingEntity.CanceledTime = EditingEntity.CanceledTime.HasValue ? Clock.ConvertFrom(EditingEntity.CanceledTime.Value) : null; + EditingEntity.ActualStartTime = Clock.ConvertToUtc(EditingEntity.ActualStartTime); + EditingEntity.CanceledTime = EditingEntity.CanceledTime.HasValue ? Clock.ConvertToUtc(EditingEntity.CanceledTime.Value) : null; return Task.CompletedTask; } diff --git a/docs/en/framework/infrastructure/timing.md b/docs/en/framework/infrastructure/timing.md index 343553d7bd..47a5d6b3f1 100644 --- a/docs/en/framework/infrastructure/timing.md +++ b/docs/en/framework/infrastructure/timing.md @@ -93,7 +93,7 @@ var normalizedDateTime = Clock.Normalize(dateTime) #### 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. +`DateTime ConvertToUserTime(DateTime utcDateTime)` and `DateTimeOffset ConvertToUserTime(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. @@ -105,7 +105,7 @@ If user's `TimeZone Setting` is `Europe/Istanbul` // 2025-03-01T05:30:00Z var utcTime = new DateTime(2025, 3, 1, 5, 30, 0, DateTimeKind.Utc); -var userTime = Clock.ConvertTo(utcTime); +var userTime = Clock.ConvertToUserTime(utcTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. userTime.Kind.ShouldBe(DateTimeKind.Unspecified); @@ -116,7 +116,7 @@ userTime.ToString("O").ShouldBe("2025-03-01T08:30:00"); // 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); +var userTime = Clock.ConvertToUserTime(utcTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours later. userTime.Offset.ShouldBe(TimeSpan.FromHours(3)); @@ -125,7 +125,7 @@ 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. +`DateTime ConvertToUtc(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. @@ -137,7 +137,7 @@ If user's `TimeZone Setting` is `Europe/Istanbul` // 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); +var utcTime = Clock.ConvertToUtc(userTime); // Europe/Istanbul has 3 hours difference with UTC. So, the result will be 3 hours earlier. utcTime.Kind.ShouldBe(DateTimeKind.Utc);