Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby, Rails, et les dates

Ruby, Rails, et les dates

Ayant été victime d'un bug lié à l'heure d'été, j'ai commencé à creuser le sujet. Cette présentation de 20 minutes couvre les bases de la gestion du temps en informatique, avec des exemples de code en Ruby et Rails. Et des memes, on ne se refait pas !

Goulven Champenois

October 30, 2024
Tweet

More Decks by Goulven Champenois

Other Decks in Programming

Transcript

  1. - date + début - date + fi n Bug

    au passage à l’heure d’été Saisie simplifiée
  2. Fusionner Date et Time # DON'T DO THAT! - date.change(hour:

    time.hour, min: time.min) # OR - Time.local(date.year, date.month, date.day, time.hour, time.min, time.sec) # DO THIS INSTEAD + time.change(year: date.year, month: date.month, day: date.day) # OR + Time.utc(date.year, date.month, date.day, time.hour, time.min)
  3. Quand du code manipule les heures,
 toujours véri fi er

    qu’il gère l’heure d’été. 👀 Moralité
  4. J’ai bien lu +9,5 !? 24 38 fuseaux horaires Décalés

    de 60, 45, 30, 
 ou 15 minutes Et tout sauf linéaires…
  5. Mais pourquoi 38 fuseaux ? Parce que le temps c’est

    de l’argent, —et de la politique, aussi.
  6. Tout ça, c’est 
 à cause des rails (et des

    trains) Besoin d’horaires (départ et arrivée) Besoin que les villes aient toutes la même heure
  7. Quand les utilisateurs 
 vivent à di ff érents endroits,


    toujours prendre en compte
 les fuseaux horaires. 👀 Moralité
  8. TimeWithZone ~= Time Utilise la gemme TZ-info Gère les fuseaux

    horaires Gère aussi l’heure d’été ActiveSupport::TimeWithZone 🫶
  9. Manipuler les dates et les heures # DON'T DO THAT!

    - Time.now - Time.parse # DO THIS INSTEAD + Time.zone.now + Time.zone.parse https://thoughtbot.com/blog/its-about-time-zones
  10. Afficher une date ou une heure # DON'T DO THAT!

    - I18n.l(time) # DO THIS INSTEAD + I18n.l(time.in_time_zone(current_user.time_zone)) # OR, in ApplicationController + around_action :use_time_zone, if: :current_user + def use_time_zone(&block) + Time.use_zone(current_user.time_zone, &block) + end
  11. Convertit les timestamps côté client Facilite la gestion du cache

    Gère l’I18N côté client Permet d’écrire « il y a X secondes, minutes… » local_time https://github.com/basecamp/local_time
  12. Année solaire ou sidérale ? Année solaire : 1 tour

    de soleil Année sidérale : 365 rotations Di ff érence : environ 5 heures ! -> années bissextiles
  13. Un peu d’histoire… ✦ Calendrier Julien ✦ Mis en place

    par Jules César ✦ Introduit en 46 avant JC (l’autre) ✦ Décalage : 11 minutes/an !
  14. Le calendrier Grégorien ✦ Introduit en 1582 ✦ Par le

    pape Grégoire XIII ✦ Durée : 365,2422 jours/an ✦ C’est celui qu’on utilise ! ✦ 350 ans pour que tout le monde l’applique !
  15. Les années bissextiles Multiple de 4 Mais PAS de 100

    SAUF multiple de 400 Exemples : 2000, 2020, 2024… 2100
  16. Le 29 février 2024… Nouvelle-Zélande : pas d’essence Suède :

    pas de CB au supermarché Japon : pas de permis de conduire Chine : pas de mariage Paris : pas de lampadaires Etc…
  17. Modifier une date # DON'T DO THAT! - Date.new(2024, 2,

    29).change(year: 2023) # => Date::Error: invalid date # WARNING Time.new(2024, 2, 29).change(year: 2023) # => 01 March 2023 # DO THIS INSTEAD + Date.new(2024, 2, 29).advance(years: -1) # OR + Date.new(2024, 2, 29) - 1.year # => 28 February 2023
  18. Jours, heures… secondes ! ✦ Décalage du calendrier grégorien :

    26 secondes/an ✦ Décalage année solaire/sidérale : variable Du coup, on ajoute des 
 secondes intercalaires.
 Qu’est-ce qui pourrait mal se passer ? 🫣
  19. TL;DR # DON'T DO THAT! - t2 - t1 #

    => -1s # DO THIS INSTEAD + (t2 - t1).clamp(0, t2) # => 0 # Et attention aux divisions par zéro !
  20. Quand du code manipule des durées,
 toujours s’attendre à l’absurde.

    Le temps informatique 
 n’est pas linéaire. 👀 Moralité
  21. Étend Date et Time date + 1.month 3.weeks_ago before? et

    after? Ajoute aussi all_day, all_week, all_month… Et même on_weekend? DateAndTime::Calculations 🫶
  22. Les formats de dates AAAA/MM/JJ MM-JJ-AAAA JJ/MM/AA mois/JJ AAAA/ jour

    de l’année AA-W15-6 Calendrier bouddhiste (+543 ans) 🧘
  23. Temps du serveur / de la VM Temps de la

    base de données Temps de Rails (UTC par défaut) Temps navigateur Le temps est relatif
  24. Pour manipuler dates, heures ou durées
 toujours utiliser les méthodes

    disponibles ! Et ne jamais faire con fi ance 
 aux utilisateurs 😉 👀 Moralité
  25. Standard international Interoperable (JS, PHP, Java…) Lisible, triable, non ambigu

    Parfait pour les APIs ! ISO 8601 require 'time' Time.zone.now.iso8601 Time.iso8601(string)
  26. L’heure d’été Les fuseaux horaires Les années bissextiles Les formats

    de dates Les « failles » temporelles 👀 Toujours tester…