¿Cómo enviar un correo electrónico a la hora local de un usuario en .NET/Sql Server?

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

  •  09-06-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un programa que necesita enviar un correo electrónico cada hora en punto, pero a una hora local para el usuario.

Digamos que tengo 2 usuarios en diferentes zonas horarias.John está en Nueva York y Fred está en Los Ángeles.El servidor está en Chicago.Si quiero enviar un correo electrónico a las 6 p.m. localmente a cada usuario, tendría que enviar el correo electrónico a John a las 7 p.m. hora del servidor y a Fred a las 4 p.m. hora del servidor.

¿Cuál es un buen enfoque para esto en .NET/Sql Server?Encontré un archivo xml con toda la información de la zona horaria, por lo que estoy considerando escribir un script para importarlo a la base de datos y luego consultarlo.

Editar: Utilicé “t4znet.dll” e hice todas las comparaciones en el lado .NET.

¿Fue útil?

Solución

Tienes dos opciones:

  • Almacene el tiempo ajustado para la acción de correo en la base de datos para cada usuario.Luego simplemente compare la hora del servidor con la hora almacenada.Para evitar confusiones y problemas de portabilidad, almacenaría todas las horas en UTC.Entonces, envíe correo cuando SERVER_UTC_TIME() == almacenadoUtcTime.
  • Almacene la hora local para cada acción de correo en la base de datos y luego conviértala sobre la marcha.Enviar correo cuando SERVER_UTC_TIME() == TO_UTC_TIME(storedLocalTime, userTimeZone).

Debe decidir qué tiene más sentido para su aplicación.Por ejemplo, si el tiempo de envío del correo es siempre el mismo para todos los usuarios, tiene más sentido optar por la opción (2).Si los tiempos de los eventos pueden cambiar entre usuarios e incluso entre usuarios, puede facilitar el desarrollo y la depuración si elige la opción (1).De cualquier manera necesitarás saber la zona horaria del usuario.

*Estas llamadas a funciones son obviamente pseudo, ya que no conozco sus invocaciones en T-SQL, pero deberían existir.

Otros consejos

Soy desarrollador de PHP, así que compartiré lo que sé sobre PHP.Estoy seguro de que .NET incluirá algo similar.

En PHP, puede obtener diferencias de zona horaria para la hora del servidor; como sugirió, enviaría los correos electrónicos en diferentes momentos en el servidor.

Cada vez que agrega un usuario, guarda su diferencia horaria con respecto a la hora del servidor (o su zona horaria en caso de que la zona horaria del servidor cambie).

Luego, cuando especifique una actualización, tenga una tarea automatizada (Cron para personas de LAMP) que se ejecute cada hora para verificar si es necesario enviar un correo electrónico.Haga esto hasta que no queden correos electrónicos para enviar.

Puedes complementar tu solución con este excelente artículo "Reloj mundial y la clase TimeZoneInformation", hice un webservice que enviaba un archivo con información que incluía la hora local y del receptor, lo que hice fue modificar esta clase para poder manejar ese tema y funcionó perfecto, exactamente como lo necesitaba.

Creo que podrías tomar esta clase y obtener de la tabla "Usuarios" la zona horaria de ellos y "calcular" el tiempo apropiado, mi código era así;

//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 clase tiene un problema en Windows Vista que bloquea la función "FromIndex(int ​​index)" pero puedes modificar el código, en lugar de usar la función:

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

Puedes cambiarlo a;

    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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top