I propose to add parameters to the Get-Date command that allows specifying the time difference of the value to be output.
For example:
Get-Date [-Date <DateTime | DateTimeOffset>] [-TimeZone <TimeZoneInfo>] ...
Get-Date [-Date <DateTime | DateTimeOffset>] [-Offset <TimeSpan>] ...
If these parameters are specified, the value to be output will be DateTimeOffset.
Extend this parameter to accept DateTimeOffset.
Specify the time zone of the output.
This parameter can take the TimeZoneInfo object as well as its ID.
And it accepts UTC and Local as special values.
For example:
Get-Date -TimeZone (Get-TimeZone)
Get-Date -Date '2020-08-01T10:00:00-07:00' -TimeZone 'Asia/Tokyo'
Get-Date -TimeZone UTC
Specifies the offset of time from UTC of the value to be output.
For example:
Get-Date -Offset ([TimeSpan]::FromHours(-8))
Get-Date -Offset '-8:00'
The following example shows how to convert the time expressed in the US local time to time in Japan.
Get-Date -Date '2020-08-01 10:00' -TimeZone 'America/Los_Angels' | Get-Date -TimeZone 'Asia/Tokyo' -Format f
Sunday, August 2, 2020 2:00 PM
-AsLocal parameter. The -AsLocal switch is equivalent to -TimeZone Local.The -TimeZone parameter covers the functionality of the -AsUTC, -AsLocal, and -AsKind parameters, and more widely.
I believe that using DateTimeOffset is preferable to using DateTime and DateTimeKind.
-Date parameterThe -Date parameter must accept DateTime, DateTimeOffset and Int64.
Since there is no existing type that satisfies these requirements, we need to change the type of the -Date parameter to a custom type such as the following.
public readonly struct DateInput
{
public DateInput(DateTime dateTime) {}
public DateInput(DateTimeOffset dateTimeOffset) {}
public DateInput(long tick) {}
}
TimeZoneInfo objectTimeZoneInfo cannot be implicitly converted from a string representing its ID.
We can create a custom type for the -TimeZone parameter as described above, or create an attribute derived from the ArgentTransformationAttribute and assign it to -TimeZone parameter.
The TimeZoneInfo.FindSystemTimeZoneById method supports different time zone ID formats, depending on the platform.
For example, 'Pacific Standard Time' on Windows, 'America/Los_Angeles' on Linux.
We need to consider whether the parameter -TimeZone should be platform-independent and should be able to take the same value.
By using a library like TimeZoneConverter, we can make it platform-independent.
For example, a format like '10:00 AM PDT' is used to describe the start time of a webinar or system maintenance.
Abbreviations for time zones such as 'PDT' are widely used, but are not specified in official specifications such as ISO 8601 and are ambiguous.
I think it would be useful if the -TimeZone parameter could accept such abbreviations, but should we support this?
-AsUTC parameterConsider removing the -AsUTC parameter because its functionality is superseded by -TimeZone UTC.
This parameter was added in the 7.1 preview release and is not yet generally available.
DateTimeOffsetCurrently, the default output for DateTimeOffset is in the following format:
DateTime : 7/29/2020 10:31:25 PM
UtcDateTime : 7/30/2020 5:31:25 AM
LocalDateTime : 7/29/2020 10:31:25 PM
Date : 7/29/2020 12:00:00 AM
Day : 29
DayOfWeek : Wednesday
DayOfYear : 211
Hour : 22
Millisecond : 54
Minute : 31
Month : 7
Offset : -07:00:00
Second : 25
Ticks : 637316586850545851
UtcTicks : 637316838850545851
TimeOfDay : 22:31:25.0545851
Year : 2020
Output in the following format, like DateTime, will be easier to read.
Wednesday, July 29, 2020 10:31:25 PM (UTC -07:00)
The Get-Date cmdlet is already too complex. Maybe better to consider new Get-DateTimeOffset cmdlet?
We can't have one parameter accepting two different types. We _can_ have the parameter accept just DateTimeOffset, which from memory DateTime will convert to cleanly, but it would be somewhat confusing.
Personally if we can come up with a more intuitive name than Get-DateTimeOffset for the cmdlet (IMO that type name is _very_ unintuitive at best, it describes the implementation more than the usage/purpose) then I'm for a new cmdlet. Otherwise, Get-Date is the natural choice for it, but potentially in completely separate parameter sets.
"The Get-Date cmdlet is already too complex." - says who? What is lacking is some decent examples of how to use the blasted thing. I spent a week wrestling with [TimeZoneInfo]::GetSystemTimeZones() (which is different between Windows and Linux!) and figuring out DST shifts - this suggestion above would look to meet a very real need and Get-Date is the obvious cmdlet to address it.
We _can_ have the parameter accept just
DateTimeOffset
DateTime has a constructor that takes only one long, while DateTimeOffset does not.
So changing the type of the -Date parameter to DateTimeOffset makes calls like Get-Date -Date 1 impossible. This is a breaking change.
Not necessarily. We can implement a transformation attribute to bridge the gap there if needed. But yeah, that's definitely something to keep in mind, thanks! 馃挅
Good point, @vexx32; just to provide some conceptual background on conversions between [datetime] and [datetimeoffset] we need to be mindful of:
Get-Date -Date 1 currently outputs an Unspecified [datetime] instance, whereas [datetimeoffset] has no equivalent representation (all instances represent concrete, unambiguous points in time).
Converting an Unspecified [datetime] to a [datetimeoffset] effectively turns it into a _local_ date (that is the local time zone's then-current UTC offset is used).
Converting a [datetimeoffset] instance back to [datetime] (via the .Date or .DateTime properties) invariably returns an Unspecified [datetime] instance, irrespective of the instance's specific offset.
See also the musings on whether we should for conceptual simplicity eliminate Unspecified output altogether (technically, a breaking change): https://github.com/PowerShell/PowerShell/issues/11731#issuecomment-659279816
Most helpful comment
Good point, @vexx32; just to provide some conceptual background on conversions between
[datetime]and[datetimeoffset]we need to be mindful of:Get-Date -Date 1currently outputs anUnspecified[datetime]instance, whereas[datetimeoffset]has no equivalent representation (all instances represent concrete, unambiguous points in time).Converting an
Unspecified[datetime]to a[datetimeoffset]effectively turns it into a _local_ date (that is the local time zone's then-current UTC offset is used).Converting a
[datetimeoffset]instance back to[datetime](via the.Dateor.DateTimeproperties) invariably returns anUnspecified[datetime]instance, irrespective of the instance's specific offset.See also the musings on whether we should for conceptual simplicity eliminate
Unspecifiedoutput altogether (technically, a breaking change): https://github.com/PowerShell/PowerShell/issues/11731#issuecomment-659279816