Web開発におけるタイムゾーンの取り扱い


私はあなたに日付と時刻を扱うにはうそをつくことは、人間が対処する必要があります最もトリッキーな分野の一つです、プログラミングでは、これは異なっていません.あなたのアプリケーションが世界の異なる点でユーザーに属しているイベントで働いているならば、あなたはタイムゾーンと多分多分1回以上起こるかもしれないイベントを保存するために再発を加える必要があります.
  • 日付をDBに保存する方法.
  • 再発の対処法
  • ユーザーのローカル時刻に時間を変換する場所.
  • これらのタスクを支援するライブラリ.
  • それに入りましょう.

    日付をDBに保存する方法
    別の場所にユーザーを持っているときにデータベース内の日付を保存するための最も一般的なアプローチは、クロックと時間規制のための主要な時間標準であるUTC(コーディネートされた普遍的な時間)で時間を節約していますが、これはあなたが特定のユースケースをチェックしなければならない最善の解決策ではありません例えば:
  • ユーザーが日付を保存している場所から?
  • すべてのユーザーが日付またはちょうど1つの管理を保存する必要がありますか?
  • どこでイベントが起こっている?
  • 例えば、最近、私の国の教会のためのテレビ・スケジュール・プラグインをしなければなりませんでした.
    しかし、一方、私の仕事では、ユーザーが世界中でイベントを保存して、編集することができるケースがありました

    日付再発を管理する方法
    私は最初のWeb開発の問題に直面するとき、私は常に私は私のユーザーエクスペリエンス、インターフェイスを与えるために使用するアプリを探して、時にはAPIのアプリは、サードパーティ製のアプリと統合する準備ができている場合.それで、すぐにブラウザを開き、Googleカレンダーを探しました.
    彼らは再帰を保存するためのかなり簡単なインターフェイスを持っており、それらはAPIドキュメントでR規則に言及しました.R規則は、再帰に対処するための標準であり、JavaScriptではほとんどのプログラミング言語でいくつかの実装がありますrrule.js というのが答えです.
    以下は2021年9月30日までのイベントの例です
    // To create the rrule
    const rule = new RRule({
      freq: RRule.WEEKLY,
      dtstart: new Date(Date.UTC(2021, 8, 18, 8, 17, 0)),
      until: new Date(Date.UTC(2021, 8, 30, 8, 17, 0)),
      count: 30,
      interval: 1
    });
    
    // to get the RRule in string
    rule.toString();
    // DTSTART:20210918T081700Z
    // RRULE:FREQ=WEEKLY;UNTIL=20210930T081700Z;COUNT=30;INTERVAL=1;WKST=MO
    
    // to get the ocurrence
    rule.all();
    
    rrule文字列をデータベース内のフィールドに保存できます.しかし、個々のフィールドとしてRulesのすべてのプロパティを保存する方が良いと思いますfrequency , interval , etcからデータベースへのイベントの問い合わせを行います.
    時間をユーザーの現地時間に変換する場所は?
    時間の変換は、視覚的な側面であり、場合でも、モバイルとWebアプリケーションへのAPIを提供しているそれらの変換からあなたのバックエンドのコードを解放し、フロントエンドを扱うことができます.を使用すると、Webブラウザから直接ユーザーのローカルタイムゾーンを検出することができますIntl API.
    Intl.DateTimeFormat().resolvedOptions().timeZone
    
    それは非常に受け入れられるbrowser support そして、あなたはそれについての詳細を読むことができますMDN .
    別のオプションは、ユーザが現在のタイムゾーンを事前に選択したタイムゾーンを指定するよう要求します.
    UTCやデータベースで保存したタイムゾーンからユーザのタイムゾーンに変換するには、JavaScriptでいくつかの良いオプションがあります.luxon , date-fns また、他のアプリケーションで同じような状況に直面している場合は、テストが容易になり、移動するために何らかの理由で変更する必要がある場合には、中央の場所にあるライブラリから機能をラップすることも推奨されます.
    ここでは、タイムゾーン変換を管理するためのラッパーの例を示します.
    import { DateTime } from "luxon";
    export const ISO_TIME_FORMAT = "HH:mm";
    
    export function useTime(zone, serverTimezone = "UTC") {
      const timeZone = zone;
      ...
    
      /**
       * Transform a JS Date in users' timezone to ISO date in UTC
       * @param {Date} date
       * @returns {Object}
       */
      const getIsoUtcDateTime = (date) => { ... };
    
      /**
       * Transform DB date and time in ISO to a JS Date in users' timezone
       * @param {String} isoDate
       * @param {String} isoTime
       * @returns {Object}
       */
      const getLocalDateTimeFromISO = (isoDate, isoTime) => { ... };
    
      return {
          ...
          getIsoUtcDateTime,
          getLocalDateTimeFromISO
      }
    
    私は、あなたにラッパーがもたらす利益の一般的な局面を見せたいので、実装の詳細を省略します.ここでは主要機能useTime は、ユーザのデータベースタイムゾーンを一度だけ定義し、返される関数を使用してタイムゾーンを使用して変換を行います.
    ラッパーを使用するには、日付と時刻を仮定するとISO"yyyy-MM-dd" and "HH:mm" 次のようにフォーマットできます.
    import { useTime } from "./useTime";
    import constants from "./constants";
    
    const { getLocalDateTimeFromISO } = useTime(user.timezone, constants.SERVER_TIMEZONE);
    
    // ... code to fetch events would go here
    
    // transform iso dates to users' timezone
    const eventsInLocal = events.map((event) => {
       const { date, time } = getLocalDateTimeFromISO(event.date, event.time);
       event.date = date;
       event.time = time;
       return event;
    }
    
    

    テスト
    ブラウザからタイムゾーンを取っている場合、開発時の動作をテストするには、インスペクタのブラウザーで別のタイムゾーンをシミュレートすることができます.

    これは、ブラウザの検査の下部にあるセクションを開き、現在の場所をオーバーライドし、タイムゾーンを拡張します.


    今、我々はブラウザのタイムゾーンを持っているAsia/Tokio and new Date() 東京在住のままに振る舞う


    結論
    私たちは困難な課題を克服するたびに、私たちは私たちは私が私は1つの想像していないあなたのスキルに日付の合計を扱うポイントに数を与えることができれば私たちのskillsetをレベルを克服する😂. ありがたいことに、我々はUTCとRulesのような我々に標準を与える方法を舗装した人々を持ちます
    読書のおかげで、私は記事がコメントが開いているか、または私のような場合の質問がある場合は、いくつかの時間を節約することができます願っていますGithub ここで私はいくつかの実験とプロジェクトを行う.
    良い一日を.

    資源
  • date-fns
  • luxon
  • rrule.js
  • 写真でDjim Loic on Unsplash