paint-brush
JavaScript で時間間隔を簡単に追加する@anwarhjg
631 測定値
631 測定値

JavaScript で時間間隔を簡単に追加する

AHJ George4m2024/01/13
Read on Terminal Reader

長すぎる; 読むには

タイムシート文字列、ホバリングボス、JavaScript があります。 問題: 時間を合計して、上司の滞りを止めたいと考えています。 解決策: 魔術は必要ありません。
featured image - JavaScript で時間間隔を簡単に追加する
AHJ George HackerNoon profile picture
0-item

このチュートリアルを完了するために、これらの魔女用品は必要ありません。著者による画像。



ふふふ。冷たい圧迫感が背筋を這う。


はぁはぁ。上司の冷たい息が、溢れ出る下水のようにあなたの首を洗い流します。しかし、どこか別の場所に留まるように彼らに指示することはできません...オフィスの時間追跡システムが壊れて以来、彼らは鷹のようにあなたを監視しています。


今、彼らはただそこにいます...ホバリング...呼吸しています。ふふふふ。


あなたはタイムシートに自分の時間を書き込もうとしましたが、上司はその作業でかなり忙しいです。もし彼らが計算を正しく行わず、あなたの時間を間違って追加してしまったらどうなるでしょうか?


ここでは、JavaScript を使用して問題を自分の手で解決する方法を説明します。はぁはぁ

問題

このStringの内容のようなタイムシートがあります。

 const a = `November 30 2023 13:20-15:00, 15:30-16:40 December 4 2023 15:45-16:15, December 5 2023 08:00-08:30, 18:15-19:30, 21:45-22:15, 22:30-23:00 December 6 2023 19:45-21:45 December 7 2023 14:15-14:45, 15:15-15:45, 16:00-16:30, 16:45-17:15, 18:45-20:15, 20:45-22:45 December 13 2023 03:00-03:50 December 15 2023 09:00-09:30 20:30-21:15 21:45-22:30 23:30-24:00 December 16 2023 23:25-23:55 December 17 2023 19:05-19:50 20:30-21:30 22:15-23:45 December 20 2023 23:30-24:00 December 21 2023 02:20-2:50 03:15-03:30 13:40-14:00 16:00-17:15 17:45-18:45 19:20-20:10 21:30-22:20 23:00 - 24:00 December 22 2023 0:00-0:15`;


各行には日付が含まれており、その後にいくつかの時間間隔が続きます。しかし、それらはあまりきれいに書かれているわけではありません。一部の間隔はカンマで区切られており、他の間隔は不規則です。


これらの矛盾を考慮すると、他の保証はないと仮定するのがおそらく良いでしょう。たとえば、すべての回が同じ年のことになると誰が言ったでしょうか。誰も、それは誰です。時間をできるだけ確実に加算したいと考えています。

ソリューション

これはとても簡単です。まず、いくつかの正規表現とヘルパー関数を作成します。それなら、私たちはただ…ううふふ!


うーん!!ボス、ちょっとどこかで落ち着いてください!


先ほど述べたように、3 段階のアルゴリズムでタスクを完了できるようになりました。


  1. タイムシート文字列を個々の行に分割し、それらを縮小してオブジェクトの配列を作成します。


  2. 反復ごとに、次のことを行います。

    A. yearRegexを使用して年を中心に行を分割し、日付文字列を記録します

    intervalsRegexを使用してすべての時間範囲間隔を収集する

    C. parseDateヘルパーとステップ 2.A の日付文字列を使用して、それぞれを JavaScript Date オブジェクトとして解析し、時間範囲を縮小します。


  3. オブジェクトの配列を縮小して合計時間を見つけます


const yearRegex = /(\d{4})/gi; const intervalsRegex = /(\d+\:\d+)\s*-\s*(\d+\:\d+)/gi; const parseDate = (date, time) => Date.parse(`${date} ${time}`); let times = [...a.split("\n")].reduce((arr, entryLine) => { let entryLineSplit = entryLine.split(yearRegex); let o = { date: entryLineSplit[0] + entryLineSplit[1], timeRanges: [...entryLine.matchAll(intervalsRegex)], }; o.hoursForDay = o.timeRanges.reduce((total, [x, start, end]) => { let s = parseDate(o.date, start); let e = parseDate(o.date, end); return total + (e - s) / 1000 / 60 / 60; }, 0); return [...arr, o]; }, []); console.log(times); let totalHours = times.reduce((total, { hoursForDay }) => total + hoursForDay, 0); console.log(totalHours);


console.log(times);ステートメントを実行すると、次のようなオブジェクトを含む配列が表示されます。

 { date: 'November 30 2023', timeRanges: [ [ '13:20-15:00', '13:20', '15:00', index: 17, input: 'November 30 2023 13:20-15:00, 15:30-16:40', groups: undefined ], [ '15:30-16:40', '15:30', '16:40', index: 30, input: 'November 30 2023 13:20-15:00, 15:30-16:40', groups: undefined ] ], totalHours: 2.8333333333333335 },

この方法の利点

オブジェクトの配列を構築することには、単純に時間間隔を抽出して追加することに比べて、いくつかの明確な利点があります。


  • これにより、事後のトラバースが容易になります。これは、毎日の時間をグラフ化するなどの作業を行う場合に最適です。


  • 各レコードの日付文字列を保存すると、 Date.parseの呼び出し後に組み込みの JS 日付算術メソッドを使用できるようになります。


  • このオブジェクトは、 String.prototype.splitを呼び出した結果を保存するのに便利な場所です。この結果は、2 日に同じ時間間隔が含まれているかどうかによって一意ではない可能性があります。

この方法の欠点

この解決策は完璧ではありません。

  • これには 2 つの大きな走査が必要です。1 回目はタイムシートの分割結果を調べ、もう 1 回目はtimesオブジェクトを調べます。このコードを最適化するには、 totalHourstimesをフィールドとして含む空のオブジェクトに対して単一の Reduce を使用する方がよいでしょう。


  • 正規表現を使用しますが、形式が複雑になるとさらに複雑になる可能性があります。

まとめ

これで、乱雑なタイムシートから時間を抽出する方法がわかりました。もう少し努力すれば、完全に稼働するタイム レコーダーを構築することもできます。しかし、そうなると、上司と知り合うために充実した時間を費やすことができなくなりますよね。ふふふ。