PSDateManagement.psm1

#Generated at 08/05/2019 13:34:17 by LIENHARD Laurent
Class Date {
    [Datetime]$FirstDay
    [Datetime]$LastDay
    [Datetime]$aDate
    hidden [System.Int32]$NumberOfDays
    hidden [System.Int32]$WorkingDays
    hidden [System.DateTime]$FirstOrLastDay

    Date() {
        $this.aDate = Get-Date
    }

    Date([Datetime]$Date) {
        $this.aDate = $Date
    }

    Date([Datetime]$StartDate, [Datetime]$EndDate) {
        if ($EndDate -lt $StartDate) {
            Write-Error -Message "EndDate ($($EndDate)) should be greater than StartSate ($($StartDate))"
        } else {
            $this.FirstDay = $StartDate
            $this.LastDay = $EndDate
            $This.aDate = $StartDate
        }
    }

    [Void] SetFirstDayAndLastDay () {
        $this.FirstDay = Get-Date $this.aDate -day 1 -hour 0 -minute 0 -second 0
        $this.LastDay = (($this.FirstDay).AddMonths(1).AddSeconds( - 1))
    }

    [System.Int32] NumberDayBetweenFirstDayAndLastDay () {
        $this.NumberOfDays = ([datetime]$this.LastDay - [datetime]$this.FirstDay).Days
        return $this.NumberOfDays
    }

    [System.Int32] NumberOFWorkingDays () {
        $we = [System.DayOfWeek]::Saturday, [System.DayOfWeek]::Sunday
        $this.WorkingDays = 0
        $now = $this.FirstDay

        while ($Now -le $this.LastDay) {
            if ($now.DayOfWeek -notin $we) {
                $this.WorkingDays++
            }
            $now = $now.AddDays(1)
        }
        Return $this.WorkingDays
    }

    [datetime] FindFirstOrLastDay ([System.DayOfWeek]$Day, [System.String]$which) {
        switch ($which) {
            "First" {
                $This.FirstOrLastDay = $this.FirstDay
                while ($This.FirstOrLastDay.DayOfWeek -ne $Day) {
                    $This.FirstOrLastDay = $This.FirstOrLastDay.AddDays(1)
                }
            }
            "Last" {
                $This.FirstOrLastDay = $this.LastDay
                while ($This.FirstOrLastDay.DayOfWeek -ne $Day) {
                    $This.FirstOrLastDay = $This.FirstOrLastDay.AddDays(-1)
                }
            }
            Default {
                $This.FirstOrLastDay = $this.FirstDay
                while ($This.FirstOrLastDay.DayOfWeek -ne $Day) {
                    $This.FirstOrLastDay = $This.FirstOrLastDay.AddDays(1)
                }
            }
        }
        Return $This.FirstOrLastDay
    }
}
function Find-DMFirstOrLastDay {
    <#
    .SYNOPSIS
        Find first or last day in a period
    .DESCRIPTION
        Find first ou last day (Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday) in a specific period
    .PARAMETER Date
        The date corresponding to the search period
    .PARAMETER Day
        The day sought among those of the week (Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday)
    .PARAMETER Which
        What day is searched (first or last)
    .EXAMPLE
        PS > $period = New-DMDate
        PS > $period.SetFirstDayAndLastDay()
        PS > Write-Output (Find-DMFirstOrLastDay -Date $period -Day Monday -Which First)
 
        lundi 5 août 2019 00:00:00
 
        find the first Monday of the period from the first day of the current month to the last day of the current month
    .EXAMPLE
        PS > $period = New-DMDate -Date ((get-date).AddMonths(-1))
        PS > $period.SetFirstDayAndLastDay()
        PS > Find-DMFirstOrLastDay -Date $period -Day Friday -Which Last
 
        vendredi 26 juillet 2019 23:59:59
 
        Find the last Friday of the previous month
    .INPUTS
        Inputs (if any)
    .OUTPUTS
        Output (if any)
    .NOTES
        General notes
    #>

    [CmdletBinding()]
    param (
        [DATE]$Date,
        [ValidateSet("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")]
        [System.DayOfWeek]$Day,
        [ValidateSet("First", "Last")]
        [System.String]$Which
    )

    begin {
        $ScriptName = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).Mycommand
    }

    process {
        write-verbose "[$Scriptname] - BEGIN PROCESS"
        $result = $Date.FindFirstOrLastDay($Day, $Which)
    }
    end {
        return $result
    }
}
function New-DMDate {
    <#
    .SYNOPSIS
        Create new date object
    .DESCRIPTION
        Create a DATE object from the current date of the day or by giving a date range.
        Methods can be applied on this object to perform treatments such as:
            * Calculation of the number of working days between 2 dates
            * Calculation of the number of days between 2 dates
    .PARAMETER Date
        The date that will be used to instantiate the DATE object
    .PARAMETER StartDate
        The start date of the interval to instantiate the DATE object
    .PARAMETER EndDate
        The end date of the interval to instantiate the DATE object
    .EXAMPLE
        PS > New-DMDate
        FirstDay LastDay aDate
        -------- ------- -----
        01/01/0001 00:00:00 01/01/0001 00:00:00 31/07/2019 15:13:22
 
        This example returns a DATE object based on today's date
    .EXAMPLE
        PS > New-DMDate -Date ((get-date).AddDays(-6))
        FirstDay LastDay aDate
        -------- ------- -----
        01/01/0001 00:00:00 01/01/0001 00:00:00 25/07/2019 15:15:12
 
        This example returns a DATE object based on today's date minus 6 days
    .EXAMPLE
        PS > New-DMDate -StartDate ((get-date).AddDays(-6)) -EndDate ((get-date))
        FirstDay LastDay aDate
        -------- ------- -----
        25/07/2019 15:16:43 31/07/2019 15:16:43 25/07/2019 15:16:43
 
        This example returns a DATE object taking StartDate as the first day and EndDate as the last day.
    .INPUTS
        Inputs (if any)
    .OUTPUTS
        Output (if any)
    .NOTES
        General notes
    #>

    [CmdletBinding(DefaultParameterSetName = "ByDay")]
    param (
        [Parameter(ParameterSetName = "ByDay")]
        [System.DateTime]$Date = (Get-Date),
        [Parameter(ParameterSetName = "ByInterval")]
        [System.DateTime]$StartDate,
        [Parameter(ParameterSetName = "ByInterval")]
        [System.DateTime]$EndDate
    )

    begin {
        $ScriptName = (Get-Variable -name MyInvocation -Scope 0 -ValueOnly).Mycommand
    }

    process {
        write-verbose "[$Scriptname] - BEGIN PROCESS"
        switch ($PSCmdlet.ParameterSetName) {
            "ByDay" {
                Write-Verbose "[$Scriptname] - $Date"
                $DateUse = [DATE]::new($date)
            }
            "ByInterval" {
                Write-Verbose "[$Scriptname] - Startdate : $($StartDate) and EndDate : $($EndDate)"
                $DateUse = [DATE]::New($StartDate, $EndDate)
            }
        }
    }

    end {
        return $DateUse
    }
}