Time (gestion du Temps)

Nous allons maintenant fabriquer une horloge numérique. (L'analogique sera un exercice !)

Jusqu'à présent, nous nous sommes concentrés sur les commandes. Avec les exemples HTTP et les exemples de génération de nombres aléatoires, nous avons demandé à Elm de faire un travail spécifique immédiatement, mais c'est une sorte de modèle bizarre pour une horloge. Nous voulons toujours connaître l'heure actuelle. C'est là que les abonnements (subscriptions) entrent en jeu !

Commencez par cliquer sur le bouton bleu "Edit" et regardez un peu le code dans l'éditeur en ligne.

import Browser
import Html exposing (..)
import Task
import Time



-- MAIN


main =
  Browser.element
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }



-- MODEL


type alias Model =
  { zone : Time.Zone
  , time : Time.Posix
  }


init : () -> (Model, Cmd Msg)
init _ =
  ( Model Time.utc (Time.millisToPosix 0)
  , Task.perform AdjustTimeZone Time.here
  )



-- UPDATE


type Msg
  = Tick Time.Posix
  | AdjustTimeZone Time.Zone



update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Tick newTime ->
      ( { model | time = newTime }
      , Cmd.none
      )

    AdjustTimeZone newZone ->
      ( { model | zone = newZone }
      , Cmd.none
      )



-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
  Time.every 1000 Tick



-- VIEW


view : Model -> Html Msg
view model =
  let
    hour   = String.fromInt (Time.toHour   model.zone model.time)
    minute = String.fromInt (Time.toMinute model.zone model.time)
    second = String.fromInt (Time.toSecond model.zone model.time)
  in
  h1 [] [ text (hour ++ ":" ++ minute ++ ":" ++ second) ]

Les nouveaux éléments proviennent tous du paquet elm/time. Passons en revue ces éléments !

Time.Posix et Time.Zone

Pour bien travailler avec le temps en programmation, nous avons besoin de trois concepts différents :

  • Le temps humain — C'est ce que vous voyez sur les horloges (8h du matin) ou sur les calendriers (3 mai). Parfait ! Mais si mon appel téléphonique est à 8 heures du matin à Boston, quelle heure est-il pour mon ami à Vancouver ? S'il est à 8 heures à Tokyo, est-ce que c'est le même jour à New York ? (Non !) Donc, entre les fuseaux horaires basés sur des frontières politiques en constante évolution et l'utilisation incohérente de l'heure d'été, le temps humain ne devrait jamais être stocké dans votre Model ou votre base de données ! Il ne sert qu'à l'affichage !
  • Le temps POSIX — Avec le temps POSIX, l'endroit où vous vivez ou la période de l'année n'ont pas d'importance. Il s'agit simplement du nombre de secondes écoulées depuis un moment arbitraire (en 1970). Où que vous alliez sur Terre, le temps POSIX est le même.

Donc pour montrer une heure à un être humain, vous devez toujours connaître Time.Posix et Time.Zone. Et rien d'autre ! Donc, tous ces histoires de "temps humain" sont pour la fonction view, pas pour le Model. En fait, vous pouvez le voir dans notre view :

view : Model -> Html Msg
view model =
  let
    hour   = String.fromInt (Time.toHour   model.zone model.time)
    minute = String.fromInt (Time.toMinute model.zone model.time)
    second = String.fromInt (Time.toSecond model.zone model.time)
  in
  h1 [] [ text (hour ++ ":" ++ minute ++ ":" ++ second) ]

La fonction Time.toHour prend Time.Zone et Time.Posix et nous renvoie un Int de 0 à 23 indiquant l'heure qu'il est dans votre fuseau horaire.

Il y a beaucoup plus d'informations sur la gestion des temps dans le README de elm/time. Lisez-le absolument avant de vous plonger dans la gestion du temps ! Surtout si vous travaillez avec des planifications, des calendriers, etc.

subscriptions

D'accord, mais comment obtenir notre Time.Posix ? Avec une souscription !

subscriptions : Model -> Sub Msg
subscriptions model =
  Time.every 1000 Tick

Nous utilisons la fonction Time.every :

every : Float -> (Time.Posix -> msg) -> Sub msg

Elle prend deux arguments :

  1. Un interval de temps en millisecondes. Nous spécifions 1000 qui signifie chaque seconde. Mais nous pourrions aussi spécifier 60 * 1000 pour chaque minute ou 5 * 60 * 1000 pour chaque cinq minutes.
  2. Un fonction qui transforme le temps actuel en Msg. Ainsi, à chaque seconde, le temps actuel va être transformé en un Tick <time> pour notre fonction update.

C'est le fonctionnement de base de n'importe quel abonnement. Vous donnez une configuration et vous décrivez comment produire des valeurs de type Msg. Pas si mal !

Task.perform

Obtenir Time.Zone est un peu plus compliqué. Notre programme a créé une commande avec :

Task.perform AdjustTimeZone Time.here

Parcourir la documentation de Task est la meilleure façon de comprendre cette ligne. Les documentations sont écrites pour expliquer les nouveaux concepts et je pense que ce serait trop digresser que d'inclure une moindre version de cette information ici. L'idée est simplement que nous commandons au runtime de nous donner le Time.Zone où que le code soit exécuté.

Exercices:

  • Ajoutez un bouton pour mettre l'horloge en pause, en désactivant l'abonnement Time.every.
  • Rendez l'horloge numérique plus jolie. Ajoutez peut-être quelques attributs style.
  • Utilisez elm/svg pour créer une horloge analogique avec une trotteuse rouge !

Source de cette pageSuggérer une modification

results matching ""

    No results matching ""