Powershell - Find the next Friday
Asked Answered
V

11

8

Hoping this won't be too difficult but I am writing a script that queries user information from the domain and exports to CSV.

The script is run by our administrative staff and all they need to input into the script is the username.

The tricky part is that I need the CSV to be named based on the coming Friday.

Note: I am in Australia so my date format is DD-MM-YYYY

The way I am currently looking at going about it is as below:

# Grab the Script Run Timestamp
$ScriptRuntime = Get-Date -Day 4 -Month 5 -Year 2013

# Grab the next Friday (including today)
$NextFriday = $ScriptRuntime.AddDays(0 + $(0,1,2,3,4,5,6 -eq 5 - [int]$ScriptRuntime.dayofweek))

Write-Host "Script Run:  "$ScriptRuntime
Write-Host "Next Friday: "$NextFriday

This works OK with all days except Saturday.

  • If i run the day as Day 26, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 27, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 28, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 29, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 30, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 31, Month 5, Year 2013 it returns 31/05/2013
  • If i run the day as Day 1, Month 6, Year 2013 it returns 31/05/2013 (this should be 07/06/2013)
  • If i run the day as Day 2, Month 6, Year 2013 it returns 07/06/2013

What am i doing wrong?

Variolite answered 28/5, 2013 at 6:29 Comment(0)
O
7

I'm not sure I'm following you but here's I would get next Friday:

$date = Get-Date

for($i=1; $i -le 7; $i++)
{        
    if($date.AddDays($i).DayOfWeek -eq 'Friday')
    {
        $date.AddDays($i)
        break
    }
}
Oestrogen answered 28/5, 2013 at 7:26 Comment(2)
Anyone looking for a perhaps less clear, but more compact, pipeline construct, could try something like 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Friday'}Epaulet
I would like to point out that in order for $date to have the value of the next Friday, it must actually be assigned, so $date = $date.AddDays($i) instead of just $date.AddDays($i)Blasphemous
L
12

This finds the next Friday:

$date = Get-Date
while ($Date.DayOfWeek -ne "Friday") {$date = $date.AddDays(1)}
Loyce answered 7/1, 2016 at 12:15 Comment(0)
O
7

I'm not sure I'm following you but here's I would get next Friday:

$date = Get-Date

for($i=1; $i -le 7; $i++)
{        
    if($date.AddDays($i).DayOfWeek -eq 'Friday')
    {
        $date.AddDays($i)
        break
    }
}
Oestrogen answered 28/5, 2013 at 7:26 Comment(2)
Anyone looking for a perhaps less clear, but more compact, pipeline construct, could try something like 1..7 | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -eq 'Friday'}Epaulet
I would like to point out that in order for $date to have the value of the next Friday, it must actually be assigned, so $date = $date.AddDays($i) instead of just $date.AddDays($i)Blasphemous
C
6

Here's a one-liner that'll do the trick too:

$Date = @(@(0..7) | % {$(Get-Date).AddDays($_)} | ? {$_.DayOfWeek -ieq "Friday"})[0]

And if you need a specific time:

$Date = @(@(0..7) | % {$(Get-Date "12:00").AddDays($_)} | ? {($_ -gt $(Get-Date)) -and ($_.DayOfWeek -ieq "Friday")})[0]
California answered 29/5, 2014 at 17:22 Comment(2)
What's the purpose of the outermost array declaration (the @(...))?Radiogram
you wouldn't need the [0] at the end if you just put either (0..6) or (1..7) at the front, depending on desired behavior (0..6 would answer OP, I believe)Epaulet
S
5

You can get the date of the Friday of this week, regardless of what date you run the code, using the following:

$today = (Get-Date).Date    
$nextfriday = $today.AddDays([int][dayofweek]::Friday - $today.DayOfWeek)    

If you want to always get the next Friday (so, next week's Friday if you run on a Saturday), you just need an extra modifier at the end:

if ($today -ge $nextfriday) {$nextfriday = $nextfriday.AddDays(7)}
Sortilege answered 14/5, 2018 at 8:14 Comment(0)
D
5

A bit late to the party, but here's my take (no loops, no conditionals):

    [datetime] $MyDate =  get-date
    [DayOfWeek] $NextDayOfWeek = 'Friday'

    $MyDate.AddDays( (7 - [int] $MyDate.DayOfWeek + [int] $NextDayOfWeek )%7 )

If you want to verify it for a larger number of dates:

    [datetime] $MyDate =  get-date
    [DayOfWeek] $NextDayOfWeek = 'Friday'

    1..30 | ForEach-Object {
                            [PSCustomObject]@{ 
                                DayOfWeek = $MyDate.DayOfWeek ;
                                Date = $MyDate; 
                                $("Next$NextDayOfWeek") = $MyDate.AddDays((7 - [int] $MyDate.DayOfWeek + [int] $NextDayOfWeek )%7)   
                            }; 
                            $MyDate = $MyDate.AddDays(1)  
                        } 
Dickenson answered 16/10, 2019 at 14:58 Comment(0)
E
1

Try this to find next friday:

$ScriptRuntime = Get-Date -Day 4 -Month 5 -Year 2013
$i= switch ( [int][dayofweek]::Friday - [int] $ScriptRuntime.dayofweek )
    { 
       -1 { 6 }
       default { $_ }
    } 
$ScriptRuntime.adddays($i)
Emmanuel answered 28/5, 2013 at 7:34 Comment(0)
S
0

I would do it like this:

$Date = Get-Date
$targetDay = [int][dayofweek]::Friday
# I use this logic to figure out the next Friday
# else we would get Friday of this week
$intToday = if([int]$Date.DayOfWeek -le [int][dayofweek]::Friday ){
                [int]$Date.DayOfWeek 
            } else { 
                [int]$Date.DayOfWeek - 7
            }
$nextFriday = $date.AddDays($targetDay - $intToday)

I came across the same issue, but I thought using a loop was a little too much. I found an article about PowerShell Find Date of a previous day in any week but the values where hard coded for the days and depending on your windows environment the Sunday may not be index 0 (zero). So, I used the logic as inspiration and figured the one above.

Hope it helps next guy.

Somewhere answered 4/1, 2016 at 23:20 Comment(0)
S
0

I put Shay's example into the extended function, so you can also target the exact time of the date that you are looking for.

Function Find-NextDate {
[CmdletBinding()]
param (
    # Parameter help description
    [Parameter(Mandatory=$true,
    Position=1)]
    [validatenotnullorempty()]
    [ValidateSet("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")]
    [string]$Day,
    [Parameter(Mandatory=$false,
    Position=2)]
    [validatenotnullorempty()]
    [string]$Time
)
process {
    if ($Time) {
        $Date = (Get-Date $Time)
        for($i=1; $i -le 7; $i++) {        
            if ($Date.AddDays($i).DayOfWeek -eq "$Day") {
                $Date.AddDays($i)
                break
            }
        }
    }
    else {
        $Date = (Get-Date)
        for($i=1; $i -le 7; $i++) {        
            if ($Date.AddDays($i).DayOfWeek -eq "$Day") {
                $Date.AddDays($i)
                break
            }
        }
    }
}

}

Sodden answered 11/4, 2019 at 9:8 Comment(0)
B
0

Based on my testing, the following solution is more efficient. It saves you a total of 6 milliseconds from the chosen answer. Don't you always want the most efficient code? :-). It is related to @bf.'s answer, but fixes the output when its Saturday.

$date = Get-Date '09/22/2022'
$nextFriday = $date.AddDays($(if([int]$date.DayOfWeek -gt 5){6}else{5-[int]$date.DayOfWeek}))

The following is what I ran to compare them:

$date = Get-Date
Get-Date -Format HH:mm:ss.fff
$date.AddDays($(if([int]$date.DayOfWeek -gt 5){6}else{5-[int]$date.DayOfWeek}))
Get-Date -Format HH:mm:ss.fff
while ($date.DayOfWeek -ne "Friday") {$date = $date.AddDays(1)}
$date
Get-Date -Format HH:mm:ss.fff

Which gave the following output:

13:51:17.701
Friday, September 23, 2022 1:51:17 PM
13:51:17.715
Friday, September 23, 2022 1:51:17 PM
13:51:17.735
Bottle answered 19/9, 2022 at 17:56 Comment(0)
T
0

A simple way without loop :

[DateTime]$MyDate = Get-Date [DayOfWeek]$DayOfWeek = 'Sunday'

$NextDayOfWeekForMyDate = $MyDate.AddDays($DayOfWeek - $MyDate.DayOfWeek + [int]($MyDate.DayOfWeek -ge $DayOfWeek)*7)

$PreviousDayOfWeekForMyDate = $MyDate.AddDays($DayOfWeek - $MyDate.DayOfWeek - [int]($MyDate.DayOfWeek -le $DayOfWeek)*7)

replace "*7" by "*7*N" for the DayOfWeek in next/previous N weeks

Thimbu answered 13/8 at 9:7 Comment(0)
R
-1

You could install ProductivityTools.PSGetDayInGivenWeek module from PowerShell Gallery

Install-Module -Name ProductivityTools.PSGetDayInGivenWeek

It exposes method Get-RequestedDayOfWeek which allows, to define what day of week are you looking for and if you are looking it before or after given day. So to find next Monday

Get-RequestedDayOfWeek '2018.03.03' -Monday -After

Module in PowerShell Gallery can be found here, and code for it here.

enter image description here

Rubin answered 18/9, 2018 at 15:9 Comment(2)
Downloading a 3rd party package for trivial stuff is really a no go in my opinion (it also "dumbs down" developers since they have no idea what happens in the background if they only install packages written by others instead of finding a way to make stuff work, especially for really trivial things).Fetterlock
I am trying to not copy and paste the code which was written once. Devs can always analyse the code on the Github and maybe learn something. Also having it in the module and referenced by other scripts helps to correct functionality everywhere if some mistake will be done in the initial script.Rubin

© 2022 - 2024 — McMap. All rights reserved.