Working with time zones in ASP.NET MVC

You would like a dropdown list of time zones that a user can select from and perhaps use it for a user profile or multi tenant profile.


Our second objective is that we do not want to manage this reference data, it should come from the system.

So what we going do is.

  • DisplayFor template to deal with data types of TimeZoneInfo, so that whenever a model or viewmodel contains a property of type TimeZoneInfo, we can then use the Html.DisplayFor helper method.
  • Custom Model Binder that will take the TimeZone value (TZID) in the drop down list and create an instance of a new TimeZoneInfo object that can be bound to the model property

Remember, the value stored in the drop down list is just the TimeZoneID:


See above, the value is the TZID. So we need to somehow convert this to a TimeZoneInfo object, there is the following static method which we can use.

Excellento, lets geek it up.

Display Template

@model TimeZoneInfo

    var timeZoneList = TimeZoneInfo
        .Select(t => new SelectListItem
            Text = t.DisplayName,
            Value = t.Id,
            Selected = Model != null && t.Id == Model.Id
@Html.DropDownListFor(model => model, timeZoneList)
@Html.ValidationMessageFor(model => model)

Model Binder and Model Binder Provider

using System;
using System.Web.Mvc;

namespace MyStory.Web.ModelBinders
    public class TimeZoneInfoModelBinder : IModelBinder
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);

            if (valueProviderResult == null) return null;

            var attemptedValue = valueProviderResult.AttemptedValue;

            return ParseTimeZoneInfo(attemptedValue);

        public static TimeZoneInfo ParseTimeZoneInfo(string attemptedValue)
            return TimeZoneInfo.FindSystemTimeZoneById(attemptedValue);

        public class TimeZoneModelBinderProvider : IModelBinderProvider
            public IModelBinder GetBinder(Type modelType)
                return modelType == typeof(TimeZoneInfo)
                    ? DependencyResolver.Current.GetService<TimeZoneInfoModelBinder>()
                    : null;

Register Model Binder

Here I am using Autofac to automatically register all concrete types that implement IModelBinder in my assembly or IModelBinderProvider, via dependency injection in the global.asax.cs

                .Where(t => typeof(IModelBinder).IsAssignableFrom(t))

                .Where(t => typeof(IModelBinderProvider).IsAssignableFrom(t))

Sample Model

    public class MyModel
        public string Name { get; set; }

        [Display(Name = "Default Time Zone" )]
        public TimeZoneInfo DefaultTimeZone { get; set; }

Now whatever view need to use this model just needs to call the DisplayFor helper.

@Html.LabelFor(model => model.DefaultTimeZone)  
<div>  @Html.DisplayFor(m => m.DefaultTimeZone, "TimeZones")  

3 thoughts on “Working with time zones in ASP.NET MVC

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s