Question

J'écris un programme qui doit envoyer un e-mail toutes les heures, mais à une heure locale pour l'utilisateur.

Disons que j'ai 2 utilisateurs dans des fuseaux horaires différents.John est à New York et Fred est à Los Angeles.Le serveur est à Chicago.Si je souhaite envoyer un e-mail à 18 heures locales à chaque utilisateur, je dois envoyer l'e-mail à John à 19 heures, heure du serveur, et à Fred à 16 heures, heure du serveur.

Quelle est une bonne approche dans .NET/Sql Server ?J'ai trouvé un fichier XML avec toutes les informations de fuseau horaire, j'envisage donc d'écrire un script pour l'importer dans la base de données, puis de l'interroger.

Modifier: J'ai utilisé « t4znet.dll » et j'ai fait toutes les comparaisons du côté .NET.

Était-ce utile?

La solution

Vous avez deux options :

  • Stockez l'heure ajustée pour l'action de courrier dans la base de données pour chaque utilisateur.Ensuite, comparez simplement l'heure du serveur avec l'heure stockée.Pour éviter toute confusion et tout problème de portabilité, je stockerais toutes les heures en UTC.Alors, envoyez un courrier lorsque SERVER_UTC_TIME() == storeUtcTime.
  • Stockez l'heure locale de chaque action de courrier dans la base de données, puis convertissez-la à la volée.Envoyer un courrier lorsque SERVER_UTC_TIME() == TO_UTC_TIME(storedLocalTime, userTimeZone).

Vous devez décider ce qui convient le mieux à votre candidature.Par exemple, si l’heure d’envoi est toujours la même pour tous les utilisateurs, il est plus logique d’opter pour l’option (2).Si les heures des événements peuvent changer entre les utilisateurs et même par utilisateur, cela peut faciliter le développement et le débogage si vous choisissez l'option (1).Dans tous les cas, vous devrez connaître le fuseau horaire de l’utilisateur.

*Ces appels de fonction sont évidemment pseudo, puisque je ne connais pas leurs invocations en T-SQL, mais ils devraient exister.

Autres conseils

Je suis un développeur PHP, je vais donc partager ce que je sais de PHP.Je suis sûr que .NET inclura quelque chose de similaire.

En PHP, vous pouvez obtenir des différences de fuseau horaire pour l'heure du serveur - comme vous l'avez suggéré d'envoyer les e-mails à des heures différentes sur le serveur.

Chaque fois que vous ajoutez un utilisateur, enregistrez son décalage horaire par rapport à l'heure du serveur (ou son fuseau horaire en cas de changement de fuseau horaire du serveur).

Ensuite, lorsque vous spécifiez une mise à jour, disposez d'une tâche automatisée (Cron pour les personnes LAMP) qui s'exécute toutes les heures pour vérifier si un e-mail doit être envoyé.Faites cela jusqu'à ce qu'il n'y ait plus d'e-mails à envoyer.

Vous pouvez compléter votre solution avec cet excellent article "Horloge mondiale et classe TimeZoneInformation", j'ai créé un service Web qui envoyait un fichier contenant des informations incluant l'heure locale et celle du destinataire. Ce que j'ai fait a été de modifier cette classe pour pouvoir gérer ce problème et cela a fonctionné parfaitement, exactement comme j'en avais besoin.

Je pense que vous pourriez suivre ce cours et obtenir du tableau "Utilisateurs" leur fuseau horaire et "calculer" l'heure appropriée, mon code ressemblait à ceci ;

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

Cette classe a un problème dans Windows Vista qui fait planter la fonction "FromIndex(int ​​index)" mais vous pouvez modifier le code, au lieu d'utiliser la fonction :

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

Vous pouvez le changer en ;

    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");
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top