In the application am working on, We have an option for each user to select their own timezone
and when displaying data for the particular user, we are fetching timezone
opted by him and display accordingly. Now as per the answer mentioned here, which is really an awesome one, I went on implementing the mentioned options, i.e. conversion of date at model
level, and I have done it as below:
NotificationViewModel.cs
public class NotificationViewModel
{
public string Text{ get; set; }
public DateTime Moment
{
get
{
return _Created;
}
set
{
_Created = Repository.GetUserTimeZoneDateTime(value);
}
}
private DateTime _Created { get; set; }
public string Icon { get; set; }
}
Repository.cs
GetUserTimeZoneDateTime
has 2 overloads
public static DateTime GetUserTimeZoneDateTime(DateTime dTime)
{
using (var context = new EntityContext())
{
var tZone = context.tbl_usrs.AsNoTracking().FirstOrDefault(x => x.uname == HttpContext.Current.User.Identity.Name).preferred_timezone;
var tZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tZone);
return TimeZoneInfo.ConvertTimeFromUtc(dTime, tZoneInfo);
}
}
public static DateTime GetUserTimeZoneDateTime(EntityContext context, DateTime dTime)
{
var tZone = context.tbl_usrs.AsNoTracking().FirstOrDefault(x => x.uname == HttpContext.Current.User.Identity.Name).preferred_timezone;
var tZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(tZone);
return TimeZoneInfo.ConvertTimeFromUtc(dTime, tZoneInfo);
}
In the above case first overload will be called, but then, when called from model
level, HttpContext.Current
will be null
and hence it fails.
In the 2nd approach, I tried, the timezone
will be fetched from controller level.
NotificationViewModel.cs
public class NotificationViewModel
{
public string Text { get; set; }
public DateTime Moment { get; set; }
public string Icon { get; set; }
}
TestController.cs
using (var context = new EntityContext())
{
var localTime = Repository.GetUserTimeZoneDateTime(context, DateTime.UtcNow);
List<NotificationViewModel> model = new List<NotificationViewModel>();
int days = DateTime.UtcNow.DayOfWeek - DayOfWeek.Sunday;
DateTime weekStart = localTime.AddDays(-days);
DateTime weekEnd = weekStart.AddDays(6);
var p = context.tbl_prchs
.Where(x => x.c_date <= weekEnd && x.c_date >= weekStart)
.Select(x => new NotificationViewModel()
{
Icon = "fa fa-gbp",
Moment = Repository.GetUserTimeZoneDateTime(context,x.c_date),
Text = "Test notes",
}).ToList();
model.AddRange(p);
}
var localTime = Repository.GetUserTimeZoneDateTime(context, DateTime.UtcNow);
fetches proper datetime
according to the preferred user timezone
. But then Moment= Repository.GetUserTimeZoneDateTime(context,x.c_date),
inside linq expression
throws error as below
LINQ to Entities does not recognize the method 'System.DateTime GetUserTimeZoneDateTime(Direct_Commercial_Van.Models.EntityDataModel.dcvEntities, System.DateTime)' method, and this method cannot be translated into a store expression.
which is expected. What else options I can try here to achieve this? or how in other ways I can handle timezone issue here?