ASP.NET hace coincidir la fecha y hora local de los usuarios con la hora del sistema

Tengo algunos problemas para entender cómo hacer coincidir la fecha y hora actual de los usuarios con la hora del servidor.

Ejemplo: supongamos que tengo un sitio web donde los usuarios pueden registrarse. Una opción de perfil es que pueden seleccionar su zona horaria local. Para ello existe un menú desplegable desde donde pueden elegir la zona horaria correcta. Entonces, un usuario de China seleccionará probablemente (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi, otro usuario de Los Ángeles seleccionará (UTC-07:00) Mountain Time (EE. UU. y Canadá) (supongo) y un chico de París seleccionará (UTC+01:00) Bruselas, Copenhague, Madrid, París.

La aplicación web se ejecuta en un servidor en EE. UU. con su zona horaria específica...

Ahora... Todos estos usuarios querrán recibir una notificación por correo electrónico el próximo viernes a las 19:00 su zona horaria local!!!

Aquí ando perdido… definitivamente el próximo viernes a las 19:00 no es a la misma hora para todos estos usuarios…

¿Cómo puedo asignar la zona horaria de su perfil para que el servicio que se ejecuta en mi sitio envíe la notificación por correo electrónico el próximo viernes a las 19:00 de la zona horaria local del usuario?

Estoy en esta etapa en este momento... completando el menú desplegable con todas las zonas horarias para que los usuarios puedan seleccionar su zona horaria actual en su perfil.

Cuando la página se carga, el menú desplegable se completa con la zona horaria:

    protected void Page_Load(object sender, EventArgs e)
    {
        ddlUserTimeZone.DataSource = GetTimeZones();
        ddlUserTimeZone.DataTextField = "Name";
        ddlUserTimeZone.DataValueField = "ID";
        ddlUserTimeZone.DataBind(); 
    }

    public Collection<TimeZoneItem> GetTimeZones()
    {
        Collection<TimeZoneItem> timeZones = new Collection<TimeZoneItem>();
        foreach (var timeZoneInfo in TimeZoneInfo.GetSystemTimeZones())
        {
            timeZones.Add(new TimeZoneItem 
            { 
                TimeZoneName = timeZoneInfo.DisplayName, 
                TimeZoneID = timeZoneInfo.Id 
            });

        }

        return timeZones;
    }

    public struct TimeZoneItem
    {
        public string TimeZoneName { get; set; }
        public string TimeZoneID { get; set; }
    }

Ahora, ¿pueden ayudar con la coincidencia de la zona horaria del perfil con la hora actual para que el correo electrónico se envíe en el momento correcto?

Gracias de antemano!

preguntado el 30 de junio de 12 a las 20:06

Por cierto, Los Ángeles, EE. UU., está en la zona horaria del Pacífico, no en la de la Montaña. -

2 Respuestas

¿Estás configurando este servicio? En ese caso, ejecute sus servidores web y servidores de bases de datos en Universal Time Coordinated (UTC o Zulu), no una zona horaria local. Todo es mucho más fácil de manejar si haces eso. Aprendí esto de la manera difícil.

UTC solía llamarse hora media de Greenwich; es la zona horaria +00:00. No cambia para el horario de verano como lo hace la hora local de EE. UU. y Europa.

Esta cosa de la zona horaria es un fastidio, y vale la pena hacerlo bien. Algunos países tienen zonas horarias de media hora.

En cualquier caso, una vez que conozca la zona horaria preferida de cada usuario y la hora a la que desea recibir su notificación, puede convertir la hora local a UTC y almacenarla.

Intente algo como esto para obtener la hora y los minutos del usuario en UTC. (Las conversiones de zona horaria necesitan una fecha, porque dependen de las reglas del horario de verano. Hay una complicación más. El día en que una zona horaria cambie de la hora diurna a la estándar, o viceversa, la hora UTC para una notificación cambiará. La mayoría de las personas maneje esto volviendo a calcular la fecha y la hora UTC de la próxima notificación (la notificación de mañana) a medida que envían cada notificación. Considere este código.

TimeZoneInfo userLocal =            ;//user's time zone
int hour =                          ;//whatever the user wants
int minute =                        ;//whatever the user wants

DateTime tomorrow = DateTime.Now.AddDays(1);
int year = tomorrow.Year;
int month = tomorrow.Month;
int day = tomorrow.Day;
DateTime notificationTime = new DateTime(year,month,day,
                                         hour,minute,0, 
                                         DateTimeKind.Unspecified);
DateTime tomorrowNotificationTime = TimeZoneInfo.ConvertTimeToUtc(
                                         notificationTime,userLocal);

Esto debería proporcionarle la hora UTC que necesita para enviar la notificación de este usuario mañana, en la zona horaria correcta para la fecha de mañana.

Respondido 01 Jul 12, 00:07

Lo ideal es que DateTime se almacene en el servidor en formato UTC.

Tienes los siguientes datos en tu servidor

  • Información de la zona horaria del usuario.
  • La hora a la que el usuario necesita la notificación.
  • La hora local actual en su servidor.

    // Convert current local server time to UTC.
    var serverUtc = DateTime.UtcNow;
    
    // Convert UTC time to users local time. This gives you the date and time as per the user.
    var userTimeZone = TimeZoneInfo.GetSystemTimeZones()[0]; // just an example. Replace with actual value.
    var userCurrentTime = TimeZoneInfo.ConvertTime(serverUtc, userTimeZone);
    
    /*
    add a day to userCurrentTime till its Friday. Add/subtract minutes till its 7:00PM.
    */
    
    var expectedNotificationTimeUtc = TimeZoneInfo.ConvertTimeToUtc(userCurrentTime, userTimeZone);
    /*
    1. store the expectedNotificationTimeUtc as the time you want to send the email. 
    2. your service can check for users their expectedNotificationTimeUtc and 
         if the UtcNow is within an acceptable range of the that time, send the email.
    */
    

Respondido 01 Jul 12, 02:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.