I'm trying to get a person age in Years,Months,Days,Hours,Minutes and Seconds.
This is what I got so far (you can tell I'm a total powershell beginner):
$now = [datetime]::now
[datetime]$birthday = "12/22/2012 03:22:00"
$age = [datetime]$now - $birthday
Write-Host "My daughter's age is:" $age.Days "days" ($age.Hours) "hours" ($age.Minutes) "minutes" ($age.Milliseconds) "seconds"
The output is:
My daughter's age is: 59 days 10 hours 27 minutes 76 seconds
It's ok, but it would be more awesome have the output more 'human readable':
1 Month 19 Days 10 hours 28 minutes 16 seconds
This is actually way more difficult than I initially expected. The code must know how many days has each month in order to split days into months and days. And also consider that this year is leap year!
Maybe PowerShell can help here with some of its magic!
Thank you!
I believe this is what you're after.
[datetime]$birthday = "12/22/2012 03:22:00"
$span = [datetime]::Now - $birthday
$age = New-Object DateTime -ArgumentList $Span.Ticks
Write-Host "My daughter's age is:" $($age.Year -1) Years $($age.Month -1) Months $age.Day "days" ($age.Hour) "hours" ($age.Minute) "minutes" ($age.second) "seconds"
Check it with the day after your birthday. There is 1 day to much!
Correct are:
[datetime]$birthday = "12/22/2012 03:22:00"
$span = [datetime]::Now - $birthday
$age = New-Object DateTime -ArgumentList $Span.Ticks
Write-Host "My daughter's age is:" $($age.Year-1) Years $($age.Month-1) Months ($age.Day-1) "days" ($age.Hour) "hours" ($age.Minute) "minutes" ($age.second) "seconds"
Related
I need to get the numbers of ( weeks and days) between 2 dates.
If day reachs 7 then it turns to 0 and add one 1 to the weeks .
A weeks never pass to mounths althought the value is increasing everytime .
for exemple :
Date : 01/01/2022 ,
Today : 05/03/2022 ,
the difference between he two days is : 8 weeks and 5 days .
here is the picture i'm showing exemple of UI :
enter image description here
You will need to use DateTime object to create 2 objects, then use DateTime.differece() the you can get the number of day using inDay and finally divide by 7 and round the output to be the number of weeks then the difference will be the number of day
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
totalDays = to.difference(from).inDays
of (totalDays < 7) {
daysDiff = totalDays
} else {
totalFullWeeks = (totalDay / 7).ceil()
daysDiff = totalDay - totalFullWeeks*7
}
Fairly new to PS, I want to batch file on Sunday between the 1st and the 2nd Tuesday of the month.
I know how to find the the 1st and 2nd Tuesdays I am looking for, cannot figure out the rest.
$FindNthDay = 1
$WeekDay = 'Tuesday'
[datetime]$Today = [datetime]::NOW
$todayM = $Today.Month.ToString()
$todayY = $Today.Year.ToString()
[datetime]$StrtMonth1 = $todayM + '/1/' + $todayY
while ($StrtMonth1.DayofWeek -ine $WeekDay ) { $StrtMonth1 = $StrtMonth1.AddDays(1) }
$StrtMonth1.AddDays(7 * ($FindNthDay - 1))
#
$FindNthDay = 2
$WeekDay = 'Tuesday'
[datetime]$Today = [datetime]::NOW
$todayM = $Today.Month.ToString()
$todayY = $Today.Year.ToString()
[datetime]$StrtMonth = $todayM + '/1/' + $todayY
while ($StrtMonth.DayofWeek -ine $WeekDay ) { $StrtMonth = $StrtMonth.AddDays(1) }
$StrtMonth.AddDays(7 * ($FindNthDay - 1))
I know how to find the the 1st and 2nd Tuesdays
Since there's only one Sunday in between, you only need to find the first one:
# Get-Date -Day 1 will give us the 1st of the current month
$firstTuesday = Get-Date -Day 1
while($firstTuesday.DayOfWeek -ne 'Tuesday') {
$firstTuesday = $firstTuesday.AddDays(1)
}
And then add another 5 days:
$sundayAfterFirstTuesday = $firstTuesday.AddDays(5).Date
Which (in January 2021) gives us:
PS ~> $sundayAfterFirstTuesday
Sunday, January 10, 2021 12:00:00 AM
In addition to Mathias's fine answer, I got hung up on this. Given that .DayOfWeek is an [enum] that's easily converted to a [Int] I was looking for a mathematically concise way to derive the first Tuesday. Since it's fairly obvious how to then find the following Sunday by just doing .AddDays(5) .
Honestly, I was stumbling a bit because While .DayOfWeek is 0 - 6 how many days to add depends on if the current day, in this case the first of the month, is less than or greater than Tuesday (2). It was worth playing around; here are 2 alternate approaches I came up with:
Example 1: A switch statement that's not at all concise but is very readable:
$Day1 = Get-Date "1/1/2021"
Switch ( $Day1.DayOfWeek )
{
'Sunday' { $Sunday = $Day1.Adddays(2).AddDays( 5 ); Break }
'Monday' { $Sunday = $Day1.Adddays(1).AddDays( 5 ); Break }
'Tuesday' { $Sunday = $Day1.AddDays( 5 ); Break }
'Wednesday' { $Sunday = $Day1.Adddays(6).AddDays( 5 ); Break }
'Thursday' { $Sunday = $Day1.Adddays(5).AddDays( 5 ); Break }
'Friday' { $Sunday = $Day1.Adddays(4).AddDays( 5 ); Break }
'Saturday' { $Sunday = $Day1.Adddays(3).AddDays( 5 ); Break }
}
$Sunday
This is also easy to adjust. For example, if you wanted to switch to 1st Sunday between 1st & 2nd Monday etc...
For the mathematical / logic approach it came out a little more crude:
$Day1 = Get-Date "1/1/2021"
If( [Int]$Day1.DayOfWeek -gt 2 ) { $Interval = 7 - ([Int]$Day1.DayOfWeek - 2) }
Else { $Interval = 2 - [Int]$Day1.DayOfWeek }
$Sunday = $Day1.AddDays( $Interval ).AddDays( 5 )
$Sunday
The above example can be more concise in PowerShell 7+ using the ternary operator:
$Day1 = Get-Date "1/1/2021"
$Interval = $Day1.DayOfWeek -gt 2 ? 7 - ([Int]$Day1.DayOfWeek - 2) : 2 - [Int]$Day1.DayOfWeek
$Sunday = $Day1.AddDays( $Interval ).AddDays( 5 )
$Sunday
Note: all of the examples user 1/1/2021 as the starting date, but I did test across multiple 1st days of the month, For example, if the first day was a Monday, Sunday, Thursday etc...
Note: Some of the [Int] casting can probably be removed if one is careful about PowerShell type conversion system, but I wanted to get this out there. If I have time I'll cleanup further.
Or a slightly different approach:
$BaseDate = (Get-Date 3/1/2021)
$BaseDate.AddDays( (& {if ([int]$BaseDate.DayOfWeek -gt 2) {14}
else { 7 } }) - [int]($BaseDate).DayOfWeek)
Sunday, March 7, 2021 12:00:00 AM
I'm having a problem with Coldfusion's DateDiff(). I'm trying to get the difference between two dates with times, like the following examples:
fromdate=06/11/2017 22:10
todate =16/11/2017 23:20
should return:
10 days, 1 hour and 10 minutes
fromdate=06/11/2017 22:10
todate =16/11/2017 20:20
should return:
9 days, 22 hours, 10 minutes
Any help?
Code:
<cfset dtFrom = "11/06/2017 22:10" />
<cfset dtTo = "11/16/2017 23:20" />
<cfoutput>
#DateDiff( "d", dtFrom, dtTo)# Days,
#DateDiff( "h", dtFrom, dtTo) % 24# Hours
#DateDiff( "n", dtFrom, dtTo) % 24 % 60# Minutes
</cfoutput>
In addition to the previous suggestion, DateDiff() isn't going to understand those specific strings or that "06/11/2017" should mean November 6. The result will be:
158 days 1 hours 10 minutes
For it to work as expected, you must convert the strings into date objects first. For example use LSParseDateTime with the right Locale.
fromDate = lsParseDateTime("06/11/2017 22:10", "English (UK)", "dd/MM/yyyy hh:mm");
toDate = lsParseDateTime("16/11/2017 23:20", "English (UK)", "dd/MM/yyyy hh:mm");
or possibly:
fromDate = lsParseDateTime("06/11/2017 22:10", "English (UK)");
toDate = lsParseDateTime("16/11/2017 23:20", "English (UK)");
Here is one way.
totalMinutes = datediff("n", fromDate, toDate);
days = int(totalMinutes /(24 * 60)) ;
minutesRemaining = totalMinutes - (days * 24 * 60);
hours = int(minutesRemaining / 60);
minutes = minutesRemaining mod 60;
writeoutput(days & ' days ' & hours & ' hours ' & minutes & ' minutes');
I have the need to retrieve the number of days in the current month, and despite my research, I have yet to find anything in powershell that does it. The following is what I have currently built to get the result I want. is there a better way to do it?
Please note that I am limited to Powershell
#check to see if this is a leap year
function LYC
{
if ([System.DateTime]::isleapyear((Get-Date).Year))
{
$Global:LY = True
}
}
#Get the number of days in current month
function fNOD
{
$MNum = (Get-Date).Month
switch ($MNum)
{
1 {$Global:DaysInMonth=31}
2 {
LYC
if (LY)
{
$Global:DaysInMonth=29
} else {
$Global:DaysInMonth=28
}
}
3 {$Global:DaysInMonth=31}
4 {$Global:DaysInMonth=30}
5 {$Global:DaysInMonth=31}
6 {$Global:DaysInMonth=30}
7 {$Global:DaysInMonth=31}
8 {$Global:DaysInMonth=31}
9 {$Global:DaysInMonth=30}
10 {$Global:DaysInMonth=31}
11 {$Global:DaysInMonth=30}
12 {$Global:DaysInMonth=31}
}
}
http://msdn.microsoft.com/en-us/library/system.datetime.daysinmonth.aspx
# static int DaysInMonth(int year, int month)
[DateTime]::DaysInMonth(2013, 3)
Assuming you want it for any date stored in $date:
((get-date $date -Day 1 -hour 0 -Minute 0 -Second 0).AddMonths(1).AddSeconds(-1)).Day
This seems to me like it might be deceptively easy:
$numDays = ((Get-Date -Month 3) - (Get-Date -Month 2))
28 days in February, July minus June gives me 30 days.
As mentioned below, that apparently sometimes does some weird integer rounding that gives off 29d, 23h, 59m or something else not right.
This seems to be consistent:
$monthLess = Get-Date -Month 4
$NumDays = (Get-Date -Month 5).Subtract($monthLess)
I can't get my head around how formatting a datetime variable inside a string works in PowerShell.
$startTime = Get-Date
Write-Host "The script was started $startTime"
# ...Do stuff...
$endTime = Get-Date
Write-Host "Done at $endTime. Time for the full run was: $( New-TimeSpan $startTime $endTime)."
gives me the US date format while I want ISO 8601.
I could use
$(Get-Date -Format u)
but I want to use $endTime to make the calculation of the timespan correct.
I have tried all permutations of $, (, ), endTime, -format, u, .ToString(...) and .ToShortDate(), but the one that works.
"This is my string with date in specified format $($theDate.ToString('u'))"
or
"This is my string with date in specified format $(Get-Date -format 'u')"
The sub-expression ($(...)) can include arbitrary expressions calls.
Microsoft Documents both standard and custom DateTime format strings.
You can use the -f operator
$a = "{0:D}" -f (get-date)
$a = "{0:dddd}" -f (get-date)
Spécificator Type Example (with [datetime]::now)
d Short date 26/09/2002
D Long date jeudi 26 septembre 2002
t Short Hour 16:49
T Long Hour 16:49:31
f Date and hour jeudi 26 septembre 2002 16:50
F Long Date and hour jeudi 26 septembre 2002 16:50:51
g Default Date 26/09/2002 16:52
G Long default Date and hour 26/09/2009 16:52:12
M Month Symbol 26 septembre
r Date string RFC1123 Sat, 26 Sep 2009 16:54:50 GMT
s Sortable string date 2009-09-26T16:55:58
u Sortable string date universal local hour 2009-09-26 16:56:49Z
U Sortable string date universal GMT hour samedi 26 septembre 2009 14:57:22 (oups)
Y Year symbol septembre 2002
Spécificator Type Example Output Example
dd Jour {0:dd} 10
ddd Name of the day {0:ddd} Jeu.
dddd Complet name of the day {0:dddd} Jeudi
f, ff, … Fractions of seconds {0:fff} 932
gg, … position {0:gg} ap. J.-C.
hh Hour two digits {0:hh} 10
HH Hour two digits (24 hours) {0:HH} 22
mm Minuts 00-59 {0:mm} 38
MM Month 01-12 {0:MM} 12
MMM Month shortcut {0:MMM} Sep.
MMMM complet name of the month {0:MMMM} Septembre
ss Seconds 00-59 {0:ss} 46
tt AM or PM {0:tt} ““
yy Years, 2 digits {0:yy} 02
yyyy Years {0:yyyy} 2002
zz Time zone, 2 digits {0:zz} +02
zzz Complete Time zone {0:zzz} +02:00
: Separator {0:hh:mm:ss} 10:43:20
/ Separator {0:dd/MM/yyyy} 10/12/2002
Instead of using string interpolation you could simply format the DateTime using the ToString("u") method and concatenate that with the rest of the string:
$startTime = Get-Date
Write-Host "The script was started " + $startTime.ToString("u")