Ahs*_*ari 34 c# asp.net asp.net-mvc-3
我正在MVC3中构建一个应用程序,当用户进入我的网站时,我想知道该用户的时区.我想知道如何在c#中执行此操作而不是在javaScript中执行此操作?
Mik*_*ill 21
如前所述,您需要您的客户端告诉您的ASP.Net服务器有关他们所在的时区的详细信息.
这是一个例子.
我有一个Angular控制器,它以JSON格式从我的SQL Server数据库加载记录列表.问题是,DateTime这些记录中的值是UTC时区,我想向用户显示当地时区的日期/时间.
我使用JavaScript" getTimezoneOffset()"函数确定用户的时区(以分钟为单位),然后将此值附加到我试图调用的JSON服务的URL:
$scope.loadSomeDatabaseRecords = function () {
var d = new Date()
var timezoneOffset = d.getTimezoneOffset();
return $http({
url: '/JSON/LoadSomeJSONRecords.aspx?timezoneOffset=' + timezoneOffset,
method: 'GET',
async: true,
cache: false,
headers: { 'Accept': 'application/json', 'Pragma': 'no-cache' }
}).success(function (data) {
$scope.listScheduleLog = data.Results;
});
}
Run Code Online (Sandbox Code Playgroud)
在我的ASP.Net代码中,我提取timezoneOffset参数...
int timezoneOffset = 0;
string timezoneStr = Request["timezoneOffset"];
if (!string.IsNullOrEmpty(timezoneStr))
int.TryParse(timezoneStr, out timezoneOffset);
LoadDatabaseRecords(timezoneOffset);
Run Code Online (Sandbox Code Playgroud)
...并将其传递给我的函数,该函数从数据库加载记录.
这有点乱,因为我想FromUTCData在数据库的每条记录上调用我的C#函数,但LINQ to SQL无法将原始SQL与C#函数结合起来.
解决方案是首先读入记录,然后迭代它们,将时区偏移应用于DateTime每个记录中的字段.
public var LoadDatabaseRecords(int timezoneOffset)
{
MyDatabaseDataContext dc = new MyDatabaseDataContext();
List<MyDatabaseRecords> ListOfRecords = dc.MyDatabaseRecords.ToList();
var results = (from OneRecord in ListOfRecords
select new
{
ID = OneRecord.Log_ID,
Message = OneRecord.Log_Message,
StartTime = FromUTCData(OneRecord.Log_Start_Time, timezoneOffset),
EndTime = FromUTCData(OneRecord.Log_End_Time, timezoneOffset)
}).ToList();
return results;
}
public static DateTime? FromUTCData(DateTime? dt, int timezoneOffset)
{
// Convert a DateTime (which might be null) from UTC timezone
// into the user's timezone.
if (dt == null)
return null;
DateTime newDate = dt.Value - new TimeSpan(timezoneOffset / 60, timezoneOffset % 60, 0);
return newDate;
}
Run Code Online (Sandbox Code Playgroud)
虽然它工作得很好,但在编写Web服务以向世界不同地区的用户显示日期/时间时,此代码非常有用.
现在,我正在苏黎世时间上午11点写这篇文章,但是如果你在洛杉矶读它,你会看到我在凌晨2点(当地时间)编辑了它.使用这样的代码,您可以让您的网页显示对您网站的国际用户有意义的日期时间.
唷.
希望这可以帮助.
Chr*_*ead 19
这不是可能的服务器端,除非您通过用户IP地址假设它或让用户以某种形式的配置文件设置它.你可以通过javascript获得客户的时间.
请参阅此处了解javacript解决方案:使用JavaScript获取客户端的时区
对于 Dot Net 版本 3.5 及更高版本,您可以使用:
TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);
Run Code Online (Sandbox Code Playgroud)
但对于低于 3.5 版本的 Dot Net,您可以通过以下方式手动处理:
首先,从客户端获取Offset并将其存储在cookie中
function setTimezoneCookie(){
var timezone_cookie = "timezoneoffset";
// if the timezone cookie does not exist create one.
if (!$.cookie(timezone_cookie)) {
// check if the browser supports cookie
var test_cookie = 'test cookie';
$.cookie(test_cookie, true);
// browser supports cookie
if ($.cookie(test_cookie)) {
// delete the test cookie
$.cookie(test_cookie, null);
// create a new cookie
$.cookie(timezone_cookie, new Date().getTimezoneOffset());
// re-load the page
location.reload();
}
}
// if the current timezone and the one stored in cookie are different
// then store the new timezone in the cookie and refresh the page.
else {
var storedOffset = parseInt($.cookie(timezone_cookie));
var currentOffset = new Date().getTimezoneOffset();
// user may have changed the timezone
if (storedOffset !== currentOffset) {
$.cookie(timezone_cookie, new Date().getTimezoneOffset());
location.reload();
}
}
Run Code Online (Sandbox Code Playgroud)
}
之后你可以在后端代码中使用 cookie,如下所示:
public static string ToClientTime(this DateTime dt)
{
// read the value from session
var timeOffSet = HttpContext.Current.Session["timezoneoffset"];
if (timeOffSet != null)
{
var offset = int.Parse(timeOffSet.ToString());
dt = dt.AddMinutes(-1 * offset);
return dt.ToString();
}
// if there is no offset in session return the datetime in server timezone
return dt.ToLocalTime().ToString();
}
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题,遗憾的是服务器无法知道客户端时区.如果你想要,你可以在进行ajax调用时发送客户端时区作为标题.
如果你想要更多关于添加标题的信息,这篇文章可能有助于如何添加标题来请求:如何使用js或jQuery向ajax请求添加自定义HTTP标头?
new Date().getTimezoneOffset();//gets the timezone offset
Run Code Online (Sandbox Code Playgroud)
如果您不想每次都添加标题,您可以考虑设置一个cookie,因为cookie与所有httpRequest一起发送,您可以处理cookie以在服务器端获取客户端时区.但我不喜欢添加cookie,原因与他们发送所有http请求的原因相同.谢谢.
您将需要同时使用客户端和服务器端技术。
在客户端:(
选择一个)
这适用于大多数现代浏览器:
Intl.DateTimeFormat().resolvedOptions().timeZone
Run Code Online (Sandbox Code Playgroud)
还有jsTimeZoneDetect的jstz.determine(),或矩时区的moment.tz.guess()旧版本浏览器功能,还以为这些库一般只在旧的应用程序使用。
两者的结果都将是IANA 时区标识符,例如America/New_York. 以您喜欢的任何方式将该结果发送到服务器。
在服务器端:(
选择一个)
使用TimeZoneInfo(仅在非 Windows 系统上):
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("America/New_York");
Run Code Online (Sandbox Code Playgroud)
使用TimeZoneConverter(在任何操作系统上):
TimeZoneInfo tzi = TZConvert.GetTimeZoneInfo("America/New_York");
Run Code Online (Sandbox Code Playgroud)
使用NodaTime(在任何操作系统上):
DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69971 次 |
| 最近记录: |