Pergunta

Estou escrevendo um programa que precisa enviar um e-mail de hora em hora, mas em um horário local para o usuário.

Digamos que tenho 2 usuários em fusos horários diferentes.John está em Nova York e Fred está em Los Angeles.O servidor está em Chicago.Se eu quiser enviar um e-mail às 18h local para cada usuário, terei que enviar o e-mail para John às 19h, horário do servidor, e para Fred, às 16h, horário do servidor.

Qual é uma boa abordagem para isso no .NET/Sql Server?Encontrei um arquivo xml com todas as informações de fuso horário, por isso estou pensando em escrever um script para importá-lo para o banco de dados e depois consultá-lo.

Editar: Usei “t4znet.dll” e fiz todas as comparações no lado .NET.

Foi útil?

Solução

Você tem duas opções:

  • Armazene o tempo ajustado para a ação de email no banco de dados para cada usuário.Depois é só comparar a hora do servidor com a hora armazenada.Para evitar confusão e problemas de portabilidade, eu armazenaria todos os horários em UTC.Portanto, envie e-mail quando SERVER_UTC_TIME() == armazenadoUtcTime.
  • Armazene a hora local de cada ação de email no banco de dados e converta instantaneamente.Enviar e-mail quando SERVER_UTC_TIME() == TO_UTC_TIME(storedLocalTime, userTimeZone).

Você deve decidir o que faz mais sentido para sua aplicação.Por exemplo, se o horário de envio for sempre o mesmo para todos os usuários, faz mais sentido escolher a opção (2).Se os horários dos eventos puderem mudar entre usuários e até mesmo por usuário, o desenvolvimento e a depuração poderão ser mais fáceis se você escolher a opção (1).De qualquer forma, você precisará saber o fuso horário do usuário.

*Essas chamadas de função são obviamente pseudo, já que não conheço suas invocações em T-SQL, mas deveriam existir.

Outras dicas

Sou um desenvolvedor PHP, então compartilharei o que sei sobre PHP.Tenho certeza de que o .NET incluirá algo semelhante.

No PHP você pode obter diferenças de fuso horário para o horário do servidor - como você sugeriu, enviaria os e-mails em horários diferentes no servidor.

Cada vez que você adiciona um usuário, salve seu deslocamento de horário em relação ao horário do servidor (ou seu fuso horário, caso o fuso horário do servidor mude).

Então, quando você especificar uma atualização, tenha uma tarefa automatizada (Cron para pessoas do LAMP) que é executada a cada hora, verificando se um e-mail precisa ser enviado.Faça isso até que não haja mais e-mails para enviar.

Você pode complementar sua solução com este excelente artigo "Relógio mundial e a classe TimeZoneInformation", fiz um webservice que enviava um arquivo com informações que incluíam o local e o horário do receptor, o que fiz foi modificar essa classe para poder resolver aquele problema e funcionou perfeitamente, exatamente como eu precisava.

Acho que você poderia pegar essa aula e obter na tabela "Usuários" o fuso horário deles e "calcular" o horário apropriado, meu código ficou assim;

//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();

Esta classe tem um problema no Windows Vista que trava a função "FromIndex(int ​​index)", mas você pode modificar o código, em vez de usar a função:

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

Você pode alterá-lo para;

    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");
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top