I'm writing this .bat that calculates the past day.
title Past Day
set /a dayNum=%date:~0,2% - 1
set monthNum=%date:~3,2%
set yearNum=%date:~6,4%
rem Checks if it's first day of the month
if %dayNum%==0 (
set /a monthNum-=1
rem Checks the last day of past month
rem For 0, 1, 3, 5, 7, 8, 10 => 31, where 0 is December[12]
rem For 4, 6, 9, 11 => 30
rem For 2 => 28 or 29[leap]
for %%a in (0, 1, 3, 5, 7, 8, 10) do (
if %monthNum%==%%a (
rem If, December, yearNum-1 and monthNum = 12
if %monthNum%==0 (
set /a monthNum=12 * 1
set /a yearNum-= 1
)
set /a dayNum=31 * 1
)
)
for %%a in (4, 6, 9, 11) do (
if %monthNum%==%%a (
set /a dayNum=30 * 1
)
)
if %monthNum%==2 (
rem Leap year check
set /a leap=!(%yearNum% %% 4) - !(%yearNum% %% 100) + !(%yearNum% %% 400)
if %leap%==1 (
set /a dayNum=29 * 1
) else (
set /a dayNum=28 * 1
)
)
)
rem Adds leading zero
if 0%dayNum:~1,1%==0 (
set dayNum=0%dayNum%
)
If it's not first day, it works well, but if I force dayNum to be 0 (indicating it is first day), the output is:
>title Past Day
>set /a dayNum=0
>set monthNum=03
>set yearNum=2020
>rem Checks if it's first day of the month
- was unexpected at this moment.
> set /a leap=!(2020 % 4) - !(2020 % 100) + !(2020 % 400)
Using echo, the variables contents are the same as they started and, I think, the code didn't entered the if statement.
The expected output is to get like dayNum=31 or dayNum=29(if leap year) and so on.
Related
i'm trying to select a date in a monthcal with the sendmessage cmd from AHK. Unfortunately, this is not working and i don't know where is my mistake or my misunderstanding. Anyone could help ? Here's what i already try.
ConvertNormalDateToSystemTime(YYYYMMDD)
; this return a SystemTime format date from a normal date
{
YYYYMMDD.=000000
YYYYMMDDHHMISS:=YYYYMMDD
VarSetCapacity(SystemTime, 16, 0) ; This struct consists of 8 UShorts (i.e. 8*2=16).
Int := SubStr(YYYYMMDDHHMISS, 1, 4) ; YYYY (year)
NumPut(Int, SystemTime, 0, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 5, 2) ; MM (month of year, 1-12)
NumPut(Int, SystemTime, 2, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 7, 2) ; DD (day of month)
NumPut(Int, SystemTime, 6, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 9, 2) ; HH (hour in 24-hour time)
NumPut(Int, SystemTime, 8, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 11, 2) ; MI (minute)
NumPut(Int, SystemTime, 10, "UShort")
Int := SubStr(YYYYMMDDHHMISS, 13, 2) ; SS (second)
NumPut(Int, SystemTime, 12, "UShort")
return % &SystemTime
}
MCM_FIRST:= 0x1000
MCM_SETCURSEL:= MCM_FIRST + 2
MyDate:= 20211115
WinActivate ahk_class AutoHotkeyGUI, ExempleCalendrier.ahk
dateASelectionnerDansCalendrier := ConvertNormalDateToSystemTime(20211115)
try
{
SendMessage MCM_SETCURSEL , , &dateASelectionnerDansCalendrier, SysMonthCal321, ahk_class AutoHotkeyGUI ; THIRD TRIAL
MsgBox % ErrorLevel
}
catch e
{
MsgBox % ErrorLevel
}
An other strange thing is that i always get the MCM_SETCURSEL message back in MyReturn variable. I already try to compile the script and run it as admin. I know that there is no multiselected option on my monthcal. Someone on Discord suggest me that MCM_SETCURSEL lparam was pointing to a systemtime. So how could i send my date to my monthcal ? Should i convert my actual date into a systemTime in an other way ? (speaking as a noob)
Thanks for any help !
I need to calculate the date between two dates, and tell me how many day are in between, if more than 30 days then I will target something.
in this script D is the date (in the past) that I want to calculate from today
set X to MYdatefromSafari -- "August 26th, 2016"
set D to ConvertDate(X)
log D
on ConvertDate(X) -- sub routine to convert string "english_month dayth/st, year" to real date
set MS to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set LW to every word of X
if (count of LW) is not 3 then return "" -- invalid format
set MI to 0 -- check month : should be in the list
repeat with I from 1 to 12
if item I of MS is item 1 of LW then set MI to I
end repeat
if MI is 0 then return "" -- the fisrt word is not in the list of months
try -- check day : it should be NNth of NNst
set DI to (text 1 thru -3 of item 2 of LW) as integer
end try
if not ((DI > 0) and (DI < 31)) then return "" -- invalid day
try -- check year
set YI to (item 3 of LW) as integer
end try
if not ((YI > 0) and (YI < 9999)) then return "" -- invalid year
return date ((DI & "/" & MI & "/" & YI) as string)
end ConvertDate
In the best scenario, that would calculate the number of date in between if less than a year, and month or year if more
EDIT :
set X to "August 26th, 2016"
set MyDate to ConvertDate(X)
set D to ConvertDate(X)
log D
set SecondDate to (current date) -- = system date
set ListDiff to DateDiff(D, CD) -- returns {diff days, diff months, diff years}
log "Days = " & item 1 of ListDiff
log "Months = " & item 2 of ListDiff
log "Years = " & item 3 of ListDiff
on DateDiff(D1, D2) -- return list with difference in days, in months, in years
-- depending if differences is less than month, or less than year or higher than a year
if D1 > D2 then -- set DStart as oldest date
copy {D1, D2} to {Dend, DStart}
else
copy {D1, D2} to {DStart, Dend}
end if
return {(Dend - DStart) div days, (Dend - DStart) div (30 * days), (Dend - DStart) div (365 * days)}
end DateDiff
on ConvertDate(X) -- sub routine to convert string "english_month dayth/st, year" to real date
set MS to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
set LW to every word of X
if (count of LW) is not 3 then return "" -- invalid format
set MI to 0 -- check month : should be in the list
repeat with I from 1 to 12
if item I of MS is item 1 of LW then set MI to I
end repeat
if MI is 0 then return "" -- the fisrt word is not in the list of months
try -- check day : it should be NNth of NNst
set DI to (text 1 thru -3 of item 2 of LW) as integer
end try
if not ((DI > 0) and (DI < 31)) then return "" -- invalid day
try -- check year
set YI to (item 3 of LW) as integer
end try
if not ((YI > 0) and (YI < 9999)) then return "" -- invalid year
return date ((DI & "/" & MI & "/" & YI) as string)
end ConvertDate
Sub-routine "DateDiff" bellow gives back a list of 3 difference values : in days, months and years.
Set X to MyDatefrom Safari
Set MyDate to ConvertDate(X)
set SecondDate to (current date) -- = system date
set ListDiff to DateDiff(D, CD) -- returns {diff days, diff months, diff years}
log "Days = " & item 1 of ListDiff
log "Months = " & item 2 of ListDiff
log "Years = " & item 3 of ListDiff
on DateDiff(D1, D2) -- return list with difference in days, in months, in years
-- depending if differences is less than month, or less than year or higher than a year
if D1 > D2 then -- set DStart as oldest date
copy {D1, D2} to {Dend, DStart}
else
copy {D1, D2} to {DStart, Dend}
end if
return {(Dend - DStart) div days, (Dend - DStart) div (30 * days), (Dend - DStart) div (365 * days)}
end DateDiff
on ConvertDate(X) -- copy your existing sub-routine
end ConvertDate
For instance if MyDate = Jan 20th 2016 and we are August 26th 2016, it will return {219, 7, 0} because différence is 216 days or 7 months (Jan to August) or 0 year (2016 both dates !).
I see some interesting behaviour with an extended explicit function.
I define an implicit function
isLeap (year:nat) res:bool
post res = year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0);
And a corresponding explicit function (since the post condition is computable)
isLeap2 : nat -> bool
isLeap2 (year) == year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0);
isLeap2 returns values expected. Then I define an extended implicit function
isLeap (year:nat) res:bool
== year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0)
post res = year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0);
This works as expected except when provided with an argument that is a multiple of 100 but not 400. The result is
Error 4056: Postcondition failure: post_isLeap in 'test' (/Users/paul/Documents/Overture/workspace/test/test.vdmsl) at line 8:31
Then as I was typing this in I thought, what about
isLeap (year:nat) res:bool
== year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0)
post res <=> year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0);
and the result is as expected. What is the difference between '=' and '<=>' in this context? In section 3.1.1 of VDM-10 Language Manual (issue Nov 2014) is states "Semantically <=> and = are equivalent when we deal with boolean values." Are they different operationally?
The answer of course is operator precedence. If I parenthesise the first version all is well.
post res = (year rem 4 = 0 and (year rem 100 = 0 => year rem 400 = 0));
I just started the matasano security challenge, and thought about learning IO at the same time.
So now, i'm stuck on challenge 1 where I need to convert a string to base64.
Anyway i've come to the point where i need to convert from binary to decimal, here is my aproach:
binToDec := method( bin, <-- program does not enter this method
dec := 0
rem := 0
i := 0
while ( bin != 0,
rem = bin % 10
bin = bin / 10
dec = dec + rem * 2 pow( i )
i = i + 1
)
return dec
)
toBase64Ascii := method( slice,
tmp := ""
for( a, 0, slice size, <-- construct a string to use with asNumber
tmp = tmp .. slice at( a )
)
dec := binToDec( tmp asNumber ) <-- the line that make the whole thing crash
)
for ( a, 0, bin size, 6,
tmp := toBase64Ascii( bin slice( a, a + 6 )
***some more code***
)
there is no error message or anything, the program just hangs indefinitely.
From the documentation:
asNumber
Returns the receiver converted to a number. Initial whitespace is ignored.
So i must say i'm quite confused here, what is happening ?
I would have done some more research but io is imposible to google for...
I'm not sure what the expected input and output of your binToDec method is, but
while ( bin != 0,
rem = bin % 10
bin = bin / 10
dec = dec + rem * 2 pow( i )
i = i + 1
)
is likely an infinite loop. bin is a floating point number which is repeatedly divided by 10, which does not mean that it ever reaches 0.
I need to convert a string to base64.
Notice that there are asBase64 and fromBase64 methods on sequences.
I have the following formula as the grouping for a Cross Tab Report:
{Command.Year} & ' ' & {Command.RF Period}
Year is a SmallInt and Period is a TinyInt.
The problem is that it shows on the report as:
2,009.00 9.00
The database values are actually:
2009 9
I can't remove the decimal places via formatting because they are in the formula together.
Ultimately I'd like it to be:
2009 09
Edit:
I found this link: http://www.kenhamady.com/form15.shtml
Now my code looks like this for period:
WhileReadingRecords;
StringVar text := Totext ( {Command.RF Period} , 6 , "" ) ; //put your numeric field in this line
NumberVar end := length ( text ) ;
NumberVar clip :=
(if Val ( text [ end - 6 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 5 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 4 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 3 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 2 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 1 to end ] ) = 0 then 1 else 0 ) +
(if Val ( text [ end - 0 to end ] ) = 0 then 1 else 0 ) ;
text [ 1 to Length ( text ) - clip ]
However, I don't use Crystal Language, I use VB. How do I append a 0 in front of the period if it does not begin with a 1?
The problem now is that September (9) shows up after October, Nov, and Dec because aphabetically 9 comes after 1.
Anybody?
The ToText function is very useful for this kind of thing, no loops required. In Crystal's VB Syntax :
Formula = ToText({Command.Year}, 0, "") & " " & ToText({Command.RF Period}, "00")
This should work if {Command.Year} and {Command.RF Period} are integers as you describe.