Now it's time to look at dates.
And anything that we're going to do with dates should
probably start with the Get‑Date cmdlet.
This is why I encourage you to read the help.
You may have run Get‑Date and you just get the current datetime,
but there are a number of parameters that you can use in order to
format the way that the datetime is presented to you,
and I'm going to go through some of these.
So I can run Get‑Date and say format it using a .NET format of g,
and this is lowercase.
These format parameters are case sensitive.
This gives me the date in this format,
and the format will be appropriate to your culture.
Because I am in North America, my format is month, day, year.
If I do capital G, then I get that particular format.
A lowercase u for the format will give me a UTC string.
If you come from a UNIX background or Linux background,
there is a uformat parameter, specify a UNIX‑type format,
again, this too is case sensitive, so I'm telling PowerShell,
get me the date formatted as year, underscore,
and then the month.
We can also create dates.
So let's say that I have a string, maybe something I've created,
or that I've read from a file, or pulled from somewhere.
I can use Get‑Date to actually turn that into a datetime object.
Don't try to fuss with the string to, say,
pull out a year, or a month, or something,
turn it into a datetime object,
and then use the datetime things I'm going to show you.
So let's do this, let's do Get‑Date and give it a year, a month, and a day.
And here's another way that I can create a datetime object, so there's $b.
Because I specified no time, it just defaults to 12:00 a.m.
Now, this is just another type of object,
so I'm going to look at all of the properties using
Select‑Object and not necessarily using Get‑Member.
Now that I see what these are,
I could then access any of these properties in my PowerShell work.
There are methods as well that we can use.
So I'm just going to look at the methods of a DateTime object.
Now, some of these are just things that are part of the .NET Framework,
which we won't necessarily get into,
but I will show you some ones that probably are of use to you.
Any of these ones that say, To something,
ShortDateString or LongDateString, those are things that you will want to use,
or maybe something like this, hey, is $b,
is it in daylight savings time?
And gives me True or False and January 1st is not in daylight savings time.
Or want to format this as a string, so I can format the date to a LongDateString.
Maybe this is an easier way than using the format parameter,
but these are methods that you probably are likely to use.
There are a number of Add methods, AddDays, AddHours, AddMinutes, and so on.
What day is it 45 days from now, or 45 days from $b?
And I get a new datetime object.
Or I want, say, I need what's the datetime in 1000 hours from now?
Sometimes we want to go backwards and say, what time was it five months ago?
My recommendation is, don't try to use the Subtract methods that you'll see,
use the Add method and just add a negative number.
So five months prior to $b is that, Sunday August 1st, 2021.
This is the type of thing that you might need if you're working,
for example, with user accounts in Active Directory.
Any discussion of dates also needs to include timespans,
how much time has occurred between two particular
datetime objects or two datetime events.
So I'm going to create a new datetime object,
this is another way that you can do it,
I'm going to create the variable $c and make it a datetime object.
PowerShell will treat this string into a datetime value.
Now, there's a cmdlet that we can use, New‑TimeSpan,
and I'll let you read the help here.
So I'm going to create a New‑TimeSpan variable and the Start will be $b,
and the ending date will be $c.
So what is that?
All right, so there is the object.
That is a TimeSpan object.
You can see the Days, Hours, Minutes,
as well as more granular approach with the TotalDays,
TotalSeconds, and so on.
This is another type of object, so if I wanted to,
I could say, hey, I just want to know the Days property,
161.
The other way that you can create a TimeSpan is just simple subtraction.
I can subtract $b from $c and get the same result.
Now, TimeSpans, when we use them in our PowerShell work,
typically will be displayed as a string,
although you can also format it as a string,
like this.
I have some examples coming up where you'll see this again in action.
So how about a practical example of using datetime values?
I'm going to create a variable, and I'm going to list some file extensions.
Now, what I want to do is use that,
and I'm going to do Get‑ChildItem on my scripts folder,
and I'm going to recursively search all files,
but I only want these particular file types that I see in $in.
I'm then going to group the results,
and I'm going to group them on a custom property.
So every file object has a CreationTime property, which is a datetime.
I want to get the Year property of that datetime object,
so we're grouping on a custom property,
which will be the year that each of these files was created.
I'm then going to select from that group object result,
I'm going to create a property called Year,
which will be the Name value from the Group‑Object,
and then I'm going to create Size, so I'm going to take the group,
and I'm going to pipe it to Measure‑Object and measure the length and the sum.
Now, I want to point out here,
here's another example where I'm leveraging the standard notation.
Notice that the $_.Group piped Measure‑Object is all in parentheses.
PowerShell is going to return that as an object.
That object is a measurement object, right?
We've seen that, that measurement object has a property called sum.
This technique that I'm using here is a way of getting just the
sum value all in line as I run the command,
and then we'll do something similar,
and this is another way of using Measure‑Object.
I am going to take the Group, and remember,
the Group property of the Group object is all the files
that go to each of these file extensions,
and I'm going to get the content of every file because these are
all txt files and measure the number of lines,
ignoring whitespace, and do the same thing.
That whole command is in parentheses,
which is going to give me a measurement object that has a Lines property,
but all I want is the Lines value that will be used for the value for Lines.
And then lastly, I'm going to format the results as a table,
and I'm going to create a custom header for Format-Table called path,
and I'm going to use my Scripts path as the value for that,
and I'll AutoSize it to make it nice, and pretty,
and easy to read.
This will take a minute or so to run because I have to get all the files,
group them, measure all the contents,
and what's probably taking the longest amount of
time is I have to take every file, read the contents,
and then measure that.
I'm creating a custom object that PowerShell will then pass on to Format-Table,
which has to do its thing, and then finally,
I will get the results written to the console here,
and there we go.
So now I have report that shows me the number of files for every year,
how big they are, and the total number of lines.
This is the type of thing that if I need this often or
I want to share with someone else,
I'm then going to build a PowerShell function around it.
But if this doesn't work in the PowerShell console,
you know, the function is not going to work,
and I won't be able to do that. So doing this in the console, as I've done here, is always the first step.