Skip to content

Instantly share code, notes, and snippets.

@wilwang
Last active March 7, 2019 15:21
Show Gist options
  • Save wilwang/968d3460527f0737be28d8bf45bff33c to your computer and use it in GitHub Desktop.
Save wilwang/968d3460527f0737be28d8bf45bff33c to your computer and use it in GitHub Desktop.
Automapper to do datetime conversions
/******
An example to automatically perform datetime conversions using automapper
Assumptions:
* all inputs are in client Local time (MyInputModel)
* all datetimes are stored as UTC (MyDto)
* all datetimes retrieved from storage are in UTC and contain the destination timezone (MyDto)
* if destination not supplied, use the server local time zone
*******/
using System;
using AutoMapper;
namespace UtcConverter
{
class MyDto
{
public DateTime CreateDate;
public string TimeZone;
}
class MyOutputModel
{
public DateTime CreateDate;
public string TimeZone;
}
class MyInputModel
{
public DateTime CreateDate;
}
class DtoToOutputMapper
{
public static IMapper Mapper { get; private set; }
static DtoToOutputMapper()
{
RegisterMappings();
}
public static void RegisterMappings()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<DateTime, DateTime>().ConvertUsing<UtcToLocalConverter>();
});
Mapper = config.CreateMapper();
}
}
class InputToDtoMapper
{
public static IMapper Mapper { get; private set; }
static InputToDtoMapper()
{
RegisterMappings();
}
public static void RegisterMappings()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<DateTime, DateTime>().ConvertUsing<LocalToUtcConverter>();
cfg.CreateMap<MyInputModel, MyDto>().ForMember("TimeZone", opt => opt.Ignore());
});
Mapper = config.CreateMapper();
}
}
class UtcToLocalConverter : ITypeConverter<DateTime, DateTime>
{
public DateTime Convert(DateTime source, DateTime destination, ResolutionContext context)
{
var inputDate = source;
if (inputDate.Kind == DateTimeKind.Utc)
{
var timeZoneId = context.Items.ContainsKey("tz")
? context.Items["tz"].ToString()
: TimeZoneInfo.Local.Id;
var localizedDate = TimeZoneInfo.ConvertTime(
inputDate,
TimeZoneInfo.Utc,
TimeZoneInfo.FindSystemTimeZoneById(timeZoneId));
return localizedDate;
}
return inputDate;
}
}
class LocalToUtcConverter : ITypeConverter<DateTime, DateTime>
{
public DateTime Convert(DateTime source, DateTime destination, ResolutionContext context)
{
var inputDate = source;
if (inputDate.Kind != DateTimeKind.Utc)
{
return inputDate.ToUniversalTime();
}
return inputDate;
}
}
class Program
{
static void Main(string[] args)
{
MyInputModel myInput = new MyInputModel
{
CreateDate = new DateTime(2019, 6, 1, 3, 0, 0, 0, DateTimeKind.Local)
};
MyDto dto = new MyDto();
MyOutputModel myOutput = new MyOutputModel();
InputToDtoMapper.Mapper.Map(myInput, dto);
dto.TimeZone = "Mountain Standard Time";
DtoToOutputMapper.Mapper.Map(dto, myOutput, opt => opt.Items["tz"] = dto.TimeZone);
Console.WriteLine($"input.createdDate = {myInput.CreateDate} ({myInput.CreateDate.Kind})");
Console.WriteLine($"dto.createDate = {dto.CreateDate} (UTC)");
Console.WriteLine($"output.createdDate = {myOutput.CreateDate} ({dto.TimeZone})");
Console.ReadKey();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment