ふふふ。冷たい圧迫感が背筋を這う。
はぁはぁ。上司の冷たい息が、溢れ出る下水のようにあなたの首を洗い流します。しかし、どこか別の場所に留まるように彼らに指示することはできません...オフィスの時間追跡システムが壊れて以来、彼らは鷹のようにあなたを監視しています。
今、彼らはただそこにいます...ホバリング...呼吸しています。ふふふふ。
あなたはタイムシートに自分の時間を書き込もうとしましたが、上司はその作業でかなり忙しいです。もし彼らが計算を正しく行わず、あなたの時間を間違って追加してしまったらどうなるでしょうか?
ここでは、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 段階のアルゴリズムでタスクを完了できるようになりました。
タイムシート文字列を個々の行に分割し、それらを縮小してオブジェクトの配列を作成します。
反復ごとに、次のことを行います。
A. yearRegex
を使用して年を中心に行を分割し、日付文字列を記録します
intervalsRegex
を使用してすべての時間範囲間隔を収集する
C. parseDate
ヘルパーとステップ 2.A の日付文字列を使用して、それぞれを JavaScript Date オブジェクトとして解析し、時間範囲を縮小します。
オブジェクトの配列を縮小して合計時間を見つけます
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 日に同じ時間間隔が含まれているかどうかによって一意ではない可能性があります。この解決策は完璧ではありません。
times
オブジェクトを調べます。このコードを最適化するには、 totalHours
とtimes
をフィールドとして含む空のオブジェクトに対して単一の Reduce を使用する方がよいでしょう。
これで、乱雑なタイムシートから時間を抽出する方法がわかりました。もう少し努力すれば、完全に稼働するタイム レコーダーを構築することもできます。しかし、そうなると、上司と知り合うために充実した時間を費やすことができなくなりますよね。ふふふ。