Skip to content
Snippets Groups Projects
dateChartService.ts 6.93 KiB
Newer Older
  • Learn to ignore specific revisions
  • Hugo NOUTS's avatar
    Hugo NOUTS committed
    import { DateTime, Interval } from 'luxon'
    import { FluidType } from 'enum/fluid.enum'
    import {
      TimeStep,
      TimePeriod,
      IDataload,
    } from 'services/dataConsumptionContracts'
    
    export function defineTimePeriod(
      referenceDate: DateTime,
      timeStep: TimeStep,
      index: number
    ): TimePeriod {
      let date: DateTime
      switch (timeStep) {
        case TimeStep.YEAR:
          date = referenceDate.set({
            month: 1,
            day: 1,
            hour: 0,
            minute: 0,
            second: 0,
            millisecond: 0,
          })
          return new TimePeriod(
            date.plus({ years: -5 * index - (5 - 1) }),
            date.plus({ years: -5 * index })
          )
        case TimeStep.MONTH:
          date = referenceDate.set({
            month: 12,
            day: 1,
            hour: 0,
            minute: 0,
            second: 0,
            millisecond: 0,
          })
          return new TimePeriod(
            date.plus({ months: -12 * index - (12 - 1) }),
            date.plus({ months: -12 * index })
          )
        case TimeStep.DAY:
          date = referenceDate
            .endOf('week')
            .set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
          return new TimePeriod(
            date.plus({ days: -7 * index - (7 - 1) }),
            date.plus({ days: -7 * index })
          )
        case TimeStep.HOUR:
          date = referenceDate.set({
            hour: 23,
            minute: 0,
            second: 0,
            millisecond: 0,
          })
          return new TimePeriod(
            date.set({ hour: 0, minute: 0 }).plus({ days: -1 * index }),
            date.plus({ days: -1 * index })
          )
        case TimeStep.HALF_AN_HOUR:
          date = referenceDate.set({ hour: 23, minute: 30 })
          return new TimePeriod(
            date.set({ hour: 0, minute: 0 }).plus({ days: -1 * index }),
            date.plus({ days: -1 * index })
          )
        default:
          date = referenceDate
          return new TimePeriod(
            date.plus({ days: -7 * index - (7 - 1) }),
            date.plus({ days: -7 * index })
          )
      }
    }
    
    export function defineFirstStepDate(
      referenceDate: DateTime,
      timeStep: TimeStep,
      index: number
    ): DateTime {
      const period = defineTimePeriod(referenceDate, timeStep, index)
      return period.startDate
    }
    
    export function defineLastStepDate(
      referenceDate: DateTime,
      timeStep: TimeStep,
      index: number
    ): DateTime {
      const period = defineTimePeriod(referenceDate, timeStep, index)
      return period.endDate
    }
    
    export function compareStepDate(
      timeStep: TimeStep,
      date1: DateTime,
      date2: DateTime
    ): boolean {
      switch (timeStep) {
        case TimeStep.YEAR:
          return date1.year === date2.year
        case TimeStep.MONTH:
          return date1.year === date2.year && date1.month === date2.month
        case TimeStep.DAY:
          return (
            date1.year === date2.year &&
            date1.month === date2.month &&
            date1.day === date2.day
          )
        case TimeStep.HOUR:
          return (
            date1.year === date2.year &&
            date1.month === date2.month &&
            date1.day === date2.day &&
            date1.hour === date2.hour
          )
        case TimeStep.HALF_AN_HOUR:
          return (
            date1.year === date2.year &&
            date1.month === date2.month &&
            date1.day === date2.day &&
            date1.hour === date2.hour &&
            Math.abs(date1.minute - date2.minute) < 30
          )
        default:
          return false
      }
    }
    
    export function defineDetailedTimeStep(
      timeStep: TimeStep,
      fluidTypes: FluidType[]
    ): TimeStep {
      if (fluidTypes.length === 1) {
        switch (timeStep) {
          case TimeStep.YEAR:
            return TimeStep.MONTH
          case TimeStep.MONTH:
            return TimeStep.DAY
          case TimeStep.DAY:
            switch (fluidTypes[0]) {
              case FluidType.ELECTRICITY:
                return TimeStep.HALF_AN_HOUR
              case FluidType.WATER:
                return TimeStep.HOUR
              case FluidType.GAS:
                return TimeStep.HOUR
            }
          case TimeStep.HOUR:
            return TimeStep.HOUR
          case TimeStep.HALF_AN_HOUR:
            return TimeStep.HALF_AN_HOUR
          default:
            return timeStep
        }
      } else {
        switch (timeStep) {
          case TimeStep.YEAR:
            return TimeStep.MONTH
          case TimeStep.MONTH:
            return TimeStep.DAY
          default:
            return timeStep
        }
      }
    }
    
    export function formatDetailedDate(
      date: DateTime,
      timeStep: TimeStep
    ): DateTime {
      switch (timeStep) {
        case TimeStep.YEAR:
          return date
        case TimeStep.MONTH:
          return date.set({
            month: 1,
            day: 1,
            hour: 0,
            minute: 0,
            second: 0,
            millisecond: 0,
          })
        case TimeStep.DAY:
          return date.set({ day: 1, hour: 0, minute: 0, second: 0, millisecond: 0 })
        case TimeStep.HOUR:
          return date.set({ hour: 0, minute: 0, second: 0, millisecond: 0 })
        case TimeStep.HALF_AN_HOUR:
          return date.set({ minute: 0, second: 0, millisecond: 0 })
        default:
          return date
      }
    }
    
    export function incrementDate(
      increment: number,
      initialdate: DateTime,
      timeStep: TimeStep
    ): { incrementIndex: number; incrementedDate: DateTime } {
      let incrementIndex = 0
      let incrementedDate: DateTime = initialdate
      switch (timeStep) {
        case TimeStep.YEAR:
          incrementedDate = initialdate.plus({ year: increment })
          incrementIndex =
            (DateTime.local().year - incrementedDate.year) % 5 === 0
              ? 1
              : (DateTime.local().year - incrementedDate.year - 4) % 5 === 0
              ? -1
              : 0
          break
        case TimeStep.MONTH:
          incrementedDate = initialdate.plus({ month: increment })
          incrementIndex = initialdate.year - incrementedDate.year
          break
        case TimeStep.DAY:
          incrementedDate = initialdate.plus({ day: increment })
          if (initialdate.weekday === 1 && incrementedDate.weekday === 7) {
            incrementIndex = 1
          } else if (initialdate.weekday === 7 && incrementedDate.weekday === 1) {
            incrementIndex = -1
          } else {
            incrementIndex = 0
          }
          break
        case TimeStep.HOUR:
          incrementedDate = initialdate.plus({ hour: increment })
          if (initialdate.hour === 0 && incrementedDate.hour === 23) {
            incrementIndex = 1
          } else if (initialdate.hour === 23 && incrementedDate.hour === 0) {
            incrementIndex = -1
          } else {
            incrementIndex = 0
          }
          break
        case TimeStep.HALF_AN_HOUR:
          incrementedDate = initialdate.plus({ minute: increment * 30 })
          if (initialdate.hour === 0 && incrementedDate.hour === 23) {
            incrementIndex = 1
          } else if (initialdate.hour === 23 && incrementedDate.hour === 0) {
            incrementIndex = -1
          } else {
            incrementIndex = 0
          }
          break
      }
      return { incrementIndex, incrementedDate }
    }
    
    export const isDataToCome = (dataload: IDataload, fluidType: FluidType) => {
      const inter =
        dataload &&
        Interval.fromDateTimes(dataload.date, DateTime.local()).count('days')
      if (fluidType === FluidType.ELECTRICITY && inter < 2) {
        return true
      }
      if (fluidType === FluidType.WATER && inter < 4) {
        return true
      }
      if (fluidType === FluidType.GAS && inter < 3) {
        return true
      } else {
        return false
      }
    }