บน windows: วิธีรับวันที่แก้ไขล่าสุด (เวลา UTC) ของไฟล์ที่มี wmic


1

ฉันเขียนแบตช์ต่อไปนี้เพื่อรับวันที่แก้ไขล่าสุด ปัญหาคือมันให้ในเวลานาฬิกาและไม่ได้อยู่ในเวลา UTC ฉันรู้ว่าฉันมีความล่าช้าในไม่กี่นาที แต่มันก็ไม่ง่ายเลยที่จะเปลี่ยนตัวเลขด้วยแบตช์ไฟล์ มีธงให้ wmic เพื่อรับเวลา UTC หรือไม่ นี่คือไฟล์แบตช์

@echo off 
setlocal enableextensions disabledelayedexpansion
set file=%1
set WORKINGdir=%~dp0
rem wmic wants double backslash
set PATHfile=%WORKINGdir%%file%
set PATHfile=%PATHfile:\=\\%
for /f %%a in (
    'wmic  DataFile where "Name='%PATHfile%'" get lastmodified   ^| find "+" '
) do set "val=%%a"
echo %val%
rem get first 14 digits (good until year 9999)
echo %val:~0,14%
endlocal

สิ่งนี้ให้ผลลัพธ์นี้กับฉัน:

20161026144823.620815+120
20161026144823

หากเขตเวลาของเครื่องเป็นแบบเดียวกันเสมอ คุณสามารถปรับได้ด้วยตนเองโดยเพิ่มออฟเซ็ตปัจจุบันเป็น UTC WMIC เป็นตัวเลือกที่ผิดในการทำสิ่งนี้ คุณจะพบว่ามันยากมากหากไม่สามารถทำได้ด้วย WMIC
Ramhound

ฉันมักจะเดินทางจากยุโรปและสหรัฐอเมริกาและกลับมา
Millemila

คุณสามารถตั้งค่าเขตเวลาบนเครื่องเป็น UTC จากนั้นคุณไม่ต้องทำอะไรเป็นพิเศษ หากไม่เป็นที่ยอมรับ HKLM\System\CurrentControlSet\Control\TimeZoneInformation เพื่อกำหนดการตั้งค่าเขตเวลาปัจจุบันและทำการปรับตามคำสั่งแบบมีเงื่อนไข
Ramhound

คุณควรปรับปรุงสคริปต์ของคุณให้ดี มนุษย์อ่านได้ แม้
Ramhound

ขออภัยมีสายพิเศษฉันคิดว่ามันดีตอนนี้
Millemila

คำตอบ:


1

อันที่จริงการคำนวณเวลาประทับเป็นความเจ็บปวด การปรับชั่วโมงเป็น UTC อาจส่งผลให้มีวันที่แตกต่างกันซึ่งหมายความว่าคุณต้องกังวลเกี่ยวกับจำนวนวันในเดือนและคุณอาจต้องกังวลเกี่ยวกับปีอธิกสุรทิน

WMIC ไม่มีบทบัญญัติในตัวเพื่อจัดรูปแบบการประทับเวลาเป็น UTC และแบทช์ไม่สนับสนุนการจัดการเลขคณิตวันที่ / เวลาอย่างแน่นอน

ฉันได้เขียน โปรแกรมอรรถประโยชน์ที่เรียกว่า JREN.BAT ที่สามารถแก้ปัญหาของคุณได้อย่างง่ายดาย มันถูกเขียนเพื่อให้สามารถเปลี่ยนชื่อไฟล์ / โฟลเดอร์โดยใช้นิพจน์ทั่วไป แต่มันมีฟังก์ชั่นพิเศษที่สามารถแก้ปัญหานี้ได้

JREN.BAT เป็นสคริปต์บริสุทธิ์ (ชุดผสม / JScript) ที่ทำงานบนเครื่อง Windows ทุกเครื่องตั้งแต่ XP เป็นต้นไป - ไม่ต้องใช้ไฟล์ exe ของ บริษัท อื่น เอกสารฉบับเต็มสามารถทำได้โดยการดำเนินการ jren /? จากพรอมต์คำสั่ง (หรือ jren /?? สำหรับความช่วยเหลือแบบเพจ)

ต่อไปนี้จะให้ฟังก์ชันการทำงานเดียวกับสคริปต์ของคุณยกเว้นว่าจะแสดงการประทับเวลาอย่าง UTC อย่างถูกต้อง

@echo off
for /f "delims=" %%A in (
  'jren "^.*" "ts({dt:'modified',tz:0})" /j /list /p "%~dp0" /fm %1'
) do set "ts=%%A"
echo %ts%

ผลลัพธ์จะอยู่ในรูปแบบ ISO 8601 โดยไม่มีเครื่องหมายวรรคตอนซึ่งจะเรียงลำดับตามลำดับเหตุการณ์ได้อย่างถูกต้องโดยใช้ความหมายของสตริง สิ่งที่ต้องการ 20161006T155621.746+0000.

คุณสามารถเพิ่มตัวเลือก fmt: เข้ากับการโทร ts () เพื่อจัดรูปแบบการประทับเวลาในแบบที่คุณเห็นว่าเหมาะสม ใช้ jren /?ts() เพื่อรับความช่วยเหลืออย่างสมบูรณ์เกี่ยวกับตัวเลือกทั้งหมดที่มีสำหรับการทำงานกับการประทับเวลา

มันง่ายมากที่จะใช้ JREN เพื่อจัดทำรายการไดเรกทอรีแบบเต็มด้วยเวลา UTC

รายการต่อไปนี้แสดงเวลาแก้ไขล่าสุดขนาดไฟล์และชื่อไฟล์สำหรับไฟล์. txt ทั้งหมดที่ขึ้นต้นด้วย t ในไดเรกทอรีปัจจุบัน

D:\test>jren "^.*" "ts({dt:'modified',tz:0,fmt:'{iso-dt}  {iso-tm}'})+size('              ')+'  '+$0" /j /list /fm t*.txt
2015-06-22  19:11:22.134            74  temp1.txt
2015-06-22  19:11:22.259             0  temp2.txt
2015-06-22  19:11:22.384             0  temp3.txt
2016-09-07  15:20:08.146         10376  tempfile.txt
2016-10-06  15:56:21.746            14  test.txt
2015-06-22  19:11:23.600           342  text2.txt
2015-06-22  19:11:23.741           288  textfile1.txt
2015-06-22  19:11:23.866           144  textfile2.txt
2015-10-19  19:12:16.441           707  TL.txt
2016-01-13  17:35:17.505          1030  tl64.txt
2016-01-13  17:36:48.501           974  tl64_2.txt
2016-01-13  17:45:16.383           943  tl64_3.txt
2016-01-13  17:37:21.308           707  tl_1.txt
2016-01-13  17:37:30.356           707  tl_2.txt
2016-01-13  17:45:50.469           707  tl_3.txt
2015-06-22  19:11:24.006            42  tmp.txt
2015-06-22  19:11:24.427        541553  toc-z.txt
2015-08-31  20:59:25.202      17442083  tree.txt
2015-06-22  19:11:24.583           304  tsc_call_layout.txt

JREN ใช้ WMI เพื่อรับการประทับเวลาที่แก้ไขล่าสุดซึ่งค่อนข้างช้า คุณอาจใช้งานได้ทั้งนี้ขึ้นอยู่กับการตั้งค่าภาษาของคุณ fsomodified, แทน modifiedเพื่อรับการประทับเวลาโดยใช้ FileSystemObject สิ่งนี้เร็วกว่ามาก แต่ก็ไม่ได้ให้มิลลิวินาทีและใช้ได้เฉพาะในกรณีที่รูปแบบสตริงการประทับเวลาภาษาของคุณในรูปแบบที่สามารถตีความได้โดยวัตถุวันที่ JScript

D:\test>jren "^.*" "ts({dt:'fsomodified',tz:0,fmt:'{iso-dt}  {hh}:{nn}:{ss}'})+size('              ')+'  '+$0" /j /list /fm t*.txt
2015-06-22  19:11:22            74  temp1.txt
2015-06-22  19:11:22             0  temp2.txt
2015-06-22  19:11:22             0  temp3.txt
2016-09-07  15:20:08         10376  tempfile.txt
2016-10-06  15:56:21            14  test.txt
2015-06-22  19:11:23           342  text2.txt
2015-06-22  19:11:23           288  textfile1.txt
2015-06-22  19:11:23           144  textfile2.txt
2015-10-19  19:12:16           707  TL.txt
2016-01-13  18:35:17          1030  tl64.txt
2016-01-13  18:36:48           974  tl64_2.txt
2016-01-13  18:45:16           943  tl64_3.txt
2016-01-13  18:37:21           707  tl_1.txt
2016-01-13  18:37:30           707  tl_2.txt
2016-01-13  18:45:50           707  tl_3.txt
2015-06-22  19:11:24            42  tmp.txt
2015-06-22  19:11:24        541553  toc-z.txt
2015-08-31  20:59:25      17442083  tree.txt
2015-06-22  19:11:24           304  tsc_call_layout.txt

1

เป็นไปได้ด้วยแบทช์บริสุทธิ์แม้ว่ามันอาจจะช้าสำหรับไฟล์จำนวนมาก ชุดคำสั่งได้มาจากฟังก์ชั่นที่ออก ไลบรารีฟังก์ชัน Richie Lawrence Batch

:: Demo_DateAddSecs.cmd ::::::::::::::::::::::::::::::::::::::::::::
@Echo off&cls
Call :GetISODT DateTime
Echo %DateTime% is now 
Call :DateAddSecs %DateTime% 7200 NewDT
Echo %NewDT% +7200 secs
Echo y___m_d_h_n_s_
Echo 20160101013000 Subtract 2h from new year 1:30
Call :DateAddSecs 20160101013000 -7200 NewDT
Echo %NewDT% -7200 secs
Echo y___m_d_h_n_s_
Echo 20160301013000 March first -12h this is a leap year
Call :DateAddSecs 20160301013000 -43200 NewDT
Echo %NewDT% -43200 secs
Echo y___m_d_h_n_s_
Pause
Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:GetISODT Var
SetLocal
for /f "tokens=1-3 delims=.+-" %%A in (
  'wmic os get LocalDateTime^|findstr ^^[0-9]'
    ) do Set _IsoDT=%%A
EndLocal&Set "%1=%_IsoDT%"&Goto :Eof
:: GetISODT.cmd :::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:DateAddSecs %yyyymmddhhnnss% %secs2Add% DTreturnvar
:: Original functions DateToSecs and SecsToDate
:: By:   Ritchie Lawrence, updated 2002-08-13. Version 1.1
:: Func: Converts DateTime to number of seconds elapsed since 
::       1st January 1970 00:00:00 adds the supplied seconds
::       and converts back to a valid Datetime
::  For a given calendar date and time of day. Tested with Win10pro.
:: Args:
::  %1 by val Datetime in the form yyyymmddhhnnss
::  %2 by val seconds integer to add/subtract 1 hour = 60*60 = 3600
::  %3 by ref the var name to receive the resulting Datetime 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SetLocal EnableExtensions& Set DT=%1
Set yy=%DT:~0,4%&set mm=%DT:~4,2%&set dd=%DT:~6,2%
set hh=%DT:~8,2%&set nn=%DT:~10,2%&set ss=%DT:~12,2%
Set /a dd=100%dd%%%100,mm=100%mm%%%100
Set /a z=14-mm,z/=12,y=yy+4800-z,m=mm+12*z-3,j=153*m+2
Set /a j=j/5+dd+y*365+y/4-y/100+y/400-2472633
if 1%hh% LSS 20 set hh=0%hh%
Set /a hh=100%hh%%%100,nn=100%nn%%%100,ss=100%ss%%%100
Set /a j=j*86400+hh*3600+nn*60+ss
Endlocal&set /A secs=%j%+%2
:: SecsToDate %secs% yy mm dd hh nn ss
SetLocal EnableExtensions
Set /a i=%secs%,ss=i%%60,i/=60,nn=i%%60,i/=60,hh=i%%24,dd=i/24,i/=24
Set /a a=i+2472632,b=4*a+3,b/=146097,c=-b*146097,c/=4,c+=a
Set /a d=4*c+3,d/=1461,e=-1461*d,e/=4,e+=c,m=5*e+2,m/=153,dd=153*m+2
Set /a dd/=5,dd=-dd+e+1,mm=-m/10,mm*=12,mm+=m+3,yy=b*100+d-4800+m/10
(if %mm% LSS 10 set mm=0%mm%)&(if %dd% LSS 10 set dd=0%dd%)
(if %hh% LSS 10 set hh=0%hh%)&(if %nn% LSS 10 set nn=0%nn%)
if %ss% LSS 10 set ss=0%ss%
Endlocal&set "%3=%yy%%mm%%dd%%hh%%nn%%ss%"&Goto :Eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

ให้ผลลัพธ์นี้

> DemoDateAddSecs.cmd
20161027053749 is now
20161027073749 +7200 secs
y___m_d_h_n_s_
20160101013000 Subtract 2h from new year 1:30
20151231233000 -7200 secs
y___m_d_h_n_s_
20160301013000 March first -12h this is a leap year
20160229133000 -43200 secs
y___m_d_h_n_s_

HTH

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.