设为首页 加入收藏

TOP

.NET WebFrom跨时区项目时间问题处理方法(一)
2019-09-25 18:11:42 】 浏览:80
Tags:.NET WebFrom 时区 项目 时间 问题 处理 方法

  前段时间因为公司的一个 WebFrom 项目设计到跨时区的问题,处理了一段时间,终于解决了,写个博客记录一下,方便以后回顾以及给他人提供一个参考的方法。

  本次的项目因为跨越了多个时区,在一些时间上会受到时区的影响,比如在美国分部使用系统插入了一条数据,在美国分部显示的时间是“2019-09-25 00:00:00“,那么在北京分部看到的时间就应该自动转换成”2019-09-25 12:00:00“(美国比北京少十二个小时),因此系统要能实现自动获取客户端的时区并转换成 UTC 时间,保存到数据库,在取出来的时候再根据客户端时区转换为当地时间。

  一开始是受部门运维的引导,知道了 oracle 自带一种数据类型叫做 timestamp with local time zone ,即按照数据库缓存的时区(Database Session Timezone),当用户存取时间时按照用户 Session 的时区对时间字段转换为当地时间。这个在我 CSDN 的博客中有提到这样的东西,链接为:https://blog.csdn.net/Wujiakai123/article/details/95391436 。然而当我开始尝试在项目中改进的时候才发现,发布到 IIS 的项目,不管有多少个客户连接进来,始终是以我的服务器为客户端去连接 oracle 的,这就导致了 oracle 中 Session 的时区一直是我的服务器的时区。因此推翻了使用 oracle 自带数据类型对时间字段进行自动转换的方法。

  此路不通,所以就只能尝试在项目里面做改进了。经过与部门其他同事讨论之后,决定在登录时通过 JS 方法获取到客户端电脑的时区,保存到用户的登录信息中,这样,在用户进行操作时,涉及到时间的都按照该时区进行转换。因为本人刚毕业不久,代码技术水平不高,因此只想出了这样的笨方法,下面将具体实现方法列出来,如果有大佬有更好的解决办法欢迎评论,我可以多学习学习。

  Login.aspx:

                <div class="newBox">
                    <asp:HiddenField ID="hidTimezone" runat="server" ClientIDMode="Static" />  //
                    <asp:Button ID="btnLogin" CssClass="LoginBtn" runat="server" OnClientClick="Login()"
                        Text="Sign In" OnClick="btnLogin_Click" />
                </div>

  hidTimezone 控件用于保存当前用户浏览器时区的值,btnLogin 按钮点击调用 Login() 方法

  Login()方法:

    <script type="text/java script">
        
        function Login() {

            //得到本地时间
            var d = new Date();
            //得到1970年一月一日到现在的秒数
            var local = d.getTime();
            //本地时间与GMT时间的时间偏移差
            var offset = d.getTimezoneOffset() * 60000;
            //获取本地时区,判断如果是负的则相加得到格林尼治时间,正的则相减
            var timezone = new Date().getTimezoneOffset() / 60 * (-1);
            document.getElementById("hidTimezone").value = timezone.toString();

            return true;
        }
    </script>

  通过 JS 方法将获取到的时区的值赋给 hidTimezone 中,登录的时候将该控件的值跟着用户的登录信息一起放在 Session 中,大概就是这样:

UserModel model = new UserModel();
model.Timezone = Convert.ToDouble(hidTimezone.value); 
Session[
"UserModelInfo"] = model;

  这样子就能将用户的浏览器时区写入到 Session 中,方便后续做时间转换的时候可使用。

  因为系统中所有页面都是继承了模板页 BasePage ,因此只要在模板页获取时区信息就可以了。

private UserLoginInfo _UserLoginInfo;
protected override void OnLoad(EventArgs e)
{
    _UserLoginInfo = (UserLoginInfo)Session["UserLoginInfo"];    
    base.OnLoad(e);
}

public class UserLoginInfo
{
    /// <summary>
    /// 用户所在时区
    /// </summary>
    public double Timezone { get; set; }
}

  这样一来,只要页面继承了 BasePage,就可以用 base.UserLoginInfo.Timezone 获取到时区信息。

  在Helper 类中新增时区转换方法:

       /// <summary>
        /// 根据时区获取本地时间
        /// </summary>
        /// <param name="timezone">时区</param>
        /// <returns></returns>
        public static DateTime GetLocalTime(double timezone)
        {
            try
            {
                double min = timezone * 60;
                var localtime = DateTime.UtcNow.AddMinutes(min);
                return localtime;
            }
            catch (Exception ex)
            {
                LogHelper.Write(ex.Message);
                throw new Exception(ex.Message);
            }

        }

        /// <summary>
        /// 根据时区将UTC时间转换成本地时间
        /// </summary>
        /// <param name="UTCTime">数据库中保存的UTC时间</param>
        /// <param name="timezone">用户本地计算机时区</param>
        /// <returns></returns>
        public static DateTime UTCToLocal(DateTime UTCTime, double timezone)
        {
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Winform中实现根据配置文件重新加.. 下一篇Winform中实现跨窗体获取ZedGraph..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目