ASP.NET将用户的本地日期和时间与系统时间匹配

时间:2012-06-30 19:45:05

标签: asp.net timezone

我在理解如何将用户当前日期和时间与服务器时间匹配时遇到一些麻烦。

示例:假设我有一个用户可以自行注册的网站。一个配置文件选项是他们可以选择他们的本地时区。为此,有一个下拉菜单,他们可以从中选择正确的时区。所以来自中国的用户可能会选择(UTC + 08:00)北京,重庆,香港,乌鲁木齐,洛杉矶的另一位用户将选择(UTC-07:00)山地时间(美国和加拿大)(我假设)来自巴黎的一个人将选择(UTC + 01:00)布鲁塞尔,哥本哈根,马德里,巴黎。

Web应用程序正在美国的服务器上运行,具有特定的时区......

现在......所有这些用户都希望在下周五19:00 当地时区收到电子邮件通知 !!!

我迷失了......绝对是下周五的19:00对所有这些用户来说都不是同时...

如何映射他们的个人资料时区,以便我网站上运行的服务将在下周五19:00用户的当地时区发送电子邮件通知???

我现在正处于这个阶段...使用所有时区填充下拉菜单,以便用户可以在他们的个人资料中选择他们当前的时区。

当页面加载比下拉列表填充时区时:

    protected void Page_Load(object sender, EventArgs e)
    {
        ddlUserTimeZone.DataSource = GetTimeZones();
        ddlUserTimeZone.DataTextField = "Name";
        ddlUserTimeZone.DataValueField = "ID";
        ddlUserTimeZone.DataBind(); 
    }

    public Collection<TimeZoneItem> GetTimeZones()
    {
        Collection<TimeZoneItem> timeZones = new Collection<TimeZoneItem>();
        foreach (var timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
        {
            timeZones.Add(new TimeZoneItem 
            { 
                TimeZoneName = timeZoneInfo.DisplayName, 
                TimeZoneID = timeZoneInfo.Id 
            });

        }

        return timeZones;
    }

    public struct TimeZoneItem
    {
        public string TimeZoneName { get; set; }
        public string TimeZoneID { get; set; }
    }

现在,您能帮助配置文件时区与当前时间的匹配,以便在正确的时间发送电子邮件吗?

提前致谢!

2 个答案:

答案 0 :(得分:2)

您是否只是设置此服务?如果是这样, 按照世界时协调 (UTC或Zulu)时间运行您的Web服务器和数据库服务器,而不是本地时区。如果你这样做,一切都更容易管理。我经过惨痛的教训才学到这个。

UTC曾被称为格林威治标准时间;这是时区+00:00。它不像美国和欧洲当地时间那样改变夏令时。

这个时区的事情很痛苦,值得一试。有些国家有半小时的时区。

无论如何,一旦你知道每个用户的首选时区,以及她想要通知的时间,你就可以将时间从本地转换为UTC并存储它。

尝试这样的方法将用户的小时和分钟转换为UTC。 (时区转换需要一个日期,因为它们取决于夏令时规则。还有一个复杂因素。当时区从日光切换到标准,反之亦然,通知的UTC时间会发生变化。大多数人通过在发送每个通知时重新计算下一个通知(明天的通知)的UTC日期和时间来处理此问题。请考虑此代码。

TimeZoneInfo userLocal =            ;//user's time zone
int hour =                          ;//whatever the user wants
int minute =                        ;//whatever the user wants

DateTime tomorrow = DateTime.Now.AddDays(1);
int year = tomorrow.Year;
int month = tomorrow.Month;
int day = tomorrow.Day;
DateTime notificationTime = new DateTime(year,month,day,
                                         hour,minute,0, 
                                         DateTimeKind.Unspecified);
DateTime tomorrowNotificationTime = TimeZoneInfo.ConvertTimeToUtc(
                                         notificationTime,userLocal);

这可以让您明天在明天的正确时区内提供此用户通知所需的UTC时间。

答案 1 :(得分:0)

理想情况下,DateTime应以UTC格式存储在服务器上。

您的服务器上有以下数据

  • 用户的时区信息。
  • 用户需要通知的时间。
  • 服务器上的当前本地时间。

    // Convert current local server time to UTC.
    var serverUtc = DateTime.UtcNow;
    
    // Convert UTC time to users local time. This gives you the date and time as per the user.
    var userTimeZone = TimeZoneInfo.GetSystemTimeZones()[0]; // just an example. Replace with actual value.
    var userCurrentTime = TimeZoneInfo.ConvertTime(serverUtc, userTimeZone);
    
    /*
    add a day to userCurrentTime till its Friday. Add/subtract minutes till its 7:00PM.
    */
    
    var expectedNotificationTimeUtc = TimeZoneInfo.ConvertTimeToUtc(userCurrentTime, userTimeZone);
    /*
    1. store the expectedNotificationTimeUtc as the time you want to send the email. 
    2. your service can check for users their expectedNotificationTimeUtc and 
         if the UtcNow is within an acceptable range of the that time, send the email.
    */