Add -UnixTimeSeconds to Get-Date to allow Unix time input (#13084)

This commit is contained in:
aetos
2020-08-12 10:13:59 -07:00
committed by GitHub
parent 68d46c1792
commit ede10850cc
2 changed files with 63 additions and 31 deletions
@@ -14,9 +14,9 @@ namespace Microsoft.PowerShell.Commands
/// <summary>
/// Implementation for the get-date command.
/// </summary>
[Cmdlet(VerbsCommon.Get, "Date", DefaultParameterSetName = "net", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096615")]
[OutputType(typeof(string), ParameterSetName = new string[] { "UFormat", "net" })]
[OutputType(typeof(DateTime), ParameterSetName = new string[] { "net" })]
[Cmdlet(VerbsCommon.Get, "Date", DefaultParameterSetName = DateAndFormatParameterSet, HelpUri = "https://go.microsoft.com/fwlink/?LinkID=2096615")]
[OutputType(typeof(string))]
[OutputType(typeof(DateTime), ParameterSetName = new[] { DateAndFormatParameterSet, UnixTimeSecondsAndFormatParameterSet })]
public sealed class GetDateCommand : Cmdlet
{
#region parameters
@@ -24,7 +24,8 @@ namespace Microsoft.PowerShell.Commands
/// <summary>
/// Allows user to override the date/time object that will be processed.
/// </summary>
[Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[Parameter(ParameterSetName = DateAndFormatParameterSet, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[Parameter(ParameterSetName = DateAndUFormatParameterSet, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)]
[Alias("LastWriteTime")]
public DateTime Date
{
@@ -40,14 +41,38 @@ namespace Microsoft.PowerShell.Commands
}
}
private DateTime _date;
private bool _dateSpecified;
// The const comes from DateTimeOffset.MinValue.ToUnixTimeSeconds()
private const long MinimumUnixTimeSecond = -62135596800;
// The const comes from DateTimeOffset.MaxValue.ToUnixTimeSeconds()
private const long MaximumUnixTimeSecond = 253402300799;
/// <summary>
/// Gets or sets whether to treat a numeric input as ticks, or unix time.
/// </summary>
[Parameter]
public SwitchParameter FromUnixTime { get; set; }
[Parameter(ParameterSetName = UnixTimeSecondsAndFormatParameterSet, Mandatory = true)]
[Parameter(ParameterSetName = UnixTimeSecondsAndUFormatParameterSet, Mandatory = true)]
[ValidateRange(MinimumUnixTimeSecond, MaximumUnixTimeSecond)]
[Alias("UnixTime")]
public long UnixTimeSeconds
{
get
{
return _unixTimeSeconds;
}
private DateTime _date;
private bool _dateSpecified;
set
{
_unixTimeSeconds = value;
_unixTimeSecondsSpecified = true;
}
}
private long _unixTimeSeconds;
private bool _unixTimeSecondsSpecified;
/// <summary>
/// Allows the user to override the year.
@@ -212,21 +237,22 @@ namespace Microsoft.PowerShell.Commands
/// <summary>
/// Unix format string.
/// </summary>
[Parameter(ParameterSetName = "UFormat")]
[ValidateNotNullOrEmpty]
[Parameter(ParameterSetName = DateAndUFormatParameterSet, Mandatory = true)]
[Parameter(ParameterSetName = UnixTimeSecondsAndUFormatParameterSet, Mandatory = true)]
public string UFormat { get; set; }
/// <summary>
/// Unix format string.
/// DotNet format string.
/// </summary>
[Parameter(ParameterSetName = "net")]
[Parameter(ParameterSetName = DateAndFormatParameterSet)]
[Parameter(ParameterSetName = UnixTimeSecondsAndFormatParameterSet)]
[ArgumentCompletions("FileDate", "FileDateUniversal", "FileDateTime", "FileDateTimeUniversal")]
public string Format { get; set; }
/// <summary>
/// Gets or sets a value that converts date to UTC before formatting.
/// </summary>
[Parameter(ParameterSetName = "net")]
[Parameter]
public SwitchParameter AsUTC { get; set; }
#endregion
@@ -243,14 +269,11 @@ namespace Microsoft.PowerShell.Commands
// use passed date object if specified
if (_dateSpecified)
{
if (FromUnixTime.IsPresent)
{
dateToUse = DateTimeOffset.FromUnixTimeSeconds(Date.Ticks).UtcDateTime;
}
else
{
dateToUse = Date;
}
dateToUse = Date;
}
else if (_unixTimeSecondsSpecified)
{
dateToUse = DateTimeOffset.FromUnixTimeSeconds(UnixTimeSeconds).LocalDateTime;
}
// use passed year if specified
@@ -544,6 +567,11 @@ namespace Microsoft.PowerShell.Commands
}
#endregion
private const string DateAndFormatParameterSet = "DateAndFormat";
private const string DateAndUFormatParameterSet = "DateAndUFormat";
private const string UnixTimeSecondsAndFormatParameterSet = "UnixTimeSecondsAndFormat";
private const string UnixTimeSecondsAndUFormatParameterSet = "UnixTimeSecondsAndUFormat";
}
#endregion
@@ -98,11 +98,11 @@ Describe "Get-Date DRT Unit Tests" -Tags "CI" {
}
It "Passing '<name>' to -uformat produces a descriptive error" -TestCases @(
@{ name = "`$null" ; value = $null }
@{ name = "empty string"; value = "" }
@{ name = "`$null" ; value = $null; errorId = "ParameterArgumentValidationErrorNullNotAllowed" }
@{ name = "empty string"; value = ""; errorId = "ParameterArgumentValidationErrorEmptyStringNotAllowed" }
) {
param($value)
{ Get-Date -Date 1/1/1970 -UFormat $value -ErrorAction Stop } | Should -Throw -ErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetDateCommand"
param($value, $errorId)
{ Get-Date -Date 1/1/1970 -UFormat $value -ErrorAction Stop } | Should -Throw -ErrorId "${errorId},Microsoft.PowerShell.Commands.GetDateCommand"
}
It "Get-date works with pipeline input" {
@@ -193,13 +193,17 @@ Describe "Get-Date" -Tags "CI" {
$timeDifference.Ticks | Should -BeLessThan 10000
}
It "-FromUnixTime works" {
It "-UnixTimeSeconds works" -TestCases @(
@{ UnixTimeSeconds = 1577836800; Expected = [System.DateTimeOffset]::FromUnixTimeSeconds(1577836800).LocalDateTime },
@{ UnixTimeSeconds = 0; Expected = [System.DateTimeOffset]::UnixEpoch.LocalDateTime },
@{ UnixTimeSeconds = -1; Expected = [System.DateTimeOffset]::FromUnixTimeSeconds(-1).LocalDateTime }
) {
param(
[long] $UnixTimeSeconds,
[DateTime] $Expected
)
# Test conversion of arbitrary date in Unix time: 2020-01-01​T00:00:00.000Z
Get-Date -Date 1577836800 -FromUnixTime | Should -Be (Get-Date -Date 637134336000000000 -AsUTC)
# Test converstion of Unix time start date: 1970-01-01​T00:00:00.000Z
Get-Date -Date 0 -FromUnixTime | Should -Be (Get-Date -Date 621355968000000000 -AsUTC)
Get-Date -UnixTimeSeconds $UnixTimeSeconds | Should -Be $Expected
}
}