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

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

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

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

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

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
0
895
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

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

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

Ответ принят как подходящий

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

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

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

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

Вы можете дополнить свое решение этой превосходной статьей «Мировое время и класс 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");
    }

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