Cannot convert this string to Date object in Powershell - powershell

I've been struggling with this for some time now and I've tried everything I could find but, have yet to be successful. I need to convert this string to a Powershell date object:
20180802 16:30:10
Everytime I try ParseExact, it's saying that it doesn't recognize the string as a valid date/time format.

Following works perfectly:
[DateTime]::ParseExact('20180802 16:30:10', 'yyyyMMdd HH:mm:ss', [CultureInfo]::InvariantCulture)
I bet your problem is 24 hour format.

Pawel Dyl's helpful answer is the correct and robust solution.
Just to offer a shortcut that may be of interest in similar situations where only a simple textual reformatting is needed in order for a [datetime] cast to recognize a string containing a date/time representation:
Transforming 20180802 16:30:10 to 2018-08-02 16:30:10 would work:
PS> [datetime] ('20180802 16:30:10' -replace '^(\d{4})(\d{2})', '$1-$2-')
Thursday, August 2, 2018 4:30:10 PM # sample output on a US-English system
Note that a [datetime] cast in PowerShell uses the invariant culture, as PowerShell does in many contexts.

Related

Powershell Cleanest way to convert a string to mmddyyyy format

Thank you in advance...
I have String output:
2021-12-23
the string Base.Type is System.Object
I would like to convert it to:
12-23-2021
or
12/23/2021
any ideas?
Note: This question is a near-duplicate of Change date format from "yyyymmdd" to "mm/dd/yyyy"; while the two are closely related, this question is more overtly focused on both parsing from a string to a date and then back to a string, using a different format; by contrast, the linked question has the from aspect covered as an incidental part of the question.
Bali C, in a comment on the question, came up with the most concise solution, which only requires a small tweak:
# Note the "\"-escaped separators - see below.
PS> Get-Date -Date 2021-12-23 -Format dd\-MM\-yyyy # or dd\/MM\/yyyy
23-12-2021
This will work with most cultures in effect, because format yyyy-MM-dd (as exemplified by your sample input string, '2021-12-23') is a recognized format in all but a few cultures.
PowerShell generally tries to use the invariant culture in order for code to work the same across cultures, but in the case of cmdlet arguments actually is culture-sensitive, which is a historical accident that cannot be fixed without breaking backward compatibility.
See below for a truly culture-invariant solution, which also explains why separator chars. - and / should be escaped for maximum robustness.
Since PowerShell's casts use the invariant culture and format yyyy-MM-dd (as exemplified by your sample input string, '2021-12-23') happens to be a recognized format in that culture, you can simply:
cast your string to [datetime] to create a System.DateTime instance
and then call .ToString() with the desired format string to produce the desired string format, as shown in the many answers to this question.
The following should work irrespective of the specific culture in effect:
PS> ([datetime] '2021-12-23').ToString('MM\-dd\-yyyy')
12-23-2021
PS> ([datetime] '2021-12-23').ToString('MM"/"dd"/"yyyy')
12/23/2021
Note that the separator chars. - and / are escaped / quoted so as to indicate that they're to be used verbatim (you're free to choose between \-escaping and embedded quoting).
This is necessary, because characters such as / are by default interpreted as placeholders for the culture-appropriate date separator, for instance, so - depending on the culture in effect (as reflected in $PSCulture) - they may be translated to a different character, such as ., for instance.
If your original string representation were not recognized in the invariant culture, you can use System.DateTime.ParseExact to parse your input string into a [datetime] (System.DateTime) instance before calling .ToString() as described above:
[datetime]::ParseExact(
'2021-12-23',
'yyyy\-MM\-dd',
$null # current culture
).ToString('MM"-"dd"-"yyyy')
The above again yields '12-23-2021'.
Note that, due to use of $null, the current culture is used for parsing, which has no effect in this case, however, given that the separator chars. use embedded quoting, and given that only digits are involved, not (culture-dependent) names, such as month names.
If you do need the context of a specific culture, pass a [cultureinfo] instance (System.Globalization.CultureInfo) instead of $null; e.g., to parse in the context of the French (France) culture, pass [cultureinfo] 'fr-FR'.

How to format Get-Date Day as 2 digits in Powershell

I try to get the Day as a two digit number out of Get-Date in PowerShell.
When I try (Get-Date).Day the result will be for example 6 but I want to have it as 06. Also for the month.
How can this be done?
I have already tried things like (Get-Date).Day.ToString("dd") but it doesn't work.
Using ToString() and supplying date formatters (e.g. "yyyy" or "dd") will only work on dates. By accessing .Day or .Year, the operation is instead attempted on an integer, which will fail.
Try (for the day):
(Get-Date).ToString("dd")
...and (and for the month):
(Get-Date).ToString("MM")
See here for custom formatting of dates using ToString()

How to get the previous hour time with format in powershell?

I need to find the previous hour time with formatting with PS:
I need the below format:
"yyyy-MM-dd-HH:mm:sstt")
I can use the below code to get the date and time in this format:
(Get-Date -Format "yyyy-MM-dd-HH:mm:sstt")
2019-09-17-08:45:27AM
I need to get the previous hour time but in the above format
I know how to get the last hour time :
(Get-Date).AddHours(-1)
How can i get the previous hour time with a combination of the above
Format?
Using -f, the format operator, as shown in Ivan Mirchev's helpful answer is definitely an option, and -f is a great general-purpose formatting option to know about, for any data type.
However, in your particular case there is a simpler solution, because the .ToString() method of [datetime] instances directly accepts a format string:
(Get-Date).AddHours(-1).ToString('yyyy-MM-dd-HH:mm:sstt')
You may try using the format operator:
"{0:yyyy-MM-dd-HH:mm:sstt}" -f (get-date).AddHours(-1)
more details: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-6#format-operator--f
Hope it helps! :)

Error with String to DateTime conversion in PowerShell (it used to work before)

A script is parsing values from a *.csv file.
One of the values is a timestamp in the format 7/21/2018 7:07 AM UTC
This line used to work before:
$DR.Item($property.Name) = (
[System.DateTime](Get-Date($property.value -replace " UTC", ""))
).TolocalTime() -f "MM/d/yyyy HH:mm:ss"
It is not working anymore. I get the following error:
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "7/21/2018 7:07 AM" to type "System.DateTime". Error: "String was not recognized as a valid
DateTime."
Your command failing suggests that the current culture ([cultureinfo]::CurrentCulture) at the time of execution is something other than en-US (US-English), in which case Get-Date won't recognize a date/time string such as "7/21/2018 7:07 AM[1].
The solution is to use a [datetime] cast directly, without involving Get-Date, because a [datetime]cast always uses the invariant culture, which is like the en-US culture with respect to date/time formats:
$DR.Item($property.Name) = ([datetime] ($property.value -replace ' UTC$')) -f "MM/d/yyyy HH:mm:ss"
Caveat: Your call to .ToLocalTime() is not needed for output formatting, as the [datetime] instance you receive will behave as if it were in local time by default, even though it technically is time-zone-agnostic, as reflected in its .Kind property containing Unspecified. That is, your output will reflect the UTC date and time, without indicating so.
If you truly want to translate the input UTC timestamp into the equivalent local time, more work is needed:
$dtUtc = [datetime]::SpecifyKind(($property.value -replace ' UTC$'), 'Utc')
$DR.Item($property.Name) = $dtUtc.ToLocalTime() -f "MM/d/yyyy HH:mm:ss"
[1] PowerShell generally uses the invariant culture when it comes to from-string and to-string type conversions, but, curiously, doesn't do so when passing strings as arguments to compiled cmdlets, as opposed to [advanced] functions (written in PowerShell).
This is a known problem, but it may not get fixed for reasons of backward compatibility.

How do I check if a date in format "yyyymmdd" is a weekday or not?

My program accepts date in the format of "yyyymmdd", I don't know how to check if it's a weekday or not. I've seen ppl using $(date +%u) -gt 5 or "$(date +%a)" in Sat|Sun echo "weekend" in other threads, but that ${date} is like Tue Nov 22 14:16:35 EST 2011 I guess. So is there a good way to convert "yyyymmdd" to ${date} format? Or is there a simple way to check if "yyyymmdd" is a weekday or not? Any language is fine. Thanks.
Any language? In Java I'd use SimpleDateFormat or Joda Time's DateTimeFormatter. In C# I'd either use DateTime.ParseExact or Noda Time's LocalDatePattern. In all of these cases, the result is a value which can be asked for things like the day of the week.
In Python I suspect you want datetime.strptime, e.g.
date = datetime.strptime(text, "%Y%m%d")
day = date.weekday()
if day < 5 # Monday(0) to Friday(4)
# Do something here
This is completely untested, however...
Normally, in a typed language (like Java, C# or Python), you'd 1) initialize your "time" to a language-specific "timedate" type, then 2) get the 'day-of-week" from some method of that time.
It looks like you're using Bourne shell. Which is an untyped language, with no native date/time functions.
Here's one possible solution:
http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/day-of-week-bash-script-2018531
Here are several time/timing related things you can do in the (Linux) Bourne shell:
http://tldp.org/LDP/abs/html/timedate.html