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

StackOverflow https://stackoverflow.com/questions/22319

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

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

Дополнить свое решение вы можете этой прекрасной статьей»Мировое время и класс 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");
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top