npocmaka
As the w32tm is here since Windows NT I have wondered if it could be used for something ...useful.
I thought the most promising options would be w32tm /ntte and w32tm /ntpte - and how possibly they can be used for time calculations.
/ntte uses as measurement 1/10^(-7) seconds and start counting from 1601.Which means this works with reeealy big numbers (can overflow even long).
here's how it can display the current time:
Code: Select all
rem (" w32tm ")/*
@echo off
for /f "eol=B " %%B in ('WMIC Path Win32_TimeZone Get bias /Format:table') do (
set /a "offset=%%B/60"
goto :endfor
)
:endfor
for /f %%S in ('call Cscript //nologo //E:jscript %0 %offset%') do (
set ntte_time=%%S
)
w32tm /ntte %ntte_time%0000
goto :eof
*/
WScript.Echo(((new Date()).getTime()-(new Date(1601,0,1,WScript.Arguments.Item(0))).getTime()));
function rem (){}
w32tm /ntpte - I still have no clear idea how this works:
Code: Select all
C:\>w32tm /ntpte 1
0x014FCFD27DE04000 - 109401 04:20:16.0000000 - 14.7.1900 г. 06:20 ч.
C:\>w32tm /ntpte 2
0x01506868FDE04000 - 109595 08:40:32.0000000 - 24.1.1901 г. 10:40 ч.
C:\>w32tm /ntpte 4294967296
0x014F373BFDE0D897 - 109207 00:00:00.0039063 - 1.1.1900 г. 02:00 ч.
C:\>w32tm /ntpte 4294967295
0x01E7CDBBFD47A980 - 158917 06:28:15.0000000 - 7.2.2036 г. 08:28 ч.
/stripchart option can be used to emulate sleep command in a similar way as ping:
Code: Select all
w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:N >nul 2>&1
For now I can only say I'm disappointed.
Last edited by npocmaka (20 Jan 2013 20:35)
----------------------------
#2 14 Jan 2013 09:51
npocmaka
a little bit more about /ntpte - each slice is calculate somehow on 256 power and modulus base - and is approximately 1 second (and can work with bigger numbers than 4294967296 - but after that the dates start to repeat the dates):
Code: Select all
C:\Program Files\Microsoft SDKs\Windows\v7.1>w32tm /ntpte 0
0x014F373BFDE04000 - 109207 00:00:00.0000000 - 1/1/1900 2:00:00 AM
C:\Program Files\Microsoft SDKs\Windows\v7.1>w32tm /ntpte 256
0x014F37D494604000 - 109207 18:12:16.0000000 - 1/1/1900 8:12:16 PM
C:\Program Files\Microsoft SDKs\Windows\v7.1>w32tm /ntpte 65536
0x014F373C9676C000 - 109207 00:04:16.0000000 - 1/1/1900 2:04:16 AM
C:\Program Files\Microsoft SDKs\Windows\v7.1>w32tm /ntpte 16777216
0x014F373BFE78D680 - 109207 00:00:01.0000000 - 1/1/1900 2:00:01 AM
C:\Program Files\Microsoft SDKs\Windows\v7.1>w32tm /ntpte 4294967296
0x014F373BFDE0D897 - 109207 00:00:00.0039063 - 1/1/1900 2:00:00 AM
Code: Select all
//NTP epoch
var NTPTE_start=new Date(1900,0,1,2);
var NTPTE_start_ms=NTPepoch.getTime();
var current_NTP=currentMS-NTP_MS;
var NTPTE_end=new Date(2036,6,2,6,28,16)
var NTPTE_end_ms=NTPTE_end.getTime();
var NTPTE_whole=NTPEpochEnd - NTPepoch;
WScript.Echo("whole NTP epoch in milliseconds divided by 4294967296: " + wholeNTEpoch/4294967296);
----------------------------
#3 19 Jan 2013 23:23
npocmaka
I've received some answers on stackoverflow . Please do not hesitate and upvote the MBu's answer .
Here's in brief :
1.) w32tm /ntpte and /ntte works easy with hex numbers if they start with 0x
2.) w32tm /ntpte works with the seconds passed since 1900 but uses byte reversed numbers (the number in hex format with reversed coupled numbers).This means unsigned integer - which is still not convenient for work because cannot be hold in cmd numbers.
3.) Both commands returns the date in ANSI format - the days passed since 1601 y.
4.) The hex value printed by w32tm /ntpte can be directly passed as a parameter to w32tm /ntte
5.) The timetapms returned by /stripchart (with /packetinfo switch which is available only in Vista and above) switch can be passed to /ntpte after byte reversing
here's an example:
Code: Select all
@echo off
rem -- printing local time with w32tm
setlocal
for /f "tokens=3,4 delims=^( " %%T in ('w32tm /stripchart /computer:localhost /samples:1 /packetinfo /period:1 ^| find "Transmit Timestamp:"') do (
set HEXx64_Time_Stamp=%%T
set ANSI_Current_Date=%%U
)
call :hexByteRevert %HEXx64_Time_Stamp% test_x46
w32tm /ntpte %test_x46%
goto :eof
:hexByteRevert [%1 - hex value , %2 - variable to store result in]
setlocal ENABLEDELAYEDEXPANSION
set hex=%~1
set res=%~2
set "temp="
for /L %%L in (2,2,16) do (
set temp=!hex:~%%L,2!!temp!
)
endlocal & call set %res%=0x%temp%
goto :eof
Last edited by npocmaka (25 Jan 2013 10:38)
----------------------------
#4 09 May 2013 09:35
npocmaka
#5 06 Sep 2013 09:57
npocmaka
Getting day of the week with w32tm.
Unfortunately will not work on XP because rely on new capabilities of /stripchart switch.
The idea is that with w32tm /stripchart /computer:localhost /samples:1 /period:1 /dataonly /packetinfo I receive the ansi date - days passed since 1.1.1601 (as far as I remember it was Monday on that day) and i can get modulus of 7 of them
Code: Select all
@echo off
setlocal
rem :: getting ansi date ( days passed from 1st jan 1601 ) , timer server hour and current hour
FOR /F "skip=16 tokens=4,5 delims=:( " %%D in ('w32tm /stripchart /computer:localhost /samples:1 /period:1 /dataonly /packetinfo') do (
set "ANSI_DATE=%%D"
set "TIMESERVER_HOURS=%%E"
goto :end_for )
:end_for
set "LOCAL_HOURS=%TIME:~0,2%"
if "%TIMESERVER_HOURS:~0,1%0" EQU "00" set TIMESERVER_HOURS=%TIMESERVER_HOURS:~1,1%
if "%LOCAL_HOURS:~0,1%0" EQU "00" set LOCAL_HOURS=%LOCAL_HOURS:~1,1%
set /a OFFSET=TIMESERVER_HOURS-LOCAL_HOURS
rem :: day of the week will be the modulus of 7 of local ansi date +1
rem :: we need need +1 because Monday will be calculated as 0
rem :: 1st jan 1601 was Monday
rem :: if abs(offset)>12 we are in different days with the time server
IF %OFFSET%0 GTR 120 set /a DOW=(ANSI_DATE+1)%%7+1
IF %OFFSET%0 LSS -120 set /a DOW=(ANSI_DATE-1)%%7+1
IF %OFFSET%0 LEQ 120 IF %OFFSET%0 GEQ -120 set /a DOW=ANSI_DATE%%7+1
echo Day of the week: %DOW%
endlocal
On XP i couldn't find a way to get the ansi date with pure batch script.
Last edited by npocmaka (06 Sep 2013 15:21)