Как отправить электронную почту в локальное время пользователя на сервере .NET/Sql?

Я пишу программу, которая должна отправлять электронное письмо каждый час в час, но в локальное для пользователя время.

Скажем, у меня есть 2 пользователя в разных часовых поясах. Джон в Нью-Йорке, а Фред в Лос-Анджелесе. Сервер находится в Чикаго. Если я хочу отправить электронное письмо в 18:00 по местному времени каждому пользователю, мне нужно будет отправить электронное письмо Джону в 19:00 по серверному времени и Фреду в 16:00 по серверному времени.

Какой хороший подход к этому в .NET/Sql Server? Я нашел файл xml со всей информацией о часовых поясах, поэтому я рассматриваю возможность написания сценария для его импорта в базу данных, а затем запроса от него.

Редактировать: я использовал «t4znet.dll» и выполнял все сравнения на стороне .NET.


person Shawn    schedule 22.08.2008    source источник


Ответы (3)


У вас есть два варианта:

  • Сохраните скорректированное время для почтового действия в базе данных для каждого пользователя. Затем просто сравните время сервера с сохраненным временем. Чтобы избежать путаницы и проблем с переносимостью, я бы все время хранил в формате UTC. Итак, отправьте почту, когда SERVER_UTC_TIME() == storeUtcTime.
  • Сохраняйте местное время для каждого почтового действия в базе данных, а затем преобразуйте его на лету. Отправить почту, когда SERVER_UTC_TIME() == TO_UTC_TIME(storedLocalTime, userTimeZone).

Вы должны решить, что наиболее целесообразно для вашего приложения. Например, если время рассылки всегда одинаково для всех пользователей, имеет смысл выбрать вариант (2). Если время событий может меняться между пользователями и даже для каждого пользователя, это может упростить разработку и отладку, если вы выберете вариант (1). В любом случае вам нужно будет знать часовой пояс пользователя.

*Эти вызовы функций, очевидно, псевдо, так как я не знаю их вызовов в T-SQL, но они должны существовать.

person rix0rrr    schedule 22.08.2008

Я PHP-разработчик, поэтому я поделюсь тем, что знаю из PHP. Я уверен, что .NET будет включать что-то подобное.

В PHP вы можете получить разницу в часовых поясах для времени сервера - как вы предложили отправлять электронные письма в разное время на сервере.

Каждый раз, когда вы добавляете пользователя, сохраняйте смещение его времени относительно времени сервера (или часового пояса, если часовой пояс сервера меняется).

Затем, когда вы укажете обновление, создайте автоматическую задачу (Cron для людей с LAMP), которая запускается каждый час, проверяя, нужно ли отправлять электронное письмо. Делайте это до тех пор, пока не останется писем для отправки.

person Ross    schedule 22.08.2008

Вы можете дополнить свое решение этой прекрасной статьей "Мировые часы и класс TimeZoneInformation. ", я создал веб-сервис, который отправлял файл с информацией, включающей локальное время и время получателя, что я сделал, так это изменил этот класс, чтобы я мог справиться с этой проблемой, и он работал идеально, именно так, как мне было нужно.

Я думаю, вы могли бы взять этот класс и получить из таблицы «Пользователи» их часовой пояс и «вычислить» соответствующее время, мой код выглядел так:

//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");
    }
person Nelson Miranda    schedule 26.08.2008