user6744606
user6744606

Reputation:

PowerShell ForEach removes leading zeros

I am kind of new with PowerShell and programming in general, so I hope you have some patience while reading this. Before I explain my problem, I feel like I have to first tell you some background information:

I have all my transactions saved in $Transactions. Each transaction has Receiver, Date and Amount.

I have grouped the yearly transactions into $TransactionsPerYear the following way:

$TransactionsPerYear = $Transactions | Group-Object { [int]($_.date -replace '.*\.') }

(Btw. Could someone explain the regex in the end for me, what each character does?)

Next thing I am doing is grouping yearly income and expenses into separate variables. After this I am trying to extract the months from each year and save them into $Months. The date is in the following format dd.MM.yyyy

Question 1:

Here's how I can get all the dates, but how do I extract just the months?

$TransactionsPerYear | Select -ExpandProperty Group | Select -ExpandProperty date | Select -Unique

Question 2:

Because I don't know how to extract the months, I've tried it the following way:

[String[]]$Months = "01","02","03","04","05","06","07","08","09","10","11","12"

When I have each month in $Months I am trying to get monthly transactions and save them into new variables:

ForEach($Month in $Months){

New-Variable -Name "Transactions_$Month$Year" -Value ($Transactions | Where {$_.Date -like "*.$Month.$Year"} | Group-Object 'Receiver' | Select-Object Count, Name, @{L="Total";E={$_ | Select -ExpandProperty Group | Measure-Object Amount -Sum | Select -ExpandProperty Sum}} | Sort-Object {[double]$_.Total})

}

The problem that I am facing here is that ForEach removes the leading zero from each month, and when this happens, this part in ForEach doesn't match with anything, and the new variable is null:

Where {$_.Date -like "*.$Month.$Year"}

Let me know if you need more info. I'd be really thankful if anyone could help me.

The date looks like: 25.02.2016

Upvotes: 0

Views: 367

Answers (2)

Bill_Stewart
Bill_Stewart

Reputation: 24535

Do you mean this?

$dates = ([DateTime] "1/1/2016"),([DateTime] "1/2/2016"),
  ([DateTime] "2/1/2016"),([DateTime] "3/1/2016")
$uniqueMonths = $dates | ForEach-Object { $_.Month } | Sort-Object -Unique
# $uniqueMonths contains 1,2,3

Upvotes: 0

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174485

From your post, it looks like you've jumped further down the rabbithole than necessary.

Instead of trying to do string manipulation every time you need to interact with the Date property, simply turn it into a DateTime object!

$Transactions = $Transactions |Select-Object *,@{Name='DateParsed';Expression={[datetime]::ParseExact($_.Date, 'dd.MM.yyyy', $null)}}

The DateTime.ParseExact() method allows us to specify the format (eg. dd.MM.yyyy), and parse a string representation of a date.

Now you can group on year simply by:

$TransactionsPerYear = $Transactions |Group-Object { $_.DateParsed.Year }

To group by both Year and then Month, I'd create a nested hashtable, like so:

# Create a hashtable, containing one key per year
$MonthlyTransactions = @{}

foreach($Year in $Transactions |Group {$_.DateParsed.Year})
{
    # Create another hashtable, containing a key for each month in that year
    $MonthlyTransactions[$Year.Name] = @{}

    foreach($Month in $Year.Group |Group {$_.DateParsed.Month})
    {
        # Add the transactions to the Monthly hashtable
        $MonthlyTransactions[$Year.Name][$Month.Name] = $Month.Group
    }
}

Now you can calculate the transaction value for a specific month by doing:

$TotalValueMay2010 = ($MonthlyTransactions[2010][5] |Measure-Object Amount -Sum).Sum

(Btw. Could someone explain the regex in the end for me, what each character does?)

Sure:

.   # match any character
 *  # zero of more times
\.  # match a literal . (dot)

Taking your own example input string 25.02.2016, the first group (.*) will match on 25.02, and \. will match on the . right after, so the only thing left is 2016.

Upvotes: 2

Related Questions