当前位置: 首页 > 知识库问答 >
问题:

Asp.NETMVC中的时区问题

微生弘
2023-03-14

我在时区面临一个问题。现在我正在从客户端保存时区,并将所有日期时间存储在UTC中。它工作正常,但当我试图将UTC的日期时间转换为CST、EST、EDT等时区后,它会显示错误的数据。

问题-假设我在美国东部夏令时晚上10点做了任何任务,并且它将在凌晨2点(按照UTC)保存在DB中,但当我尝试获取一天的数据并通过当前UTC日期时。

我的问题是,如果我试图获取一天的数据,比如从美国东部时间午夜11点到当前时间,但我从UTC到美国东部时间的转换是错误的,因为UTC 12午夜是昨天晚上8点(因为美国东部时间比UTC晚4小时)。(从日期[UTC转换为EDT]-2017年7月6日08:00pm到日期-2017年7月6日11:00pm)由于此转换,我只能从晚上8点到晚上11点获取数据

代码-下面是转换代码。在from date中,我只选择了utcnow.date和from a date

Javascript代码-

function setTimezoneCookie() {
            try {
                var timezone_cookie = "timezoneoffset";
                var timeZoneName = "timezonename"

                var tz = jstz.determine();
                var aa = tz.name();
                // if the timezone cookie not exists create one.

                if (!$.cookie(timezone_cookie)) {
                    // create a new cookie
                    $.cookie(timezone_cookie, new Date().getTimezoneOffset());
                    $.cookie(timeZoneName, aa);
                }
                else {
                    var storedOffset = parseInt($.cookie(timezone_cookie));
                    var currentOffset = new Date().getTimezoneOffset();
                    if (storedOffset !== currentOffset) {
                        $.cookie(timezone_cookie, new Date().getTimezoneOffset());
                        $.cookie(timeZoneName, aa);
                        location.reload();
                    }
                    else {
                        $.cookie(timeZoneName, aa);
                    }
                }
            }

c#代码-

 fromDate =Convert.ToDateTime(fromDate).ToClientTimeZoneinDateTime().ToString();  
                toDate = Convert.ToDateTime(toDate).ToClientTimeZoneinDateTime().ToString();

                ObjectParameter totalRecords = new ObjectParameter("TotalRecords", typeof(int));
                var DetailsList = objDetailsList.GetDetails(loginUserId,locationId, userId, taskType, pageIndex, numberOfRows, sortColumnName, sortOrderBy, textSearch, totalRecords, fromDate, toDate);
                if (DetailsList.Count() > 0)
                {
                    string output = BuildJQGridResults(DetailsList, numberOfRows, pageIndex, Convert.ToInt32(totalRecords.Value));
                    response.Write(output);
                }
                else
                {
                    JQGridResults result = new JQGridResults();
                    List<JQGridRow> rows = new List<JQGridRow>();
                    result.rows = rows.ToArray();
                    result.page = 0;
                    result.total = 0;
                    result.records = 0;
                    response.Write(new JavaScriptSerializer().Serialize(result));
                }

下面是将UTC时间转换为客户端时区的方法

public static DateTime ToClientTimeZoneinDateTime(this DateTime dt)
{
    try {               
        if (System.Web.HttpContext.Current.Request.Cookies["timezoneoffset"] != null || System.Web.HttpContext.Current.Request.Cookies["timezonename"] != null)
        {                  
            var timezonename = System.Web.HttpContext.Current.Request.Cookies["timezonename"].Value;
            timezonename = timezonename.Replace("%2F", "/");
            var timezoneLocal1 = FindTimezoneName(timezonename);
            TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(timezoneLocal1);
            bool isCurrentlyDaylightSavings = tzi.IsDaylightSavingTime(dt);
            if (isCurrentlyDaylightSavings == true)
                dt.AddHours(1);

            var timeOffSet = System.Web.HttpContext.Current.Request.Cookies["timezoneoffset"].Value;

            var offset = int.Parse(timeOffSet.ToString());
            dt = dt.AddMinutes(-1 * offset);                  
            return dt;
        }             
        return dt.ToLocalTime();
    }
    catch (Exception)
    {
        return DateTime.UtcNow;
    }
}

毫无疑问,因为时区处理正确,但如果最终用户试图在美国东部时间晚上8点后获取数据,则会面临来自UTC的时区落后问题。我也附上了截图。

我需要如何处理这种情况?

共有1个答案

伍宝
2023-03-14

主要的问题是你转换了错误的方向。您正在从UTC转换到用户的时区,但您的输入位于用户的时区,因此您需要转换另一个方向-从用户的时区到UTC。然后您的查询将显示更好的结果。

其他一些事情:

>

  • 不要试图手动增加/减少分钟或小时来转换时区。使用TimeZoneInfo上提供的转换功能,如ConvertTimeFromUtcConvertTimeToUtc等。无需测试DST。

    试/抓根本不应该在你的代码中。如果无法执行操作,则引发异常。不要通过吞下异常来掩盖重要的错误。

    dt.ToLocalTime()也不应该出现在代码中。永远不要依赖服务器的本地时区。

    new Date().getTimezoneOffset()返回的偏移量是用户的当前偏移量。您不能假定它是所选日期的正确偏移量。不管怎样,你不需要这样做,因为你已经得到了时区的名称。(您根本不需要timezoneoffsetcookie。)

    客户端上的jstz.determine()返回的时区名称将是IANA tzdb标识符,例如America/Los_Angeles。使用TimeZoneInfo.FindSystemTimeZoneById(除非您在Linux或Mac上运行.NET Core),这些功能在服务器端不起作用。需要转换到Windows时区。我看到您有一个FindTimeZoneName函数,我假设它正在执行转换。您没有在代码中显示详细信息,但我强烈建议您使用我的TimeZoneConverter库来实现它,因为它是通过对时区的更改来维护的。

    读取Cookie和时区转换是不同的问题。不要把它们捆绑在一起。

    最终,你应该有这样的东西:

    public static DateTime FromTimeZoneToUtc(this DateTime dt, string timeZone)
    {
        var windowsId = TimeZoneConverter.TZConvert.IanaToWindows(timeZone);
        var tzi = TimeZoneInfo.FindSystemTimeZoneById(windowsId);
        return TimeZoneInfo.ConvertTimeFromUtc(dt, tzi);
    }
    

    或者,更好的是,如果你使用野田佳彦时间,那么你根本不需要转换时区。

    public static DateTime FromTimeZoneToUtc(this DateTime dt, string timeZone)
    {
        var tz = DateTimeZoneProviders.Tzdb[timeZone];
        var local = LocalDateTime.FromDateTime(dt);
        return local.InZoneLeniently(tz).ToDateTimeUtc();
    }
    

  •  类似资料:
    • 我有这个iCal文件: 但是当我把它载入我的GMAIL时,它说日历设置为上午10点到11点 如果我的VTIMEZONE配置没有设置任何偏移,为什么会发生这种情况?如何在我的日历中获得实际的DTSTART和DTEND时间?

    • 本文向大家介绍关于Java中的mysql时区问题详解,包括了关于Java中的mysql时区问题详解的使用技巧和注意事项,需要的朋友参考一下 前言 话说工作十多年,mysql 还真没用几年。起初是外企银行,无法直接接触到 DB;后来一直从事架构方面,也多是解决问题为主。 这次搭建海外机房,围绕时区大家做了一番讨论。不说最终的结果是什么,期间有同事认为 DB 返回的是 UTC 时间。 这里简单做个验证

    • 您好,我有一个按钮,当我单击它时,此函数称为: 这里是CreateQrLink函数 这是我想通过点击下载QrCode按钮从这个视图下载图像的视图,我如何实现它?我不在数据库中保存QrLink我应该保存它还是其他什么?我想从src=Model获取照片。QrUrl

    • 它给出了准备好的SQL语句字符串: 无论我指定的时区如何,返回的时间戳都是相同的时间戳。它忽略了我指定的带有时区的Calendar对象。这是怎么回事,我做错了什么?

    • 问题内容: 我有一个对象,我需要将其以格式插入MySQL的datetime字段中。 这给了我准备好的SQL语句字符串: 无论我指定的时区如何,返回的时间戳都是相同的时间戳。它忽略了我指定的带有时区的Calendar对象。怎么回事,我在做什么错? 问题答案: 时区只是查看日期(这是固定时间点)的不同方式。我在这里写了一个小例子(请注意断言): 此代码段的输出是(结果将根据执行日期/时间而有所不同):

    • 问题内容: 我需要一个具有日期和年份指定值的jsDate对象。我希望给我Date对象2000作为价值,但如果我的电脑的时间设定到芝加哥时区,我得到,和布宜诺斯艾利斯:。 有没有一种方法可以创建Date对象,并返回我们在构造函数中设置的日期,无论在用户计算机上设置了什么时区? 更新:我需要在另一个库中使用此Date对象(该库调用其方法,因此使用UTC getter并没有真正的帮助。 问题答案: 在J