2

I am trying to create an arbitrary time using batch files. I am trying to subtract set values (such as 1 day, 1 month, and 2000 years) from my code to display the system time subtracted by the set values stated previously. For the hours and minutes, I am subtracting 10 hours and 10 minutes (shown in code as different values). I am also aware that date and time are variables related to my system. ~ Please ignore

Important - My problem now is with this part:

if %minb% EQU 60 set /a minb=%minb%-60 & set /a hourb=%hourb%+1
if %hourb% EQU 24 set /a hourb=%hourb%-24 & set /a dayb=%dayb%+1
if %dayb% EQU 30 set /a dayb=%dayb%-30 & set /a monthb=%monthb%+1
if %monthb% EQU 12 set /a monthb=%monthb%-12 & set /a yearb=%yearb%+1

I can't seem to be able to make the minutes reset to 0 and have the hours add 1 when the minute value hits 60, and same with the hour-day, day-month, month-year relationships, other than that, the problems with my code are mostly fixed. When I run the code and wait for the minutes (or add to the time difference) to reach 60, they just pass 60 and don't reset nor add to the hoursb value.

.

My date and time formats are:

  • Short date: M/d/yyyy
  • Long date: dddd, MMMM d, yyyy
  • Short time: h:mm
  • Long time: h:mm:ss

I am using Windows 10.

Please note that the values in the set /a do not match my description, but of course they can be changed around. They are set to the shown numbers for test purposes only.

EDIT:

Code:

@echo off
:start
set day=%date:~-7,2%
set month=%date:~-10,2%
set year=%date:~-4,4%
set hour=%time:~0,2%
set min=%time:~3,2%

set /a "hourb=%hour%-10"
set /a "minb=%min%+30"
set /a "dayb=%day%-1"
set /a "monthb=%month%-1"
set /a "yearb=%year%-2000"

if %minb% lss 10 set minb=0%minb%
if %hourb% lss 10 set hourb=0%hourb%
if %dayb% lss 10 set dayb=0%dayb%
if %monthb% lss 10 set monthb=0%monthb%

if %minb% EQU 60 set /a minb=%minb%-60 & set /a hourb=%hourb%+1
if %hourb% EQU 24 set /a hourb=%hourb%-24 & set /a dayb=%dayb%+1
if %dayb% EQU 30 set /a dayb=%dayb%-30 & set /a monthb=%monthb%+1
if %monthb% EQU 12 set /a monthb=%monthb%-12 & set /a yearb=%yearb%+1

cls
:: ———————————————————————–
@mode con cols=20 lines=6
title Arbitrary Clock

:time    
echo.     
echo.    %hourb%:%minb%
echo.    
echo.    %dayb%-%monthb%-%yearb%  
echo.      
ping -n 2 0.0.0.0 >nul
cls
goto :start

Alright, so as you can see in the new edit to the code, I set the values to the stated at the beginning of this question. Subtracting 10 from the hours, subtracting 1 from the days and months, and subtracting 2000 from the years. I added 30 to the minutes to show the problem right now.

So my system time is 4:40, 1/5/2019. Alright?

The displayed time on the clock is 06:70, 04-00-19.

The desired outcome is 07:10, 04-12-18.

This was edited heavily. Thanks in advance.

Aacini
  • 65,180
  • 12
  • 72
  • 108
Rare Pepe
  • 23
  • 4
  • Please note that: you should not include `This is my second question......`. We can learn it our own. Also, never include tag-names in your question titles. Note that `rem` is the 'official' comment for batch file; `::` may cause unexpected behaviour sometimes. Also, you should note that `date` and `time` environment variables depend on user regional settings and are changeable. We could not verify your example that way. Please take a look at [mcve]. What is the date-time format you are setting in the first lines of your program? [edit] your question to include/exclude what I have mentioned. – double-beep Jan 05 '19 at 10:41
  • If you subtract the date `01/01/2000` from the time, e.g. `05:32`, the resulting time will still be `05:32`! – Compo Jan 05 '19 at 10:50
  • What do you need `delayed expansion`? – double-beep Jan 05 '19 at 10:56
  • 2
    I suggest you to review these answers: [Calculate time difference](https://stackoverflow.com/questions/9922498/calculate-time-difference-in-windows-batch-file/9935540#9935540), [Arithmetic operations with times](https://stackoverflow.com/questions/42603119/arithmetic-operations-with-hhmmss-times-in-batch-file/42603985#42603985) and [Calculate a duration between two dates](https://stackoverflow.com/questions/51082845/calculate-a-duration-between-two-dates-dd-mm-yyyy-hhmmss-in-batch-file/51090719#51090719)... – Aacini Jan 05 '19 at 11:56
  • double-beep: I have edited most of the post to fix the mistakes pointed out by you. I am aware that date and time are environment variables and I removed delayed expansion. I had delayed expansion there because I first tested it with seconds but after that I removed it because I found it to be harder. I forgot to remove the delayed expansion command but it is now edited out. Compo: I forgot to point out that I also want to subtract a number from the hours and minutes, but have done so in the edit. – Rare Pepe Jan 05 '19 at 11:58
  • Aacini, I have looked at your suggested answers and found that they don't directly assist with my desired outcome. They are rather more of stopwatches and date difference calculators than permanent date differences. I do not want to implement them in my code because they don't really help but I am trying to implement them in some way or another. Anyways, thanks for the comment. – Rare Pepe Jan 05 '19 at 12:42
  • Your question makes little sense, you cannot subtract a date from a date to get another date. You can only effectively convert each component to a common denominator, _in this case minutes_, then subtract the total number of minutes from the current date and time to determine a resultant date. Please try better to explain your task, because the only way I can see this work is to subtract `01` day, subtract `01` month, subtract `2000` years, subtract `10` hours and subtract `10` minutes from the current date and time. I would also suggest simplifying the whole thing and using `PowerShell`. – Compo Jan 05 '19 at 13:30
  • Compo, sorry for the trouble. Now, the problem isn't with the subtracting. I've fixed that as shown in edits. I just need to fix the problem with the minutes reaching 60, now put in the question. I will also change the question title because it is no longer the problem. I do not know how to simplify the whole thing, kind of new to programming and this is just a random project I am pursuing. – Rare Pepe Jan 05 '19 at 13:49
  • The problem is with the subtracting because you cannot subtract a date and time from a date and time to get a date and time. You can only subtract a date and time from a date and time to get a resultant number of minutes, hours, days, months and years etc. not a date. – Compo Jan 05 '19 at 14:15
  • But then how can I fix the problem with the minutes becoming 60? – Rare Pepe Jan 05 '19 at 14:17
  • Compo, I am not subtracting a date and time from a date and time. Please ignore that paragraph. It is rather more of subtracting or adding maybe 30 days to the days value and 12 hours +- to the hours value, and subtracting 2018 years from the current year, 2019. I apologize for not picking that up, but I hope I have clarified the problem enough. This is why I was saying the problem isn't with the subtracting (at least, I think so) but with the minutes becoming 60 etc. I meant subtracting 1 day, 1 month, 2000 years, 10 hours and 10 minutes not subtracting from the date 01/01/2000. Sorry. – Rare Pepe Jan 05 '19 at 14:22
  • Please,write an example. Put the input and the desired output with numbers!!! – Aacini Jan 05 '19 at 14:33
  • Please check the new edit. I hope it is easy to understand. – Rare Pepe Jan 05 '19 at 14:44
  • `PowerShell`, as I've already suggested, will easily perform this kind of task, and does not care about your locale, _(date/time format)_. – Compo Jan 05 '19 at 15:28
  • I've no idea how to use PowerShell for this task.No idea what PowerShell is. May I ask for a code spoonfeed? – Rare Pepe Jan 05 '19 at 15:46
  • No, because code requests are off topic here. You should research, learn and write your own code. PowerShell is built into the OS you're using, and there are many answers here, even under the batch-file tag which use it for batch files requiring date and time output, modifications or calculations. – Compo Jan 05 '19 at 17:38

2 Answers2

1

You have a fundamental error in your description. When you subtract a number of days/months/years from a date, you are subtracting a date, not a number! For example, if today date is 05/01/2019 (obviously in DD/MM/YYYY format) and you want to subtract 1 month, the result should be 05/12/2018 because you are subtracting a date (1 month). If you subtract a number 1 from the month part, then the result will be 05/00/2019. For this reason, this problem should be solved via the well-known methods to add and subtract dates.

The problem with these methods is that they are valid just for a certain range of dates, and that ranges usually start in 1583. If you want to subtract 2000 from year 2018 and get 18, then such "year 18" is not a valid year in the usual date management methods. For this reason, besides to use the usual methods to manage dates, you also need to complete a couple small adjustments.

I taken the code segments linked in my comment and modified they slightly in order to solve this problem. I completed some tests and it seems to work correctly, but perhaps the method may fail in certain specific range of values.

@echo off
setlocal EnableDelayedExpansion

rem Subtract a number of Days/Months/Years @ Hours:Minutes:Seconds from a datetime stamp
rem Antonio Perez Ayala aka Aacini

rem Define the "Date in DDMMYYYY format" To "Julian Day Number" conversion "function"
set "DateToJDN(Date)=( a=1Date, y=a%%10000, a/=10000, m=a%%100, d=a/100-100, a=(m-14)/12, (1461*(y+4800+a))/4+(367*(m-2-12*a))/12-(3*((y+4900+a)/100))/4+d-32075 )"

set /P "stamp1=Enter base timestamp as DD/MM/YYYY HH:MM:SS  "
set /P "stamp2=Enter timestamp to subtract in same format:  "

set "adjust=0"
for /F "tokens=1-4" %%a in ("%stamp1% %stamp2%") do set "date1=%%a" & set "time1=%%b" & set "date2=%%c" & set "time2=%%d"
if 1%date2:~-4% lss 11600 (
   set /A "adjust=1%date2:~-4%+1600"
   set "date2=%date2:~0,-4%!adjust:~1!"
   set "adjust=1600"
)
set /A "days=!DateToJDN(Date):Date=%date1:/=%! - !DateToJDN(Date):Date=%date2:/=%!, days1600=%DateToJDN(Date):Date=00001600%"
set /A "ss=(((1%time1::=-100)*60+1%-100) - (((1%time2::=-100)*60+1%-100)"
if %ss% lss 0 set /A "ss+=60*60*24, days-=1"
set /A "hh=ss/3600+100, ss%%=3600, mm=ss/60+100, ss=ss%%60+100"
if %days% lss %days1600% set /A days+=days1600, days1600=0
set /A "l=days+68569,n=(4*l)/146097,l=l-(146097*n+3)/4,i=(4000*(l+1))/1461001,l=l-(1461*i)/4+31,j=(80*l)/2447,D=l-(2447*j)/80+100,l=j/11,M=j+2-(12*l)+100,Y=100*(n-49)+i+l+10000+adjust"
if %days1600% equ 0 set /A Y-=1600

echo                                            -----------------------
echo                                     Result:  %D:~1%/%M:~1%/%Y:~1% %hh:~1%:%mm:~1%:%ss:~1%

A small example:

Enter base timestamp as DD/MM/YYYY HH:MM:SS  05/01/2019 10:53:45
Enter timestamp to subtract in same format:  01/01/2000 10:10:00
                                           -----------------------
                                    Result:  04/12/0018 00:43:45

PS - I really would like to see a PowerShell solution for this problem. It seems that it would take just a simple and short line of code...

Aacini
  • 65,180
  • 12
  • 72
  • 108
0

A simpler windows batch option is to call a PowerShell command from within your batch script to manipulate past and future dates.

Below, lines 8 and 9 create and format your arbitrary date.

 :: Set the below 3 variables to generate an Arbitrary Clock
 :: Use a negative number to subtract (-7), positive number to add (7)
 set Altered_Days=-7
 set Altered_Months=-10
 set Altered_Years=-4

 :: The script will merge days and years to determine the arbitrary date and print the Arbitrary date to the screen
 set /a Altered_Days=(%Altered_Years%*356)+%Altered_Days%
 powershell -command "(((Get-date).AddDays(%Altered_Days%)).AddMonths(%Altered_Months%)).ToString('HH:mm, MM-dd-yyyy')" 

 :: If you want to capture the value in a variable, use the below line
 powershell -command "(((Get-date).AddDays(%Altered_Days%)).AddMonths(%Altered_Months%)).ToString('HH:mm, MM-dd-yyyy')">captureVar && set /p Arbitrary_Clock=<captureVar
 echo Arbitrary Clock Prediction && echo %Arbitrary_Clock%

This will enable your batch script to create the end result you are looking for on your Windows 10 OS.

One of the great things about PowerShell is that it can easily be called from the cmd line and a batch script. To do so, enter

   powershell -command "the powershell command(s)"

If the PowerShell command calls for quotes, you must use a single quote to avoid ending the PowerShell session. To escape characters, follow batch scripting rules. Batch variables can be read in the PowerShell command, but values created in PowerShell must be redirected for later use in your batch script. This can be done as in line 12 above, or by using PowerShell's Set-Content command to write to a file. I frequently use PowerShell in my batch scripts to manipulate file data.

  powershell -command "(Get-Content 'file.txt') -replace 'string','' | Select-String -Pattern 'keep lines with string' -SimpleMatch) -replace 'another string','to somthing different' | Set-Content 'file.txt'"

In the case of adding or subtracting time, PowerShell makes the task easy. And it doesn't require you to create a different script. You can write everything else as batch, use PowerShell commands you find helpful, and save the windows' script as batch.

For detailed explanations on how Get-Date and addDays work, reference:

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-date?view=powershell-6

and

https://devblogs.microsoft.com/scripting/adding-and-subtracting-dates-with-powershell/

David
  • 134
  • 7