Преобразовать строку в объект DateTime в заданном c часовом поясе с помощью Powershell - PullRequest
1 голос
/ 23 января 2020

С моим ограниченным знанием Powershell я пытаюсь преобразовать строку в текущем из:

2020-01-23 10:06:07

в объект datetime в часовом поясе Eastern Standard Time. В конечном итоге я хочу иметь возможность форматировать в соответствии со стандартом ISO8601 с правильным смещением от UT C.

20-01-23T10:06:07-05:00

Это достижимо в powershell? Я посмотрел на ConvertTimeFromUtc, но я изо всех сил стараюсь указать, что часовой пояс - это восточное стандартное время вместо GMT.

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Рассматривать данную номинальную дату (ту, которая не указана относительно к какому часовому поясу она относится) как единицу в EST Часовой пояс (восточное стандартное время США):

То есть преобразовать строку даты, например '2020-01-24 03:00:57', в экземпляр [datetimeoffset], представляющий этот неопределенный в терминах часового пояса строка в качестве даты / времени, локальных по отношению к часовому поясу EST (восточное стандартное время) (возможно, с примененным смещением DST (летнее время)), который затем можно отформатировать в формате ISO 8601, включающем спецификацию полученной даты c UT C смещение.

# Construct a nominal [datetime] instance whose .Kind property value is
# Unspecified (which means unspecified with respect to any particular
# time zone), which a cast from a string achieves:
$nominalDate = [datetime] '2020-01-24 03:00:57'

# Determine the target time zone.
# Note: On macOS and Linux, use 'America/New_York' (ICU library IDs).
$tz = [TimeZoneInfo]::FindSystemTimeZoneById('Eastern Standard Time')

# Get the UTC offset for the nominal date (.Kind == Unspecified), 
# which is interpreted as local to that time zone.
# The offset is returned as a [timespan] instance that properly reflects
# DST, if the date falls into the DST window of the target time zone.
# If the input date is ambiguous or invalid, standard time is assumed.
$utcOffset = $tz.GetUtcOffset($nominalDate)

# Construct a [datetimeoffset] instance with the UTC offset determined above.
# This in effect creates a date that represents the nominal date in the 
# target time zone, using that time zone's DST-appropriate UTC offset.
$dto = [DateTimeOffset]::new($nominalDate.Ticks, $utcOffset)

# Format according to ISO 8601 with UTC offset, but remove the
# fractional-seconds part:
# Note: With the standar "o" format specifier, only [datetimeoffset]
#       instances include their UTC offset in the resulting string,
#       not [datetime] instances.
$dto.ToString('o') -replace '\.\d+(?=-)'

Выше приведено '2020-01-24T03:00:57-05:00', по желанию.

С датой ввода в DST-окне, такой как '2020-07-24 03:00:57', получится
'2020-07-24T03:00:57-04:00' - обратите внимание, что смещение UT C теперь на час меньше.

См. Также: System.DateTime ([datetime], как литерал типа PowerShell), System.DateTimeOffset ([datetimeoffset]) и System.TimeZoneInfo ([TimeZoneInfo]) и Стандартные строки формата даты и времени .


Ниже приводится пример связанного использования с другой предпосылкой:

Для перевода данной локальной даты в эквивалент EST:

То есть преобразовать локальный момент времени, например, полученный с помощью Get-Date, в эквивалентное время в часовом поясе EST.

# Start with a local date, in any time zone.
# (A [datetime] instance whose .Kind property value is Local, though
#  Unspecified would work the same).
# Alternatively, start with a UTC date (where .Kind is UTC)
$localDate = Get-Date

# Translate it to Eastern Standard time, as a [datetimeoffset] instance.
# Note: Casting $localDate to [datetimeoffset] is crucial to ensure
#       that a [datetimeoffset] with the proper UTC offset is returned.
#       Without it, you'd get a [datetime] instance that is nominally
#       the correct time, but has an Unspecified .Kind value.
#       Also, only a [datetimeoffset] instance includes a UTC offset
#       when stringified with format string 'o'
$dtoEST = [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId(
  [datetimeoffset] $localDate, 
  'Eastern Standard Time'
)

# Format according to ISO 8601 with UTC offset, but remove the
# fractional-seconds part:
$dtoEST.ToString('o') -replace '\.\d+(?=-)'

Выше приведена строка, такая как '2020-01-23T16:44:41-05:00'.

0 голосов
/ 23 января 2020

В самом DataTime нет информации о часовом поясе. Если вы хотите преобразовать дату UT C в дату другой зоны, вы можете использовать ConvertTimeFromUt c, как вы упомянули. Пример:

$DateTime = Get-Date "2020-01-23 10:06:07"
$TimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
[TimeZoneInfo]::ConvertTimeFromUtc($DateTime, $TimeZone)

Или вы можете конвертировать из любого часового пояса. Получить часовые пояса:

[TimeZoneInfo]::GetSystemTimeZones() | select Id | sort Id

Конвертировать из одного часового пояса в другой:

$DateTime = Get-Date "2020-01-23 10:06:07"
$SourceTimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Eastern Standard Time")
$DestinationTimeZone = [TimeZoneInfo]::FindSystemTimeZoneById("Azores Standard Time")
[TimeZoneInfo]::ConvertTime($DateTime, $SourceTimeZone, $DestinationTimeZone)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...