Passed
Pull Request — master (#188)
by Mathieu
02:07
created

server/src/Infrastructure/Adapter/DateUtilsAdapter.ts   A

Complexity

Total Complexity 15
Complexity/F 1.5

Size

Lines of Code 120
Function Count 10

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 99
dl 0
loc 120
rs 10
c 0
b 0
f 0
wmc 15
mnd 5
bc 5
fnc 10
bpm 0.5
cpm 1.5
noi 0

10 Functions

Rating   Name   Duplication   Size   Complexity  
A DateUtilsAdapter.getCurrentDate 0 3 1
A DateUtilsAdapter.getCurrentDateToISOString 0 3 1
A DateUtilsAdapter.addDaysToDate 0 3 1
A DateUtilsAdapter.getWorkedFreeDays 0 20 1
A DateUtilsAdapter.getWorkedDaysDuringAPeriod 0 22 4
A DateUtilsAdapter.getEasterDate 0 19 1
A DateUtilsAdapter.getLeaveDuration 0 16 3
A DateUtilsAdapter.getDaysInMonth 0 3 1
A DateUtilsAdapter.isWeekend 0 3 1
A DateUtilsAdapter.format 0 3 1
1
import { Injectable } from '@nestjs/common';
2
import {
3
  format as fnsFormat,
4
  isWeekend as fnsIsWeekend,
5
  getDaysInMonth as fnsGetDaysInMonth,
6
  eachDayOfInterval,
7
  addDays
8
} from 'date-fns';
9
import { IDateUtils } from 'src/Application/IDateUtils';
10
11
@Injectable()
12
export class DateUtilsAdapter implements IDateUtils {
13
  constructor(private readonly date: Date = new Date()) {}
14
15
  public format(date: Date, format: string): string {
16
    return fnsFormat(date, format);
17
  }
18
19
  public getDaysInMonth(date: Date): number {
20
    return fnsGetDaysInMonth(date);
21
  }
22
23
  public isWeekend(date: Date): boolean {
24
    return fnsIsWeekend(date);
25
  }
26
27
  public getCurrentDate(): Date {
28
    return this.date;
29
  }
30
31
  public getCurrentDateToISOString(): string {
32
    return this.date.toISOString();
33
  }
34
35
  public addDaysToDate(date: Date, days: number): Date {
36
    return addDays(date, days);
37
  }
38
39
  public getWorkedDaysDuringAPeriod(start: Date, end: Date): Date[] {
40
    const dates: Date[] = [];
41
    const workedFreeDays: Date[] = [];
42
43
    for (let year = start.getFullYear(); year <= end.getFullYear(); year++) {
44
      workedFreeDays.push(...this.getWorkedFreeDays(year));
45
    }
46
47
    for (const day of eachDayOfInterval({ start, end })) {
48
      if (
49
        this.isWeekend(day) ||
50
        workedFreeDays.filter(d => d.toISOString() === day.toISOString())
51
          .length > 0
52
      ) {
53
        continue;
54
      }
55
56
      dates.push(day);
57
    }
58
59
    return dates;
60
  }
61
62
  public getWorkedFreeDays(year: number): Date[] {
63
    const fixedDays: Date[] = [
64
      new Date(`${year}-01-01`), // New Year's Day
65
      new Date(`${year}-05-01`), // Labour Day
66
      new Date(`${year}-05-08`), // Victory in 1945
67
      new Date(`${year}-07-14`), // National Day
68
      new Date(`${year}-08-15`), // Assumption
69
      new Date(`${year}-11-01`), // All Saints' Day
70
      new Date(`${year}-11-11`), // The Armistice
71
      new Date(`${year}-12-25`) // Christmas
72
    ];
73
74
    const easterDate = this.getEasterDate(year);
75
    const easterDays: Date[] = [
76
      addDays(easterDate, 1), // Easter Monday
77
      addDays(easterDate, 39) // Ascension
78
    ];
79
80
    return [...fixedDays, ...easterDays];
81
  }
82
83
  public getEasterDate(year: number): Date {
84
    const a = year % 19;
85
    const b = Math.floor(year / 100);
86
    const c = year % 100;
87
    const d = Math.floor(b / 4);
88
    const e = b % 4;
89
    const f = Math.floor((b + 8) / 25);
90
    const g = Math.floor((b - f + 1) / 3);
91
    const h = (19 * a + b - d - g + 15) % 30;
92
    const i = Math.floor(c / 4);
93
    const k = c % 4;
94
    const l = (32 + 2 * e + 2 * i - h - k) % 7;
95
    const m = Math.floor((a + 11 * h + 22 * l) / 451);
96
    const n0 = h + l + 7 * m + 114;
97
    const n = Math.floor(n0 / 31) - 1;
98
    const p = (n0 % 31) + 1;
99
100
    return new Date(year, n, p);
101
  }
102
103
  public getLeaveDuration(startDate: string, isStartsAllDay: boolean, endDate: string, isEndsAllDay: boolean): number {
104
    let duration = this.getWorkedDaysDuringAPeriod(
105
      new Date(startDate),
106
      new Date(endDate)
107
    ).length;
108
109
    if (false === isStartsAllDay) {
110
      duration -= 0.5;
111
    }
112
113
    if (false === isEndsAllDay && duration > 0.5) {
114
      duration -= 0.5;
115
    }
116
117
    return duration;
118
  }
119
}
120