How to get last day of specified month in powershell - powershell

I need to get the last day of a month previous from specified.
I have a string (file name), which contains a date in its end. I need to capture the date (already done) and get the last date of the preceding month. For example the string is "proemail vytvoreni_9.2017 2017-10-16", so I need to get 30th September 2017. This is what I have now:
$Report = Read-Host "File name"
$Date = [datetime]$Report.Substring($Report.get_Length()-10)
$Last_month = $Date.AddMonths(-1)
$Date_text = $Last_month.ToString().Substring(3,7)
$month_year = ($Date_text.Split("."))
$days_count = [datetime]::DaysInMonth($month_year[1],$month_year[0])
$days_count = $days_count.ToString()
$month = $month_year[0]
$year = $month_year[1]
$Date_limit = [DateTime]($month,$days_count,$year)
All works well, except for the last row, that returns this error: Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.DateTime". I tried to convert $month and $year to string by .ToString() method, but it didn't help

(Get-Date).AddDays(-$(Get-Date).Day)
Saturday, September 30, 2017 2:36:19 PM
((Get-Date).AddDays(-$(Get-Date).Day)).Day
30

$filename = "proemail vytvoreni_9.2017 2017-10-16"
# Take the date from the filename
$sub = $filename.Substring($filename.Length-10)
# make it into a date format
$filedate = Get-Date -Date $sub
# take that date 2017-10-16 and substracts its own days so in this case substract 16 days, then show me the date
(($filedate).AddDays(-$filedate.Day)).Date
Output:
Saturday 30 september 2017 0:00:00

I've looked at this problem and different solution for this for awhile and here is my answer.
Create any date you want. Here is an easy way to get the month you want.
$date = [datetime]::Parse("11/2019")
Then simply add the next month and remove one day. p
$date.AddMonths(1).AddDays(-1)
Hope this helps somebody else.

Related

Extract time from date time and find difference between 2 times

I am trying to convert EPOC time to date time and need to extract the time only from that
I am doing below
$min = $Time_Start | measure -Minimum
$max = $Time_End | measure -Maximum
[datetime]$oUNIXDatemin=(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($min.Minimum))
$oUNIXDatemin_1 = $oUNIXDatemin.ToString("HH:mm:ss")
[datetime]$oUNIXDatemax=(Get-Date 01.01.1970)+([System.TimeSpan]::fromseconds($max.Maximum))
$oUNIXDatemax_1 = $oUNIXDatemax.ToString("HH:mm:ss")
Problem is while converting I am getting $oUNIXDatemin_1 and $oUNIXDatemax_1 value like
$oUNIXDatemin_1
12 October 2021 07:46:46
$oUNIXDatemax_1
12 October 2021 21:16:04
My EPOC values are
$min.Minimum
1634024806
$max.Maximum
1634073364
Please let me know what is wrong here. Need to find the difference in HH:mm:ss format.
In PowerShell, you'd usually use a format string. Subtracting two PowerShell datetimes returns a value of type Timespan, which is well-behaved over a span of more than 24 hours.
([datetime]"12 October 2021 21:16:04" - [datetime]"12 October 2021 07:46:46") -f "HH:mm:ss"
13:29:18
Be careful here. Both intervals (durations) and time (of day) have the same format, but different meanings. For example, it makes sense to multiply the interval "01:00:00" (1 hour) by 3 to get three hours; it doesn't make sense to multiply the time "01:00:00" (1 o'clock AM) by 3.
I'm sure the overall calculation can be simplified, but it's too early for me.

Retrieve datetime object in Powershell without the time portion

Is it possible to retrieve only the date portion of a datetime object in PowerShell? Reason being I need to compare the LastWriteTime property of files with today's date to determine whether to backup a file or not. As-is a datetime object includes the time as well which will always evaluate to false when I do something like:
if ($fileDate -eq $currentDate) {
# Do backup
}
I haven't found anyway to do this. If we use the format operator or a method, it converts the object to a string object. If you try to convert that back to a datetime object, it appends the time back onto the object. Probably something simple, but I've been looking at this script for a while and that's the last part that's breaking.
EDIT: As #jessehouwing points out in the comments below, my answers are unnecessarily complicated. Just use $datetime.Date.
A couple of ways to get a DateTime without any time component (ie set to midnight at the start of the date in question, 00:00:00):
$dateTime = <some DateTime>
$dateWithoutTime = $dateTime.AddSeconds(-$dateTime.Second).AddMinutes(-$dateTime.Minute).AddHours(-$dateTime.Hour)
or
$dateTime = <some DateTime>
$dateWithoutTime = Get-Date -Date ($dateTime.ToString("yyyy-MM-dd"))
I ran each version in a loop, iterating 100,000 times. The first version took 16.4 seconds, the second version took 26.5 seconds. So I would go with the first version, although it looks a little more complicated.
Based on answers found here: https://techibee.com/powershell/powershell-how-to-query-date-time-without-seconds/2737 (that article is about stripping just the seconds from a DateTime. But it can be extended to stripping hours, minutes and seconds).
Assuming $fileDate is not a dateTime object, then you can just convert both to strings and format them.
if ($fileDate.ToString() -eq $currentDate.ToString("dd/MM/yyyy")) {
# Do backup
}
This will not answer how to remove time on datetime, but to do your validation purpose of identifying when to backup.
I do suggest to subtract your two given date values and compare the result if total hours are already met to do your backup.
if (( $currentDate - $fileDate ).TotalDays > 7) {
# Do Backup
}
you can also validate for the following
Days :
Hours :
Minutes :
Seconds :
Milliseconds :
Ticks :
TotalDays :
TotalHours :
TotalMinutes :
TotalSeconds :
TotalMilliseconds :
Assuming $currentTime contains a DateTime object, you can retrieve a new DateTime object with the same date but with the time portion zeroed like this:
$midnight = Get-Date $currentTime -Hour 0 -Minute 0 -Second 0 -Millisecond 0

Calculate number of days between two dates in Perl

I am using Perl to create a script that will email password expiration notifications.
I have two dates:
The date that the users password was set
The date that the users password will expire (180 days after the password was set)
use DateTime::Format::Strptime;
my $dt_pattern = DateTime::Format::Strptime->new( pattern => '%F',);
my $displayName = $entry->get_value("displayName");
my $pwdLastSet = convertWinFileTimestamp($entry->get_value("pwdLastSet"));
# Determine password expiration date
my $pwdLastSet_dt = $dt_pattern->parse_datetime($pwdLastSet);
my $pwdExpirationDate = $pwdLastSet_dt->add( days => $maxPwdAge );
# Days until password expires
# HELP!!!!!!!
sub convertWinFileTimestamp {
my $timestamp = shift;
# Strip off nanoseconds, then adjust date from AD epoch (1601) to UNIX epoch (1970)
return POSIX::strftime( "%Y-%m-%d",
localtime( ( $timestamp / 10000000 ) - 11644473600 ) );
}
I cannot figure out how to calculate the difference between the two dates!
Below is the output for each variable:
pwdLastSet: 2015-02-12
pwdExpireDate: 2015-08-11T00:00:00
Any help much appreciated...been googling like crazy but I can't figure it out...Thanks!
I tried the following lines of code:
my $pwdDaysLeft = int(($pwdExpirationDate - $pwdLastSet) / 86400);
but got the following error:
Only a DateTime::Duration or DateTime object can be subtracted from a DateTime object. at pwdreminder.pl line 65
So, we have three dates here:
The date that the password was last set. This starts off as a string in the format YYYY-MM-DD stored in $pwdLastSet, but then you parse it into a DateTime object stored in $pwdLastSet_dt.
The date that the current password expires. This is calculated by adding $maxPwdAge days to $pwdLastSet_dt, which gives a DateTime object which is then stored in $pwdExpirationDate.
The current date. Which, in your current code, you don't calculate.
What you actually want is the difference in days a between the second and third of these two dates. We can ignore the first date as is it only used to calculate the second date. I assume that you're calculating that correctly.
Hopefully, the password expiration date will always be in the future. So the calculation we want to do is:
my $diff = $pwdExpirationDate - $current_date;
As long as both of those are DateTime objects, we'll get a DateTime::Duration object back, which we can then ask for the number of days.
DateTime has a today() method that will give the current date. So our code becomes:
# Use delta_days() to get a duration object that just contains days
my $diff = $pwdExpirationDate->delta_days(DateTime->today);
print $diff->in_units('days');

GWT DateTimeFormat returns the wrong date

I have the following code
String test = "21/04/2013";
fmt = DateTimeFormat.getFormat("MM/dd/yyyy");
Date dateTest = fmt.parse(test);
Window.alert(fmt.format(dateTest));
And the alert box shows the date
09/04/2014
instead of
21/04/2013
Why?
As others already say, it's because of your pattern. What they don't say is why it behaves that way.
When parsing 21/04/2013 as MM/dd/yyyy, DateTimeFormat will decompose the date as:
Month Day of month Year
21 4 2013
and it'll then adjust things to make a valid date. To do that, the Month part is truncated at 12 (so that temporary date is Dec 4th, 2013) and the remainder (21 - 12 = 9) is then added, leading to Sept. 4th 2014, which according to your format displays as 09/04/2014.
You wanted to show 21/04/2013 but the format was MM/dd/yyyy.
It should be dd/MM/yyyy
So change it like this:
String test = "21/04/2013";
fmt = DateTimeFormat.getFormat("dd/MM/yyyy");
Date dateTest = fmt.parse(test);
Window.alert(fmt.format(dateTest));
You're reversing day and month.
String test = "21/04/2013";
fmt = DateTimeFormat.getFormat("dd/MM/yyyy");
Date dateTest = fmt.parse(test);
Window.alert(fmt.format(dateTest));

Zend_Date : expanding a 2 digit year value to 4 digit year

Have a date of birth in format 'MM/dd/yy' for people born in the 1900's. I'm using Zend_Date to
parse and convert the string value
$date = new Zend_Date();
$logger->info(sprintf('Convert DOB %s -> %s',$dateOfBirth,$date->toString('yyyy-M-dd')));
I get
2010-06-24T16:55:50+00:00 INFO (6): DOB 9/13/57
2010-06-24T16:55:50+00:00 INFO (6): Convert DOB : 9/13/57 -> 2057-9-13
I expected
2010-06-24T16:55:50+00:00 INFO (6): Convert 9/13/57 -> 1957-9-13
What am i missing? I don't think this is related to the real year 'yyyy' / ISO year 'YYYY' handling in Zend_Date.
My current horrible hack
$formattedDate = $date->toString('dd/M').'/19'.$date->toString('YY');
short (1 or 2 digit) version of YEAR is always in current century.
so use:
$dob = '9/13/57';
$date = new Zend_Date($dob, 'M/d/yy');
echo $date->subYear(100)->toString('YYYY-MM-d');
Apparently, it's a bit more complicated. According to this site, 2-digit years greater than or equal to 70 become 1970-1999 whereas those less than 70 become 2000-2069.