你能从请求变量中确定时区吗?

时间:2008-12-03 19:50:28

标签: asp.net datetime .net-3.5 timezone globalization

有没有办法在服务器端执行时区偏移,通过http读取请求中的内容,而不是将所有内容发送到客户端并让它处理它?<​​/ p>

6 个答案:

答案 0 :(得分:22)

这更复杂,但我之前不得不求助于这种情况,因为机器和用户配置文件设置有时与访问者的偏好不匹配。例如,英国访问者暂时从澳大利亚服务器访问您的网站。

  1. 使用@balabaster建议的地理定位服务(例如MaxMind.com),以获得与其IP匹配的区域(Global.Session_Start最佳)。这是本地ISP的一个很好的匹配,但对AOL来说不太好。将偏移量存储在会话cookie中。

  2. 或者当用户进入网站时,使用JavaScript将时区偏移量作为表单提交/重定向的一部分。这是浏览器的当前偏移量,但不一定是访问者的首选区域。将此值用作默认值;存储在另一个会话cookie中。

    
    <script type="text/javascript" language="JavaScript">
    var offset = new Date();
    document.write('<input type="hidden" id="clientTzOffset" name="clientTzOffset" value="' + offset.getTimezoneOffset() + '"/>');
    </script>
    
  3. 允许访问者通过持久性cookie(对于匿名用户)和其帐户配置文件中的字段(如果已通过身份验证)更新区域。

  4. 来自会话值的持久值#3。您还可以为经过身份验证的用户存储相同的持久性Cookie,以便在登录前显示时间。

答案 1 :(得分:5)

检查detect_timezone.js - 在确定用户的时区方面做得非常好

答案 2 :(得分:0)

在Page Unload ... Request.ServerVariables之前的任何事件中。如果你想要他们的物理时区,那么你检查他们的IP地址并使用IP到地理位置转换工具。

我不确定你是否还有其他方法可以做到,所以如果你需要为他们的计算机配置时区,就必须等待javascript的页面加载......

答案 3 :(得分:0)

  

有没有办法在服务器端进行时区偏移   通过http读取请求中的内容,而不是发送   一切都给客户并让它处理它?<​​/ p>

这是我提出的解决方案,当我遇到与WCF Web服务相同的问题时:

How to get a WCF Web Service to return DateTimes in user's local timezone

基本上,我得到我的JavaScript / Angular代码来确定用户的时区,然后将此值传递给我的一个WCF Web服务。

注意我有一个名为getListOfRecords的Web服务,它接受一个参数,即时区偏移值。

$scope.loadSomeDatabaseRecords = function () {

    var d = new Date()
    var timezoneOffset = d.getTimezoneOffset();

    return $http({
        url: 'http://localhost:15021/Service1.svc/getListOfRecords/' + timezoneOffset,
        method: 'GET',
        async: true,
        cache: false,
        headers: { 'Accept': 'application/json', 'Pragma': 'no-cache' }
    }).success(function (data) {
        $scope.listScheduleLog = data.Results;
    });
}

从那里,我的C#代码读入数据库记录,将该时区偏移应用于UTC DateTime值,并将其返回给客户端。

答案 4 :(得分:0)

这是我如何使用JavaScript和MVC解决的方法:

首先,在主站点脚本上,添加了以下代码:

var clientOffset = getCookie("_clientOffset");
var currentOffset = new Date().getTimezoneOffset() * -1;
var reloadForCookieRefresh = false;

if (clientOffset  == undefined || clientOffset == null || clientOffset != currentOffset) {
    setCookie("_clientOffset", currentOffset, 30);
    reloadForCookieRefresh = true;
}

if (reloadForCookieRefresh)
    window.location.reload();

function setCookie(name, value, days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

function getCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

在操作过滤器内部的服务器端:

public class SetCurrentRequestDataFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // currentRequestService is registered by request using IoC container
        var currentRequestService = iocResolver.Resolve<ICurrentRequestService>();

        if (context.HttpContext.Request.Cookies.AllKeys.Contains("_clientOffset"))
        {
            currentRequestService.ClientOffset = int.Parse(context.HttpContext.Request.Cookies.Get("_clientOffset").Value);
        }

    }
}

答案 5 :(得分:-1)

我们可以使用服务器端的以下代码获取时区,而不是从客户端发送值。

private TimeZoneInfo GetRequestTimeZone()
    {
        TimeZoneInfo timeZoneInfo = null;
        DateTimeOffset localDateOffset;
        try
        {
            localDateOffset = new DateTimeOffset(Request.RequestContext.HttpContext.Timestamp, Request.RequestContext.HttpContext.Timestamp - Request.RequestContext.HttpContext.Timestamp.ToUniversalTime());
            timeZoneInfo = (from x in TimeZoneInfo.GetSystemTimeZones()
                            where x.BaseUtcOffset == localDateOffset.Offset
                            select x).FirstOrDefault();
        }
        catch (Exception)
        {
        }
        return timeZoneInfo;
    }

...谢谢