我们的应用程序旨在处理来自不同地理位置的用户。
我们无法检测到当前最终用户的本地时间和时区对它进行的操作是什么。他们选择不同的文化,例如 sv-se、en-us、ta-In,即使他们从欧洲/伦敦时区访问也是如此。
我们将它托管在美国的托管服务器中,应用程序用户来自Norway/Denmark/Sweden/UK/USA/India
问题是我们用来DateTime.Now
存储记录创建/更新日期等。
由于服务器在美国运行,所有用户数据都保存为美国时间:(
在 SO 进行研究之后,我们决定将所有历史日期存储在 DB 中DateTime.UtcNow
问题:
在 上创建了一条记录29 Dec 2013, 3:15 P.M Swedish time
。
public ActionResult Save(BookingViewModel model)
{
Booking booking = new Booking();
booking.BookingDateTime = model.BookingDateTime; //10 Jan 2014 2:00 P.M
booking.Name = model.Name;
booking.CurrentUserId = (User)Session["currentUser"].UserId;
//USA Server runs in Pacific Time Zone, UTC-08:00
booking.CreatedDateTime = DateTime.UtcNow; //29 Dec 2013, 6:15 A.M
BookingRepository.Save(booking);
return View("Index");
}
我们希望向在印度/瑞典/美国登录的用户显示相同的历史时间。
截至目前,我们正在使用当前文化用户登录并从配置文件中选择时区,并使用 TimeZoneInfo 类进行转换
<appSettings>
<add key="sv-se" value="W. Europe Standard Time" />
<add key="ta-IN" value="India Standard Time" />
</appSettings>
private DateTime ConvertUTCBasedOnCulture(DateTime utcTime)
{
//utcTime is 29 Dec 2013, 6:15 A.M
string TimezoneId =
System.Configuration.ConfigurationManager.AppSettings
[System.Threading.Thread.CurrentThread.CurrentCulture.Name];
// if the user changes culture from sv-se to ta-IN, different date is shown
TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById(TimezoneId);
return TimeZoneInfo.ConvertTimeFromUtc(utcTime, tZone);
}
public ActionResult ViewHistory()
{
List<Booking> bookings = new List<Booking>();
bookings=BookingRepository.GetBookingHistory();
List<BookingViewModel> viewModel = new List<BookingViewModel>();
foreach (Booking b in bookings)
{
BookingViewModel model = new BookingViewModel();
model.CreatedTime = ConvertUTCBasedOnCulture(b.CreatedDateTime);
viewModel.Add(model);
}
return View(viewModel);
}
查看代码
@Model.CreatedTime.ToString("dd-MMM-yyyy - HH':'mm")
注意:用户可以在登录前更改文化/语言。它是一个基于本地化的应用程序,在美国服务器上运行。
我见过NODATIME
,但我不明白它如何帮助托管在不同位置的多文化 Web 应用程序。
问题
如何29 Dec 2013, 3:15 P.M
为登录 INDIA/USA/Anywhere 的用户显示相同的记录创建日期?
到目前为止,我的逻辑ConvertUTCBasedOnCulture
是基于用户登录的文化。这应该与文化无关,因为用户可以使用来自印度/美国的任何文化登录
数据库栏
创建时间:SMALLDATETIME
更新:尝试的解决方案:
DATABASE COLUMN TYPE: DATETIMEOFFSET
用户界面
最后,我在每个请求中使用下面的 Momento.js 代码发送当前用户的本地时间
$.ajaxSetup({
beforeSend: function (jqXHR, settings) {
try {
//moment.format gives current user date like 2014-01-04T18:27:59+01:00
jqXHR.setRequestHeader('BrowserLocalTime', moment().format());
}
catch (e) {
}
}
});
应用
public static DateTimeOffset GetCurrentUserLocalTime()
{
try
{
return
DateTimeOffset.Parse(HttpContext.Current.Request.Headers["BrowserLocalTime"]);
}
catch
{
return DateTimeOffset.Now;
}
}
然后叫进来
model.AddedDateTime = WebAppHelper.GetCurrentUserLocalTime();
在视图中
@Model.AddedDateTime.Value.LocalDateTime.ToString("dd-MMM-yyyy - HH':'mm")
在视图中,它向用户显示本地时间,但我想看到dd-MMM-yyyy CET/PST
(2 小时前)。
这 2 小时前应该从最终用户的本地时间计算。与使用时区显示和本地用户计算创建/编辑时间的堆栈溢出问题完全相同。
示例: answered Jan 25 '13 at 17:49 CST (6 hours/days/month ago)
因此来自美国/印度用户的其他查看可以真正理解此记录是在印度/美国当前时间正好 6 小时创建的
几乎我想我什么都做到了,除了显示格式和计算。我怎样才能做到这一点?