#python #wmi #datetime-format
Вопрос:
У меня есть CIM_DATETIME
время, приобретенное у wmic os get lastbootuptime
:
20190309221835.234400-480
CIM_DATETIME
форматируется следующим образом:
yyyymmddHHMMSS.mmmmmmsUUU
Как я могу преобразовать это во что-то более удобное для человека в Bash или Python?
Формат, который был бы наиболее желательным, — это:
Sunday, March 10th, 2019 @ 16:01:30 UTC
Это или если бы я мог преобразовать его во что-то нормальное, например, в метку времени Unix. Если вам интересно, что мне нужно для этого на языках, отличных от Windows (в пакете уже есть много решений), потому что я занимаюсь компьютерной экспертизой, но в качестве основной операционной системы я использую Linux, поэтому я хочу иметь возможность легко интерпретировать даты, которые я получаю от WMI, во что-то, что я могу легко интерпретировать. Это настолько нишевое занятие, что я даже не могу найти в Интернете инструмент для этого. :/
Спасибо.
Комментарии:
1. Пожалуйста, добавьте желаемый результат для этого примера ввода в свой вопрос.
2. @Сайрус сделал дело!
3. Было бы неплохо, если бы желаемый результат соответствовал заданному входу.
4. @Armali Хорошая мысль! Часовые пояса и форматы преобразования очень быстро сбивают с толку. Должно же быть что-то, по чему можно было бы проверять ошибки.
Ответ №1:
Вы можете получить метку времени без часового пояса с помощью этого:
from datetime import datetime
datetime.strptime(CIM_DATETIME.split('-')[0], '%Y%m%d%H%M%S.%f')
[Обратите внимание, что для разделения строки предполагается отрицательное смещение часового пояса.]
Загвоздка с часовым поясом в том, что он выражается в минутах, поэтому вам нужно разделить на 60. Но нужно ли вам читать часовой пояс? Если это всегда будет одно и то же, то вы сможете внести это отдельно.
Комментарии:
1. Спасибо, но для компьютерной экспертизы часовой пояс действительно предпочтительнее.
Ответ №2:
но для компьютерной криминалистики часовой пояс действительно предпочтительнее.
ответ комбинаториста уже делает половину работы. Его можно легко расширить, чтобы учесть смещение часового пояса:
import datetime
CIM_DATETIME ='20190309221835.234400-480'
dt = datetime.datetime.strptime(CIM_DATETIME[:-4], '%Y%m%d%H%M%S.%f')
# dt is now datetime.datetime(2019, 3, 9, 22, 18, 35, 234400)
dt -= datetime.timedelta(minutes=int(CIM_DATETIME[-4:]))
# dt is now datetime.datetime(2019, 3, 10, 6, 18, 35, 234400)
dt.strftime("%A, %B %d., %Y @ %X UTC")
Ответ №3:
Вот решение в Bash, которое я придумал. Вывод кажется правильным и совпадает со временем, когда пару дней назад я загрузил окно Windows-незадолго до полуночи. Я также удалил»@», потому что это едва ли сделало время приятнее для просмотра, и поэтому мне пришлось удалить его в следующих сценариях, используя CIM_DATETIME
из date
-за того, что команда не смогла это разобрать.
CIM_DATETIME="20190309221835.234400-480"
date="${CIM_DATETIME:0:8}"
date="$(date -d "$date" ' %A, %B%e, %Y')"
time="${CIM_DATETIME:8:6}"
time="$(echo "$time" | sed 's/../amp;:/g;s/:$//')" # Adds : between hours, minutes and seconds of time so it can be parsed correctly
timezone="${CIM_DATETIME:21}"
time="$time $timezone"
time="$(date -d "$time" ' %r %Z')"
echo "$date $time"
Пример Вывода: Saturday, March 9, 2019 11:38:35 PM EDT
Спасибо вам за все решения.
Ответ №4:
Вот моя улучшенная версия ответа Армали, которая имеет дело с отрицательными / нулевыми / положительными часовыми поясами и позволяет использовать UTC или локальную нотацию:
[ПРАВИТЬ] Отказ от ответственности: Код в этом посте устарел. Я опубликовал этот код в виде пакета python. Установите с pip install windows_tools.installed_software
Использование:
from windows_tools.wmi_queries import cim_timestamp_to_datetime_utc
print(cim_timestamp_to_datetime_utc('20201103225935.123456 0'))
[/ПРАВИТЬ]
from datetime import datetime, timedelta
import re
def convert_cim_timestamp(cim_timestamp: str, utc_result: bool = True) -> str:
"""
Convert WMI timestamp to python datetime object
"""
cim_time, cim_tz = re.split('[ -]', cim_timestamp)
dt = datetime.strptime(cim_time, '%Y%m%d%H%M%S.%f')
if not utc_result:
dt -= timedelta(minutes=int(cim_tz))
return dt.strftime('%A, %B %d., %Y @ %X')
else:
utc_sign = ' ' if ' ' in cim_timestamp else '-'
utc_offset = int(int(cim_tz)/60)
return dt.strftime("%A, %B %d., %Y @ %X UTC{}{}".format(utc_sign, utc_offset))
# Example
cim_tz = '20201103225935.123456-240'
print(convert_cim_timestamp(cim_tz))
cim_tz = '20201103225935.123456 120'
print(convert_cim_timestamp(cim_tz))
Комментарии:
1. мне кажется, что было бы проще установить timedelta в качестве часового пояса (заменить tzinfo), а затем (если желаемый вывод-строка) использовать
%z
в директиве форматирования. кромеutc_result
того, значение kwarg вводит в заблуждение; затем на выходе указывается смещение UTC, оно не преобразуется в UTC.2. Спасибо, как было предложено в правке, это старый код, и он был изменен в репозитории git 😉