2008-08-22 5 views
3

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

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

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

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

ответ

0

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

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

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

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

0

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

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

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

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

0

Вы можете дополнить свое решение этой замечательной статьей «World Clock and the TimeZoneInformation class», я сделал веб-сервис, который отправил файл с информацией, которая включала время локального и приемного времени, что я сделал, чтобы изменить этот класс, чтобы я мог справиться с этой проблемой и он работал идеально, точно так, как мне было нужно.

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

//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 индекс)» функции, но вы можете изменить код, вместо того, чтобы использовать функцию:

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"); 
    }