Comment puis-je gérer les fuseaux horaires dans ma webapp?

107

Je recherche une meilleure compréhension de la user story suivante:

John travaille à Sidney. À 9h00 du matin, il enregistre un événement dans une application Web qui s'exécute sur un serveur à Zurich. Le lendemain, il se rend à New York pour une réunion d'urgence au cours de laquelle l'événement devrait être discuté. Au cours de la réunion, il recherche l'événement par date et heure.

À mon avis, il y a au moins deux problèmes ici:

  1. Comment enregistrer les horodatages dans la base de données
  2. Comment dois-je les présenter dans l'interface utilisateur

Lorsque John recherchera l'événement, il saura qu'il s'est produit à 9h00, mais que doit-il entrer dans le navigateur Web? Il ne trouvera rien quand il saisira simplement "9:00" comme horodatage, car cela pourrait être l'heure de Zurich ou de New York (puisque l'événement n'a pas été trouvé, l'application n'a aucun moyen de savoir que cela s'est passé à Sidney, donc il ne peut pas sélectionner automatiquement le fuseau horaire correct).

Quel est le bon moyen de demander à l'utilisateur un horodatage pouvant inclure le fuseau horaire?

Le deuxième problème est de savoir comment afficher les résultats. Si des équipes du monde entier ont besoin de discuter de l'événement (et de trouver des événements connexes, pensez à une attaque de cracker qui cible plusieurs sites partout dans le monde à la fois).

Quel est un bon exemple pour afficher des horodatages qui pourraient avoir été créés dans un fuseau horaire différent?

Remarque: veuillez vous concentrer sur la facilité d'utilisation de l'exigence. Je peux comprendre moi-même le mappage de la base de données. Actuellement, je ne suis pas sûr du flux de travail. Il doit demander / présenter les informations nécessaires d'une manière non intrusive / intuitive. Si vous le pouvez, indiquez un lien vers une application Web existante qui résout déjà ce problème.

Aaron Digulla
la source
5
Stack Overflow résout ce problème en mettant tout en UTC. Pas toujours pratique, mais c'est vraiment sans ambiguïté, pas difficile à mettre en œuvre et fonctionne.
Ry-
2
L'UTC est tentant mais OTOH, SO n'a jamais besoin de synchroniser les événements sur plusieurs fuseaux horaires.
Aaron Digulla
3
Que se passe-t-il si l'un des pays impliqués adopte une législation qui change l'heure locale après la planification de l'événement, mais avant que l'événement ne se produise? Comment le système devrait-il gérer cela? en.wikipedia.org/wiki/…
Julius Musseau
1
Ce type de question de fuseau horaire classique a été tellement battu à mort pendant des décennies sur Internet et sur papier, je suis surpris de voir des commentaires et des primes aussi vifs sur cette question!
BenSwayne
2
Mon j'ajoute un point supplémentaire de complexité en soulignant l'évidence, à savoir que la plupart des pays occidentaux changent de fuseau horaire deux fois par an ("Daylight Savings Time"), et que les règles pour le moment où cela se produit ne sont ni uniformes au niveau mondial ni nécessairement triviales, algorithmiquement parlant?
fr13d

Réponses:

100

Le problème du stockage des horodatages est simple: stockez-les au format UTC.

En ce qui concerne leur affichage, il serait logique de prendre le paramètre de fuseau horaire de l'appareil et de l'utiliser comme fuseau horaire actuel. Cela dit, il devrait y avoir une liste déroulante de fuseau horaire à côté de la case "Heure d'entrée", qui par défaut est le fuseau horaire actuel de l'appareil, afin que l'utilisateur puisse le modifier si nécessaire.

La majorité de vos utilisateurs ne changeront probablement pas beaucoup, voire pas du tout. Pour la plupart, la situation que vous avez décrite est rare. En implémentant une liste déroulante avec une valeur par défaut appropriée, vous devriez être en mesure de rendre les choses assez faciles pour ceux qui se déplacent (car ils ont généralement une meilleure compréhension des fuseaux horaires qu'un non-voyageur).

En fait, il serait encore mieux d'enregistrer le fuseau horaire sur lequel l'appareil était défini lors de la première exécution de votre application, puis de voir si cela change un jour. Si cela change, alors l'utilisateur est probablement un voyageur et bénéficierait probablement de la liste déroulante du fuseau horaire. Sinon, n'affichez pas la liste déroulante et choisissez par défaut le fuseau horaire de l'appareil (car l'utilisateur n'a pas besoin de les connaître). Dans les deux cas, ayez un paramètre dans l'application qui permet à l'utilisateur d'afficher / masquer manuellement la liste déroulante du fuseau horaire.


Pour résumer ce qui précède:

  • Lors de la première exécution, enregistrez le fuseau horaire sur lequel l'appareil est défini.
  • Utilisez ce fuseau horaire comme fuseau horaire par défaut. Supposons toujours ce fuseau horaire.
  • Si l'appareil change de fuseau horaire, ajoutez une liste déroulante pour sélectionner le fuseau horaire dans lequel l'événement se trouve, par défaut sur le fuseau horaire de l'appareil.
  • Ajoutez une option pour afficher / masquer manuellement cette liste déroulante de fuseau horaire.
  • Stockez toujours les horodatages en UTC.
Niet the Dark Absol
la source
Qu'entend-on par "fuseau horaire" Il semble utilisé de manière ambiguë. Cela ressemble à une référence: en.wikipedia.org/wiki/Tz_database D'après ce que je peux dire, un "fuseau horaire" est "Area / Location", par exemple "America / New_York". Cela semble être géographique, ce qui est excellent car, par exemple, America / Los_Angeles signifie à la fois PST et PDT selon que le globe fonctionne à l'heure d'été. Et si tel est le cas, la question est de savoir comment comptabiliser les changements semestriels de décalage UTC pour les zones? Aussi comment appelons-nous ces appreviations puisqu'elles ne sont pas des "zones" géographiquement exactes?
iJames
C'est une excellente réponse. Existe-t-il une bonne pratique sur la façon de stocker les informations de fuseau horaire? Par exemple - lequel serait le meilleur - «PST» ou «Amérique / Pacifique»? Comment pourrai-je facilement convertir un horodatage UTC en fuseau horaire utilisateur capturé? Toutes les meilleures pratiques à ce sujet seraient appréciées.
Patthebug
27

Dans nos applications, nous stockons généralement le fuseau horaire de l'utilisateur lors de notre première inscription, comme souvent vu sur les sites de forum, et affichons toujours l'heure avec le fuseau horaire .

Quant à stocker les dates, UTC est la voie à suivre. Convertissez-le en UTC et collez-le dans la base de données. Lors de la récupération, convertissez simplement l'heure dans le fuseau horaire défini pour l'utilisateur.

J'ai dû résoudre un cas d'utilisation similaire, où des notifications personnalisées, telles que «Bonne année», pouvaient être envoyées à tous les utilisateurs de l'application Web. Étant donné que les utilisateurs sont répartis dans le monde entier, nous devions afficher la notification en fonction du fuseau horaire. Le stockage de l'horodatage en UTC a bien servi notre objectif, sans hoquet.

Dans votre cas d'utilisation, si vous ne stockez pas le fuseau horaire de l'utilisateur quelque part, vous ne pourrez jamais renvoyer avec précision vos résultats de recherche sans demander l'entrée de l'utilisateur, à moins que vous ne commenciez à utiliser une sorte de détection d'emplacement comme le fait gmaps, mais ce n'est pas le cas. t fiable. Vous devrez donc demander le fuseau horaire à chaque fois pour vous assurer que l'utilisateur sait ce qu'il entre sur le site Web.

Si vous disposez d'informations sur le fuseau horaire, toute l'application Web doit être exécutée avec le paramètre de fuseau horaire. Par conséquent, lorsque l'utilisateur recherche 9h00, il effectuera une recherche avec le fuseau horaire de Sydney. D'autre part, s'il crée un événement alors qu'il est assis à New York, il créera un événement avec le fuseau horaire de Sydney. Nous résolvons de tels cas en affichant toujours le fuseau horaire tout en affichant les dates.

J'espère que ça aide! :)

Varun Achar
la source
Je pense qu'avec l'ajout d'un menu déroulant pour les fuseaux horaires lors de la recherche et de la création d'événements, c'est la voie à suivre. (quand j'ai besoin de rechercher l'événement créé par un collègue à New York, je ne veux pas faire le calcul moi-même)
RasmusWL
C'est une excellente réponse. Existe-t-il une bonne pratique sur la façon de stocker les informations de fuseau horaire? Par exemple - lequel serait le meilleur - «PST» ou «Amérique / Pacifique»? Comment pourrai-je facilement convertir un horodatage UTC en fuseau horaire utilisateur capturé? Toutes les meilleures pratiques à ce sujet seraient appréciées.
Patthebug
11
  1. UTC. Rester simple.

  2. Utilisez le fuseau horaire le plus pertinent pour l'utilisateur.

    Si vous savez que l'utilisateur se rendra ou se rendra à Sydney pour l'événement, il pensera à ce fuseau horaire lors de l'organisation du transport vers l'événement. Le fait qu'ils soient actuellement à New York est en grande partie hors de propos. Et bien sûr, si votre application affiche des dates dans une variété de fuseaux horaires, elle doit toujours afficher le fuseau horaire à côté de la date, par exemple 09h00 EST .

    Si cela n'encombre pas trop votre interface, vous pouvez afficher les dates dans le fuseau horaire de l'événement et le fuseau horaire local, par exemple 2012-06-13 09:00 EST (2012-06-12 19:00 EDT) .

    Je dirais que la recherche est un problème similaire, avec une mise en garde: nous pouvons tolérer les faux positifs (obtenir un résultat auquel nous ne nous attendions pas), mais nous ne pouvons pas supporter les faux négatifs (ne pas obtenir le résultat que nous attendions).

    Encore une fois, je me concentrerais sur la recherche du fuseau horaire le plus pertinent pour l'utilisateur (par exemple, le fuseau horaire de l'événement), et donnerais la priorité à ces résultats dans les résultats de la recherche, mais vous pouvez également renvoyer des événements qui correspondent à d'autres fuseaux horaires pertinents pour l'utilisateur (par exemple heure locale). Si vous faites cela, vous devez afficher la date de l'événement dans le fuseau horaire correspondant, en particulier si vous mettez le texte correspondant en surbrillance.

Richard Poole
la source
7

Ici, je donne des suggestions pour une meilleure convivialité sans trop me soucier de la faisabilité de la mise en œuvre.
1. Pour le premier numéro de stockage des événements dans db, tout le monde serait d'accord pour le stocker en UTC

2. Pour donner la meilleure expérience utilisateur, enregistrez l'historique du fuseau horaire de l'utilisateur. Si vous pouviez enregistrer l'horodatage du changement de fuseau horaire, c'est encore mieux. Cela nous permettra de donner à l'utilisateur la liberté d'interroger sans spécifier explicitement le fuseau horaire à chaque fois.

Donc, avec ces fonctionnalités, voyons comment la requête de recherche de seulement "9.00" par John sera traitée:
Avec les fonctionnalités mentionnées ci-dessus, je sais maintenant que John a été dans 2 fuseaux horaires jusqu'à la date (ou obtenir la liste des fuseaux horaires pour la période mentionnée). Je vais donc cacher 9h00 du fuseau horaire de Sydney à UTC, lancer une requête. Convertissez également 9,00 du fuseau horaire NewYork en UTC, lancez une requête. En conséquence, je montrerai 2 lignes à John affichant ce qu'il a fait à 9h00 à Sydney et à 9h00 à New York. La ligne de New York sera vide dans ce cas, mais je pense qu'elle devrait encore être montrée à l'utilisateur, juste pour l'informer que nous avons également recherché ce fuseau horaire.

3. Quel est le bon moyen de demander à l'utilisateur un horodatage pouvant inclure le fuseau horaire?

Si son fuseau horaire a été récemment modifié, chaque fois qu'il se connecte à l'application, une notification doit être envoyée pour que votre fuseau horaire par défaut soit changé en fuseau horaire natif.
Lors de la création d'un événement, disons que l'utilisateur sélectionne le fuseau horaire dans la liste déroulante.Ne charge pas l'utilisateur en donnant des options de tous les fuseaux horaires du monde.La première option de la liste déroulante doit être le fuseau horaire actuel de l'appareil de l'utilisateur. après cela, les fuseaux horaires de son historique des fuseaux horaires, puis UTC et puis les fuseaux horaires restants qu'il n'a jamais utilisés jusqu'à ce jour.

4 Comment afficher les résultats, si des équipes du monde entier ont besoin de discuter de l'événement:

Je voudrais diviser ce cas d'utilisation entre le nombre d'équipes 2 ou plus de 2.
Pour seulement 2 équipes, je préférerais que chaque équipe voit l'horodatage dans son fuseau horaire local et le fuseau horaire de l'autre équipe. (Personnellement, je préfère parler dans le fuseau horaire de la personne à l'autre bout pour sa commodité lors de la planification d'une réunion). Pour plus de 2 équipes, il est préférable de considérer le fuseau horaire plus commun, à savoir UTC. Donc, dans ce cas, chaque utilisateur devrait voir l'horodatage dans 2 fuseaux horaires, en UTC et dans son fuseau horaire par défaut.

Ces suggestions sont données avec l'intention que l'utilisateur ne doive effectuer aucun calcul dans son heure locale, mais en même temps, il devrait être en mesure de communiquer couramment avec d'autres utilisateurs dans leur fuseau horaire préféré.

Pranalee
la source
2
+1 C'est une idée très intéressante car je sais que l'utilisateur a entré un événement à 9h00 à Sidney, donc quand le même utilisateur recherche une heure (sans fuseau horaire explicite), je devrais supposer qu'il veut dire "où j'étais cette fois "
Aaron Digulla
4

Ok, j'ai une approche différente des autres:

Premièrement, j'ai supposé quelques choses à l'avance.

La personne qui annonce un événement a un smartphone (s'il s'agit d'un navigateur, je n'ai pas à faire ces hypothèses) avec:

  1. GPS

  2. Capacité HTML5.

  3. Capacité Javascript

Comment dois-je enregistrer les horodatages dans la base de données?

Solution: évidemment UTC , j'ai superposé la procédure ci-dessous:

Étape 1. Utilisez la géolocalisation de l'utilisateur à l'aide de l'API de géolocalisation

    window.onload = getMyLocation;

    function getMyLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(displayLocation);
        } else {
            alert("Oops, no geolocation support");
        }
    }

    function displayLocation(position) {
        var latitude = position.coords.latitude;
        var longitude = position.coords.longitude;
        var div = document.getElementById("location");
        div.innerHTML = "You are at Latitude: " + latitude + ", Longitude: " + longitude;
    }

Étape 2. Donnez le (Long, Lat) comme argument à certains des api (Lat, Long) de TimeZone comme l' API Yahoo (utilisez Flag R pour convertir Latitude en Fuseau horaire) pour obtenir le fuseau horaire des utilisateurs.

=> Le fuseau horaire des utilisateurs est déterminé sans entrée de l'utilisateur (j'utilise ceci parce que vous ne pouvez pas simplement supposer que l'utilisateur connaît le fuseau horaire de l'endroit où il vit, je ne connaissais mon fuseau horaire qu'après quelques mois ou quelque chose à l'endroit: P, assez stupide! )

La table de chaque événement a Timezone, Eventet peut donc également avoir CityName Ensuite, créez une autre table de base de données avec une classification basée sur CityNames. Donc ici l'utilisateur aura deux colonnes

|---------------------------------------|
|_____NewYork________|______Sydney______|
|                    |                  |
|Event 1             |  Event 2         |
|____________________|__________________| 

Pour l'interface utilisateur

=> utiliser l'API Google Calendar ou certaines des API Calendar

Lectures connexes:

  1. Déterminez le fuseau horaire à partir de la latitude / longitude sans utiliser de services Web comme Geonames.org

  2. Recherche de fuseau horaire à partir de la latitude et de la longitude

Je sais que c'est juste pour montrer une idée de la façon de résoudre ce problème. Mais voyez à quel point cela devient précis et léger pour les utilisateurs lorsque le fuseau horaire est déterminé à l'aide des API de l'appareil

J'espère que ça aide!

uday
la source
4
Il est assez facile de trouver le fuseau horaire de quelqu'un sans géolocalisation. new Date().getTimezoneOffset()le donne en quelques minutes derrière UTC.
Ry-
@minitech, c'est vrai, mais que se passe-t-il si l'événement se passe à New York et quelque part au sud où son fuseau horaire est le même. J'utilise la géolocalisation afin que vous puissiez localiser la ville (même avec précision), le fuseau horaire en un seul coup et baser ma table de base de données dessus. Je souhaite minimiser les entrées utilisateur à l'aide de l' API de l'appareil pour augmenter l'efficacité de l'application.
uday
Alors? L'heure sera la même aux deux endroits, il n'y a donc pas de problème. -1
Ry-
@minitech, vous pouvez voir ce lien expliquant pourquoi je recommande d'utiliser les API de l'appareil plutôt que d'autres méthodes. webdirections.org/sotmw2011
jeudi
2
D'accord, mais le problème ici n'est pas d'obtenir la ville de l'utilisateur. Il ne s'agit que d'obtenir le fuseau horaire. Utiliser une API de géolocalisation qui ne fonctionne pas sur tous les navigateurs / ordinateurs, puis rediriger vers une API de calendrier, est un mauvais moyen d'obtenir le fuseau horaire d'un utilisateur lorsqu'il est disponible dans une seule ligne de code.
Ry-
2

Pour ce cas particulier, je stockerais à la fois l'heure locale et l'heure UTC. UTC est un peu majeur et utilisé pour la synchronisation et la conversion de l'heure en fuseau horaire actuel. Local est utilisé pour les recherches et pour des informations supplémentaires, telles que:

Vous avez une réunion:

12:00 Monday (UTC)
9:00 Monday (Sydney, creation local time)
11:00 Monday (Zurich, local time)

ou quelque chose comme ça. L'autre moyen consiste à stocker le fuseau horaire de création et à le convertir au moment de l'exécution (c'est particulièrement préférable au cas où l'utilisateur changerait l'heure de la réunion). Dans tous les cas, la raison principale est de pouvoir restaurer l'heure de création d'origine afin que l'utilisateur puisse s'y référer.

Petr Abdulin
la source
2
  1. Comment enregistrer les horodatages dans la base de données

Lors de la création de l'événement, je stockais l'heure UTC et le fuseau horaire local (aka creation time zone). J'utiliserais ce que j'ai stocké pour convertir l'heure UTC en heure locale (aka creation time) et le stocker avec l'heure UTC et creation time zone.

REMARQUE: je peux stocker l'heure locale dès le départ, mais lorsque l'utilisateur recherche un événement, j'espère qu'une conversion en heure locale existe. J'espère également que le serveur pourra détecter dans quel fuseau horaire se trouve le client.

  1. Comment dois-je les présenter dans l'interface utilisateur

Lorsqu'un utilisateur recherche pour « 9:00 », je voudrais rechercher des événements qui incluent « 9:00 » soit UTC OU creation time OU heure locale. Pour les résultats, j'afficherais un tableau de résultats dans creation time(Ceci est destiné à afficher les horodatages qui peuvent avoir été créés dans un fuseau horaire différent, car nous supposons que l'utilisateur cherche à quelle heure il a créé un événement pour où qu'il soit.) et affichez un deuxième tableau des résultats ci-dessous avec les résultats associés, peut-être avec l'en-tête "Pas ce que vous recherchez? Voir les résultats associés" (ceux-ci incluent les résultats restants de l'heure UTC et locale).

Dans l'ensemble, j'afficherais l'heure UTC, l'heure locale, le creation timeet le creation time zone(c'est-à-dire l'heure locale et le fuseau horaire de l'événement où il a été créé) triés par heure UTC, afin que vous puissiez voir quel événement vient en premier, au cas où deux différents les événements étaient prévus à 9h00 dans deux fuseaux horaires différents.


la source
1
+1 J'aime l'idée de montrer tous les événements dans tous les fuseaux horaires où l'heure locale correspond; Je ne suis juste pas satisfait du SQL ( BETWEENconditions 24x ).
Aaron Digulla