Last active
March 7, 2019 15:21
-
-
Save wilwang/968d3460527f0737be28d8bf45bff33c to your computer and use it in GitHub Desktop.
Automapper to do datetime conversions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****** | |
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