I have next custom model binder:
public class WebApiModelBinderDateTime : IModelBinder
{
public bool BindModel(HttpActionContext executionContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null)
{
return false;
}
DateTime date = (DateTime)value.ConvertTo(typeof(DateTime), CultureInfo.CurrentCulture);
date = DateTime.SpecifyKind(date, DateTimeKind.Utc);
bindingContext.Model = date;
return true;
}
}
Culture is setup in web.config like this:
<globalization culture="en-GB" enableClientBasedCulture="false" uiCulture="en-GB" />
and in global.asax like this:
CultureInfo culture = CultureInfo.CreateSpecificCulture("en-GB");
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
The problem is that this binder returns different dates locally and remotely.
E.g. 2019-06-03T09:53:26.651Z
will be converted to 2019-06-03 10:53:26
locally but to 2019-06-03 09:53:26
in the cloud(it's an old system which is deployed to Azure Cloud Services).
I tried to debug both locally and remotely but has not found any differences between CultureInfo.CurrentCulture
, ModelBindingContext
, ValueProvider
or ValueProviderResult
.
What else can cause different timezones?
A few things:
Culture settings and time zones are completely orthogonal concepts. Culture can affect the formatting of a string, or which calendar system is applied, but it does not influence time zones. They have nothing to do with each other.
You're specifying DateTimeKind.Utc
, thus everywhere you use this the resulting value will be serialized with a trailing Z
indicating UTC. If indeed the values are UTC based, then everything is fine and there's nothing left to do. However if you are applying these to arbitrary values that may represent time in a different time zone, setting UTC kind is not going to help. Instead, you might consider using a DateTimeOffset
type rather than a DateTime
.
You didn't show us how you apply this model binder or how you consume the API. Assuming that your API is correctly delivering the UTC-based result (with the Z
), then your concern about time zones is entirely based on the interpretation by the client-side code.
To answer directly "What else can cause different time zones?"
DateTime.Now
or DateTimeOffset.Now
or TimeZoneInfo.Local
or use DateTimeKind.Local
, .ToLocalTime()
, etc., as well as several APIs that convert from local time like .ToUniversalTime()
, then the server's local time zone setting (from the date and time control panel or settings page) is what controls that time zone. It is a server-wide setting for all applications on the server. You can also view or control it with tzutil.exe
on the command line.