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. The things especially gets complicated when you save this value to a database and read later, or send it to a client in a different time zone.
One solution to this problem is always use DateTime.UtcNow
and assume 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 date time (UTC or local) in a single point in your application.
Example: Getting the current time
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
namespace AbpDemo
{
public class MyService : ITransientDependency
{
private readonly IClock _clock;
public MyService(IClock clock)
{
_clock = clock;
}
public void Foo()
{
//Get the current time!
var now = _clock.Now;
}
}
}
- Inject the
IClock
service when you need to get the current time. Common base classes (like ApplicationService) already injects it and provides as a base property - so, you can directly use asClock
. - Use the
Now
property to get the current time.
Most of the times,
IClock
is the only service you need to know and use in your application.
Clock Options
AbpClockOptions
is the options class that used to set the clock kind.
Example: Use UTC Clock
Configure<AbpClockOptions>(options =>
{
options.Kind = DateTimeKind.Utc;
});
Write this inside the ConfigureServices
method of your module.
Default
Kind
isUnspecified
, that actually make the Clock as it doesn't exists at all. Either make itUtc
orLocal
if you want to get benefit of the Clock system.
DateTime Normalization
Other important function of the IClock
is to normalize DateTime
objects.
Example usage:
DateTime dateTime = ...; //Get from somewhere
var normalizedDateTime = Clock.Normalize(dateTime)
Normalize
method works as described below:
- Converts the given
DateTime
to the UTC (by using theDateTime.ToUniversalTime()
method) if current Clock is UTC and givenDateTime
is local. - Converts the given
DateTime
to the local (by using theDateTime.ToLocalTime()
method) if current Clock is local and 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 the 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.
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 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 UTC
.
See the setting documentation to learn more about the setting system.
ITimezoneProvider
ITimezoneProvider
is a service to simple convert Windows Time Zone Id values to Iana Time Zone Name values and vice verse. It also provides methods to get list of these time zones and get a TimeZoneInfo
with a given name.
It has been implemented using the TimeZoneConverter library.