Timing
Working with times & time zones is always tricky, especially if you need to build a global system that is used by users in different time zones.
ABP provides a basic infrastructure to make it easy and handle automatically wherever possible. This document covers the ABP services and systems related to time and time zones.
If you are creating a local application that runs in a single time zone region, you may not need all these systems. But even in this case, it is suggested to use the
IClock
service introduced in this document.
IClock
DateTime.Now
returns a DateTime
object with the local date & time of the server. A DateTime
object doesn't store the time zone information. So, you can not know the absolute date & time stored in this object. You can only make assumptions, like assuming that it was created in UTC+05 time zone. Things especially get complicated when you save this value to a database and read it later, or send it to a client in a different time zone.
One solution to this problem is always using DateTime.UtcNow
and assuming all DateTime
objects as UTC time. In this way, you can convert it to the time zone of the target client when needed.
IClock
provides an abstraction while getting the current time, so you can control the kind of the datetime (UTC or local) in a single point in your application.
Example: Getting the current time
- Inject the
IClock
service when you need to get the current time. Common base classes (like ApplicationService) already inject it and provide it as a base property - so, you can directly use it asClock
. - Use the
Now
property to get the current time.
Most of the time,
IClock
is the only service you need to know and use in your application.
Clock Options
AbpClockOptions
is the options class that is used to set the clock kind.
Example: Use UTC Clock
Write this inside of the ConfigureServices
method of your module.
The default
Kind
isUnspecified
, which effectively disables the Clock functionality. Either make itUtc
orLocal
if you want to get the benefit of the Clock system.
DateTime Normalization
Another important function of the IClock
is to normalize DateTime
objects.
Example usage:
Normalize
method works as described below:
- Converts the given
DateTime
to the UTC (by using theDateTime.ToUniversalTime()
method) if the current Clock is UTC and the givenDateTime
is local. - Converts the given
DateTime
to the local (by using theDateTime.ToLocalTime()
method) if the current Clock is local and the givenDateTime
is UTC. - Sets
Kind
of the givenDateTime
(using theDateTime.SpecifyKind(...)
method) to theKind
of the current Clock if givenDateTime
'sKind
isUnspecified
.
Normalize
method is used by the ABP when it gets a DateTime
that is not created by IClock.Now
and may not be compatible with the current Clock type. Examples;
DateTime
type binding in the ASP.NET Core MVC model binding.- Saving data to and reading data from database via Entity Framework Core.
- Working with
DateTime
objects on JSON deserialization.
DisableDateTimeNormalization Attribute
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 ConvertToUserTime(DateTime utcDateTime)
and DateTimeOffset ConvertToUserTime(DateTimeOffset dateTimeOffset)
methods convert given UTC DateTime
or DateTimeOffset
to the user's time zone.
If
SupportsMultipleTimezone
isfalse
ordateTime.Kind
is notUtc
or these is no timezone setting, it returns the givenDateTime
orDateTimeOffset
without any changes.
Example:
If user's TimeZone Setting
is Europe/Istanbul
Converts given user's DateTime to UTC
DateTime ConvertToUtc(DateTime dateTime)
method convert given user's DateTime
to UTC.
If
SupportsMultipleTimezone
isfalse
ordateTime.Kind
isUtc
or these is no timezone setting, it returns the givenDateTime
without any changes.
Example:
If user's TimeZone Setting
is Europe/Istanbul
Other IClock Properties
In addition to the Now
, IClock
service has the following properties:
Kind
: Returns aDateTimeKind
for the currently used clock type (DateTimeKind.Utc
,DateTimeKind.Local
orDateTimeKind.Unspecified
).SupportsMultipleTimezone
: Returnstrue
if the currently used clock is UTC.
Time Zones
This section covers the ABP infrastructure related to managing time zones.
TimeZone Setting
ABP defines a setting, named Abp.Timing.TimeZone
, that can be used to set and get the time zone for a user, tenant or globally for the application. The default value is empty, which means the application will use the server's time zone.
You can change your host/tenant global time zone in the Settings Management UI
The Account Pro Module supports user to set their own time zone in the account settings page.
See the setting documentation to learn more about the setting system.
UseAbpTimeZone Middleware
The app.UseAbpTimeZone()
middleware is used to set the time zone for the current request.
* It will get timezone from settings, the order is `User` -> `Tenant` -> `Application/Global`.
* If current request is anonymous, it will get timezone from the request header/cookie/form/query string. the key is `__timezone`.
If you want to get current timezone, you can inject
ICurrentTimezoneProvider
service. Please add this middleware after authentication.
ITimezoneProvider
ITimezoneProvider
is a service to simply convert Windows Time Zone Id values to Iana Time Zone Name values and vice verse. It also provides methods to get the list of these time zones and get a TimeZoneInfo
with a given name.
It has been implemented using the TimeZoneConverter library.