Jump to content
Tuts 4 You
LCF-AT

How to change time date?

Recommended Posts

LCF-AT

Hi guys,

could anybody help to show me how to change the windows time to a other data and setting it back to original time?Of course I can do it manually but I would like to do it via batch file  or some code maybe.On internet I found something like that...

Date 01.01.2018

...what works so far but how to set it back to original time without to do it manually?Is that also doable?So at the end I should have 2 batch files.One with the static date and one with the real actually date...anyhow.Any ideas maybe?

greetz

Share this post


Link to post
Share on other sites
evlncrn8

well, setting it back to the 'right' time use something like atomic clock sync.. the time api's in windows though (at least from 7 onwards) require admin privileges to set them..

windows time api's -> https://docs.microsoft.com/en-us/windows/desktop/sysinfo/time-functions

messing with times could really mess up things on the system though esp on file sorting / searches by date and so on...

might be easier to just hook whatever program you're intending to play with and play with its api's locally, sandbox style with hooks

as opposed to changing things system wide

Edited by evlncrn8 (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites
Progman

If you are only doing a short amount of processing for less than a second or so, perhaps can just capture the output of "DATE /T" ("TIME /T") using the "FOR" construct to variable %A, and then just feed in that again with "DATE %A" ("TIME %A").  Then you do not require internet syncing.  If it is a long operation, you can measure the net time using a batch script taking advantage of WMI ("wmic OS Get localdatetime").  So its all pretty much very easily and simply batch scriptable.  Once in a while a resync might be necessary if using such an imprecise to the nearest seconds command like TIME.

 

@echo off
for /f "delims=" %%a in ('wmic OS Get localdatetime ^| find "."') do set up=%%a
REM DO OPERATION HERE
for /f "delims=" %%a in ('wmic OS Get localdatetime  ^| find "."') do set dt=%%a

set beg=%up:~0,4%-%up:~4,2%-%up:~6,2%T%up:~8,2%-%up:~10,2%-%up:~12,2%-%up:~15,3%
set end=%dt:~0,4%-%dt:~4,2%-%dt:~6,2%T%dt:~8,2%-%dt:~10,2%-%dt:~12,2%-%dt:~15,3%


call :TimeDifference nettime %end% %beg% 

echo %beg%
echo %end%
echo Net time is: %nettime%


pause
goto :eof

:TimeDifference Return_Variable Start_Date_Time Stop_Date_Time
:: Version -0 2009-12-25 Frank P. Westlake
:: Calculate the difference in time between parameter 2 and parameter 3
:: and return the values in the variable named by parameter 1.
::
:: Parameters 2 and 3 are ISO8601 DATE/TIMEs of the format
::
::     YYYY-MM-DDThh-mm-ss
::
:: where '-' may be any of '/:-., '.
::
:: RETURN:
:: The variable named by %1 will be set with a string containing each of
:: the following values seperated by spaces:
::
::   DAYS HOURS MINUTES SECONDS MILLISECONDS
::
:: EXAMPLE: Call :TimeDifference diff "2009-12-01T 1:00:00.00" "2009-11-30T13:00:00.01"
::          Sets variable "DIFF=0 12 0 0 10"
SetLocal EnableExtensions EnableDelayedExpansion
For /F "tokens=1-14 delims=T/:-., " %%a in ("%~2 %~3") Do (
  Set "h2=0%%d" & Set "h3=0%%k" & Set "n2=%%g00" & Set "n3=%%n00"
  Set /A "y2=%%a, m2=1%%b-100, d2=1%%c-100, h2=1!h2:~-2!-100, i2=1%%e-100, s2=1%%f-100, n2=1!n2:~0,3!-1000"
  Set /A "y3=%%h, m3=1%%i-100, d3=1%%j-100, h3=1!h3:~-2!-100, i3=1%%l-100, s3=1%%m-100, n3=1!n3:~0,3!-1000"
)
Set /A "t2=((h2*60+i2)*60+s2)*1000+n2, t3=((h3*60+i3)*60+s3)*1000+n3"
Set /A "a=(14-m2)/12, b=y2-a, j2=(153*(12*a+m2-3)+2)/5+d2+365*b+b/4-b/100+b/400"
Set /A "a=(14-m3)/12, b=y3-a, j3=(153*(12*a+m3-3)+2)/5+d3+365*b+b/4-b/100+b/400"
Set /A "d=j3-j2, t=t3-t2"
If %d% LEQ 0 (If %d% LSS 0 (Set /A "d=j2-j3, t=t2-t3") Else If %t% LSS 0 (Set /A "t=t2-t3"))
If %t% LSS 0 (Set /A "t+=(1000*60*60*24), d-=1")
Set /A "n=t %% 1000, t/=1000, s=t %% 60, t/=60, m=t %% 60, t/=60"
EndLocal & Set "%~1=%d% %t% %m% %s% %n%"
Goto :EOF
:: END SCRIPT ::::::::::::::::::::::::::::::::::::::::

 

So the best solution which requires a privileged administrator prompt is to use this code:

    @echo off
    setlocal

    set dt=
    for /f "tokens=*" %%A in ('wmic OS Get localDateTime /value ^| findstr "."') do @set dt=%%A
    set dt=%dt:~14,-1%
    set "trail=%dt:~8%"
    set "saveddt=%dt:~0,8%"
    set targetstamp=20120813%trail%
    wmic OS Set localdatetime=%targetstamp%

    REM do some work...
    pause

    set dt=
    for /f "tokens=*" %%A in ('wmic OS Get localDateTime /value ^| findstr "."') do @set dt=%%A
    set dt=%dt:~14,-1%
    set "newtrail=%dt:~8%"
    wmic OS Set localdatetime=%saveddt%%newtrail%

 

 

Edited by Progman (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites
LCF-AT

Hi guys,

thanks for your answers so far.

Example: The Windows time is set to actually right date & time for my local area like you have for yours etc.Now lets say I do change the date & time to any other in past or future.Now the question is whether its possible to get the real date & time for my local area "anyhow" also without any internet access etc.So I thought it would be not possible or?

I tried your 2. script Progman but time / date isnt changed.I only get this message..

Eigenschaften von "\\****\ROOT\CIMV2:Win32_OperatingSystem=@" werden aktualisiert
Eigenschaft(en) wurde(n) aktualisiert.
Drücken Sie eine beliebige Taste . . .

...some update but thats all.

http://willjusticeprevil.blogspot.com/2015/07/batch-file-set-date-with-wmic-invalid.html

"running in privileged cmd reports having set new date. however, nothing changes on pc - wmic os set localdatetime doesn't change date. ymmv."

greetz

  • Thanks 1

Share this post


Link to post
Share on other sites
Techlord
5 hours ago, LCF-AT said:

Now lets say I do change the date & time to any other in past or future.Now the question is whether its possible to get the real date & time for my local area "anyhow" also without any internet access etc.So I thought it would be not possible or?

You want to do so when offline?

Then you'd need to store the offset difference by how many hours/mins/days you are setting the clock forward or backward and then you'd be able to "restore" it back to the original time with just a click.Wouldn't take too long for you to quickly create a small prog that would have 2 buttons. One to "store" and another to "restore".

When you change the present ("presumed accurate") time to set the clock say, an hour forward. Then a click of the store button woud store the "1 hour" difference by which you advanced the clock. Later when you want to restore the original accurate time, all you'd have to do it to click then "restore" button, which would then read from a file, the offset (1 hour in this case), to restore the system time back to the original correct one.

Alternative would be solutions like this dedicated Time Server or sync with another computer but that is not what you'd want, if I understood your problem right.

These are the 2 easy solutions since you wanted the solutions when your system is offline.

Greetz

 

  • Like 1

Share this post


Link to post
Share on other sites
LCF-AT

Hi,

yes,just wanted to know whether its anyhow possible to get the real time / date also in offline modus (also if not offline too in other case).

Ok,so it seems I really need to store the date / time anywhere before I change it.I will play around a little.Thanks again so far.

greetz

  • Like 1

Share this post


Link to post
Share on other sites
Progman

Just to add to this discussion since I needed for writing scripts that can fix time seeded random number generators for reproducible output, here is a Windows and Posix compatible way of dealing with this.  Note I do not provide a way to take a user friendly specified date/time combination and convert it to a high/low part or a time/microseconds pair but these also can be done programmatically (and is now implemented as shown using a format with command line arguments of year 1601-30827, month 1-12, day 1-31, hour 0-23, minute 0-59, second 0-59, milliseconds 0-999).  The problem is to write the code to be locale sensitive is some work and even the batch/bash scripts will almost certainly not handle all aspects of that.

//root/admin priviledge needed to set time
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#else
//can sudo chown root prestime and sudo chgrp root prestime or just run with sudo
//must disable automatic date & time: timedatectl set-ntp 0
//re-enable with timedatectl set-ntp 1
//#include <errno.h>
#include <sys/time.h>
#include <time.h>
#endif

/*Example usage on Windows and Linux:
>echo %date% %time%
Sat 11/03/2018 17:29:11.97

>prestime 0 0
30700434 1558713536

>echo %date% %time%
Mon 01/01/1601  1:00:01.54

>prestime 0 0 30700434 1558713536

>echo %date% %time%
Sat 11/03/2018 17:29:39.34


$ date
2018. nov. 3., Saturday, 17:30:52 GMT

$ sudo ./prestime 100000 0
[sudo] password for user:
1541262654 925289

$ date
1970. jan. 2., Friday, 04:46:42 GMT

$ sudo ./prestime 100000 0 1541262654 925289

$ date
2018. nov. 3., Saturday, 17:31:18 GMT
*/

int main(int argc, char* argv[])
{
#ifdef WIN32
	//parameters: desired time high part, desired time low part - sets the desired time and returns the old time
	//parameters: desired time high part, desired time low part, old time high part, old time low part - sets the old time plus the difference between the desired time and the current time
	SYSTEMTIME SysTm;
	FILETIME FlTm;
	GetSystemTime(&SysTm);
	SystemTimeToFileTime(&SysTm, &FlTm);
	if (argc == 8) {
		printf("%lu %lu\n", FlTm.dwHighDateTime, FlTm.dwLowDateTime);
		//normalized Gregorian calendar date-time conversion
		//year 1601-30827, month 1-12, day 1-31, hour 0-23, minute 0-59, second 0-59, milliseconds 0-999
		sscanf(argv[1], "%lu", &SysTm.wYear);
		sscanf(argv[2], "%lu", &SysTm.wMonth);
		sscanf(argv[3], "%lu", &SysTm.wDay);
		sscanf(argv[4], "%lu", &SysTm.wHour);
		sscanf(argv[5], "%lu", &SysTm.wMinute);
		sscanf(argv[6], "%lu", &SysTm.wSecond);
		sscanf(argv[7], "%lu", &SysTm.wMilliseconds);	
		SystemTimeToFileTime(&SysTm, &FlTm); //wDayOfWeek 0-6 is ignored...
		printf("%lu %lu\n", FlTm.dwHighDateTime, FlTm.dwLowDateTime);				
	} else if (argc == 5) {
		ULARGE_INTEGER ul, ulsub; //must copy and not cast due to problems with alignment faults in 64-bit windows per MSDN docs
		ul.HighPart = FlTm.dwHighDateTime;
		ul.LowPart = FlTm.dwLowDateTime;
		sscanf(argv[1], "%lu", &ulsub.HighPart);
		sscanf(argv[2], "%lu", &ulsub.LowPart);
		ulsub.QuadPart = ul.QuadPart - ulsub.QuadPart;
		sscanf(argv[3], "%lu", &ul.HighPart);
		sscanf(argv[4], "%lu", &ul.LowPart);
		ul.QuadPart = ul.QuadPart + ulsub.QuadPart;
		FlTm.dwHighDateTime = ul.HighPart;
		FlTm.dwLowDateTime = ul.LowPart;
	} else {
		printf("%lu %lu\n", FlTm.dwHighDateTime, FlTm.dwLowDateTime);
		sscanf(argv[1], "%lu", &FlTm.dwHighDateTime);
		sscanf(argv[2], "%lu", &FlTm.dwLowDateTime);
	}
	FileTimeToSystemTime(&FlTm, &SysTm);
	SetSystemTime(&SysTm);
#else
	//parameters: desired time seconds, desired time microseconds - sets the desired time and returns the old time
	//parameters: desired time seconds, desired time microseconds, old time seconds, old time microseconds - sets the old time plus the difference between the desired time and the current time
	struct timeval now;
	gettimeofday(&now, NULL);
	if (argc == 8) {
		printf("%lu %lu\n", now.tv_sec, now.tv_usec);
		struct tm Tm = {0}; //tm_isdst = 0
		sscanf(argv[1], "%d", &Tm.tm_year);
		sscanf(argv[2], "%d", &Tm.tm_mon);
		sscanf(argv[3], "%d", &Tm.tm_mday);
		sscanf(argv[4], "%d", &Tm.tm_hour);
		sscanf(argv[5], "%d", &Tm.tm_min);
		sscanf(argv[6], "%d", &Tm.tm_sec);
		now.tv_sec = mktime(&Tm); //tm_wday, tm_yday are ignored...
		sscanf(argv[7], "%lu", &now.tv_usec);	
		now.tv_usec *= 1000; //milliseconds to microseconds
	} else if (argc == 5) {
		struct timeval desired;
		sscanf(argv[1], "%lu", &desired.tv_sec);
		sscanf(argv[2], "%lu", &desired.tv_usec);
		timersub(&now, &desired, &desired);
		sscanf(argv[3], "%lu", &now.tv_sec);
		sscanf(argv[4], "%lu", &now.tv_usec);
		timeradd(&now, &desired, &now);
	} else {
		printf("%lu %lu\n", now.tv_sec, now.tv_usec);
		sscanf(argv[1], "%lu", &now.tv_sec);
		sscanf(argv[2], "%lu", &now.tv_usec);
	}
	return settimeofday(&now, NULL);
#endif
}

 

Example usage on Windows and then Linux:

>echo %date% %time%
Sat 11/03/2018 17:29:11.97

>prestime 0 0
30700434 1558713536

>echo %date% %time%
Mon 01/01/1601  1:00:01.54

>prestime 0 0 30700434 1558713536

>echo %date% %time%
Sat 11/03/2018 17:29:39.34


$ date
2018. nov. 3., Saturday, 17:30:52 GMT

$ sudo ./prestime 100000 0
[sudo] password for user:
1541262654 925289

$ date
1970. jan. 2., Friday, 04:46:42 GMT

$ sudo ./prestime 100000 0 1541262654 925289

$ date
2018. nov. 3., Saturday, 17:31:18 GMT

 

Edited by Progman (see edit history)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×