如何在.NET / Sql Server中在用户本地时间发送电子邮件?

时间:2020-03-05 18:42:00  来源:igfitidea点击:

我正在编写一个程序,该程序每小时需要每小时发送一次电子邮件,但要在用户本地时间进行。

假设我有2个用户位于不同的时区。约翰在纽约,弗雷德在洛杉矶。服务器在芝加哥。如果我想在本地用户下午6点发送电子邮件,则必须在服务器时间晚上7点发送给John,在服务器时间下午4点发送给Fred。

在.NET / Sql Server中,有什么好的方法?我已经找到了包含所有时区信息的xml文件,因此我正在考虑编写脚本以将其导入数据库,然后对其进行查询。

编辑:我使用了t4znet.dll,并在.NET端进行了所有比较。

解决方案

回答

我是一名PHP开发人员,所以我将分享我从PHP中学到的知识。我确定.NET将包含类似内容。

在PHP中,我们可以建议服务器在不同时间发送电子邮件,从而获得服务器时间的时区差异。

每次添加用户时,请保存其与服务器时间的偏移量(或者服务器时区更改时的时区)。

然后,当我们指定更新时,有一个自动任务(LAMP人员为Cron),该任务每小时运行一次,以查看是否需要发送电子邮件。这样做直到没有电子邮件要发送为止。

回答

我们有两种选择:

  • 将调整后的邮件操作时间存储到每个用户的数据库中。然后,只需将服务器时间与存储的时间进行比较即可。为避免混淆和可移植性问题,我将所有时间都存储在UTC中。因此,在SERVER_UTC_TIME()== storedUtcTime时发送邮件。
  • 将每个邮件操作的本地时间存储到数据库中,然后即时进行转换。当SERVER_UTC_TIME()== TO_UTC_TIME(storedLocalTime,userTimeZone)时发送邮件。

我们应该决定什么对应用程序最有意义。例如,如果所有用户的邮寄时间始终相同,那么选择选项(2)会更有意义。如果事件时间可以在用户之间甚至每个用户之间变化,那么如果我们选择选项(1),则可以使开发和调试更加容易。无论哪种方式,我们都需要知道用户的时区。

*这些函数调用显然是伪的,因为我不知道它们在T-SQL中的调用,但是它们应该存在。

回答

我们可以通过这篇出色的文章"世界时钟和TimeZoneInformation类"来补充解决方案,我制作了一个Web服务,该文件发送了包含本地时间和接收器时间的信息的文件,我所做的就是修改此类,以便我处理该问题。完全可以按照我的需要完美地工作。

我认为我们可以参加此类,并从"用户"表中获取他们的时区并"计算"适当的时间,我的代码如下:

//Get correct destination time
DateTime thedate = DateTime.Now;

string destinationtimezone = null;

//Load the time zone where the file is going
TimeZoneInformation tzi = TimeZoneInformation.FromName(this.m_destinationtimezone);

//Calculate
destinationtimezone = tzi.FromUniversalTime(thedate.ToUniversalTime()).ToString();

此类在Windows Vista中具有一个问题,该问题导致" FromIndex(int index)"函数崩溃,但是我们可以修改代码,而不必使用该函数:

public static TimeZoneInformation FromIndex(int index)
    {
        TimeZoneInformation[] zones = EnumZones();

        for (int i = 0; i < zones.Length; ++i)
        {
            if (zones[i].Index == index)
                return zones[i];
        }

        throw new ArgumentOutOfRangeException("index", index, "Unknown time zone index");
    }

我们可以将其更改为;

public static TimeZoneInformation FromName(string name)
    {
        TimeZoneInformation[] zones = EnumZones();

        foreach (TimeZoneInformation tzi in zones)
        {
            if (tzi.DisplayName.Equals(name))
                return tzi;
        }

        throw new ArgumentOutOfRangeException("name", name, "Unknown time zone name");
    }