Completely depends on the kind of code you’re wrighting. MySQL queries can do this, php can do it. I’m oldfashioned, mostly bring dates back to secs from 1970-1-1 0:00:00 than subtract, and format the result.
If you have control over the date, meaning you’re the one giving the date format then yeah GNU date(1) might be a good choice for you, if not well dateutils as suggested above.
malcolmlewis
Hi
Install dateutils and there is ddiff and dadd... check the man page for formatting as required...
Code:
ddiff 2017-11-15 2018-27-08
350
I’m trying to avoid having too many dependencies in scanvirus. It now has two. However, I will keep that info noted for something else. Thanks.
scanvirus is missing the feature: how long since last scan? linux and mswin
I have various ways of saving that data, including globals and logfile. If I read the logfile backward or grep, I can find the date info. Next question…
How do I convert a text date into numbers I can use?
I’m using GNU coreutils “date” as follows in a Bash script to work out when some housekeeping has to be done:
#!/bin/bash
date +%Y%m%d > ~/.local/share/«Directory and file»
LastDate=$(cat ~/.local/share/«Directory and file»)
TwoDaysAgo=$(date --date='2 days ago' +%Y%m%d)
if $LastDate -lt $TwoDaysAgo ]
then
«Do something»
fi
By adding ‘%H’, ‘%M’, ‘%S’, and %N you can increase the accuracy from “Day” through to “Nanoseconds” if need be …
First,
As jetchisel and dcurtisfra describe,
date is available by default and supports diffing dates.
As for changing date formats, I’d recommend you simply avoid the problem instead of doing a conversion (although of course conversion is an option). Create your own application log and create events however you wish, including your preferred data format. Then you can extract data as you wish from your own logs and do as you wish.
Or,
Re-think what your task, maybe there is a different and possibly better way of doing what you need to have accomplished.
For instance, why do you need to diff your dates and then do something with that info? Would simply activating a counter that counts seconds and then execute a task at some threshold accomplish the same objective?
Do the samething and run both declare -p and printf.
declare -p month day year
printf '%s
' "$month" "$day" "$year"
Both solution should work on any POSIX compliant shell (including bash of)
I gave you what you asked for, but it might be what you need… but hey it is your script…
One more thing i’d use the format ‘+%D’ but that is using a slash / as the separator. One advantage is that you can convert that into epoch without messing with the delimiter.
var=$(date -d'last year' '+%D')
Now convert that into Unix epoch time.
date -d"$var" '+%s'
So now at least you have a time format that you can do math/arithmetic with. Just my 2 cents…
These scans I usually run after booting and often more than once a session.
A counter that functions outside the script would require more complex code. I understand the linux concept of multi-user and multi-processing system. I’m avoiding starting other processes that I would need to later shutdown. Based on all the info presented, I --think-- i’v found the simplest and most practical method. This also avoids adding more dependencies.
Provide some simple upgrade instructions to the user. Copy older logs somewhere else.
dateinsecondssince1970 Clean Scan: linux 10-09-2018 10:01:43pm {}
The first parm is masked out in ‘scanvirus -vl’. The script can then make use of new field. Then It should be a simple matter of finding both last mswin and linux scan.
Also, I make an additional data file holding date of last scans of linux and mswin. Or adding that info to the beginning of the logfile, masking it from ‘scanvirus -vl’.
Thanks to all for the very useful info. I need to work the on the new design more.
Please be aware that, Bash is a mixture of “quick and dirty” and “strict”:
The “quick and dirty” is what I posted previously.
[HR][/HR]A “strict” method ensures that the values which Bash is comparing are strictly integer values and not what Bash “decides for itself”:
Ensure that Bash is using integer values: ‘declare -i LastDate’ – ensures that the parameter “LastDate” is in fact an integer value … - Use integer comparisons: ‘if (( $ LastDate< $TwoDaysAgo))’ – note the integer “less than” comparison and the use of ‘((’ and ‘))’ to force Arithmetic Evaluation of the Compound Command …
With additional information (and help here), I found on linux help pages, this is a code snip from scanvirus that allows me to keep the original logs. NOT recommended to use at this time for current scan virus users. Still needs some debugging. I may need to have users delete or rename old logs.
elif [ "$1" = "-vl" ] || [ "$1" = '-viewlogs' ] ; then
let system_mask=0
if [[ "$2" == *"l"* ]]; then
system_mask=1
elif [ "$2" == *"m"* ];then
system_mask=2
fi
let scan_limit=0
if [[ "$2" == *"d"* ]]; then
if [[ "$3" == "" ]]; then
let scan_limit=0
else
scan_limit="$3"
fi
fi
current_time_seconds=$(date +%s)
let linecount=0
while read -ra line
do
let linecount=linecount+1
if [ "$linecount" -le 4 ]; then
for update_field in ${line
[li]}[/li] do
printf "%s" $update_field
done
printf "
"
continue
fi
scan_time_seconds=${line[6]}
if [ "$scan_time_seconds" = "" ]; then
#date --date="11/12/2018 09:04:34pm" '+%s'
#echo "11-13-2018" | tr "-" "/"
scan_date=$(printf "${line[3]}" | tr "-" "/")
scan_time=${line[4]}
scan_time_seconds=$(date --date="$scan_date $scan_time" '+%s')
#printf "scan_time_seconds= %s %s
" $scan_time_seconds
fi
scan_difference_seconds=$((current_time_seconds - scan_time_seconds))
scan_difference_minutes=$((scan_difference_seconds / 60))
scan_difference_hours=$((scan_difference_minutes / 60))
scan_difference_days=$((scan_difference_hours / 60))
#printf "%s - %s = %s %s
" $current_date $scan_date $scan_difference_seconds $scan_difference_minutes
if [ $scan_difference_days -le $scan_limit ] || [ $scan_limit -eq 0 ]; then
printf "%s %s %s %s %s %s %s" ${line[0]} ${line[1]} ${line[2]} ${line[3]} ${line[4]} ${line[5]}
printf " %s days" $scan_difference_days
printf "
"
fi
done < "${Virus_Vault_Folder}/VirusScanLog.txt"
printf "
"
I’v been reading the comments and the help pages. The string comparison work. I’ll leave them alone for now. ‘let systemmask=0’ is being used like white space. It might be causing a bug.
Also, i’v figured out how to fix the broken line for ‘mswin’. I may need to change the position of the time stamp.
I forgot to include all three: code, input, and output. Using ‘declare -i var1 var2 var3’, mixing strings and vars might be creating a buggy output.
elif [ "$1" = "-vl" ] || [ "$1" = '-viewlogs' ] ; then
let system_mask=0
if [[ "$2" == *"l"* ]]; then
system_mask=1
elif [ "$2" == *"m"* ];then
system_mask=2
fi
let scan_limit=0
if [[ "$2" == *"d"* ]]; then
if [[ "$3" == "" ]]; then
let scan_limit=0
else
scan_limit="$3"
fi
fi
current_time_seconds=$(date +%s)
let linecount=0
while read -ra line
do
let linecount=linecount+1
if [ "$linecount" -le 4 ]; then
for update_field in ${line
[li]}[/li] do
printf "%s" $update_field
done
printf "
"
continue
fi
scan_time_seconds=$(printf "${line[6]}" | tr " " "/")
if [ "$scan_time_seconds" = "" ]; then
#date --date="11/12/2018 09:04:34pm" '+%s'
#echo "11-13-2018"
scan_date=$(printf "${line[3]}" | tr "-" "/")
scan_time=${line[4]}
scan_time_seconds=$(date --date="$scan_date $scan_time" '+%s')
#printf "scan_time_seconds= %s %s
" $scan_time_seconds
fi
scan_difference_seconds=$((current_time_seconds - scan_time_seconds))
scan_difference_minutes=$((scan_difference_seconds / 60))
scan_difference_hours=$((scan_difference_minutes / 60))
scan_difference_days=$((scan_difference_seconds / 216000))
#printf "%s - %s = %s %s
" $current_date $scan_date $scan_difference_seconds $scan_difference_minutes
if [ $scan_difference_days -le $scan_limit ] || [ $scan_limit -eq 0 ]; then
printf "%s %s %s %s %s %s %s" ${line[0]} ${line[1]} ${line[2]} ${line[3]} ${line[4]} ${line[5]}
printf " %s " $scan_difference_days
printf "
"
fi
done < "${Virus_Vault_Folder}/VirusScanLog.txt"
printf "
"
Input file: scanlog file is worst possible mixing of old and new code runs. To see if the new code can handle it.
..... Virus Scan Log .....
_____________________________________________________________________
Clean Scan: linux 11-07-2018 04:25:55pm {}
Clean Scan: linux 11-07-2018 05:01:49pm {}
Clean Scan: linux 11-07-2018 05:21:34pm {}
Clean Scan: linux 11-08-2018 01:21:37pm {}
Clean Scan: linux 11-11-2018 01:14:36pm {}
Clean Scan: linux 11-11-2018 01:38:24pm {}
Clean Scan: linux 11-12-2018 12:57:02pm {}
Clean Scan: linux 11-12-2018 08:44:07pm {} 1542084259
Clean Scan: mswin 11-12-2018 08:45:36pm {;} 1542084350
Clean Scan: linux 11-12-2018 09:04:34pm {} 1542085487
Clean Scan: linux 11-13-2018 01:44:37pm {}
Clean Scan: linux 11-13-2018 02:33:04pm {}
Clean Scan: linux 11-13-2018 10:24:35pm {}
Clean Scan: linux 11-14-2018 01:46:56pm {}
Clean Scan: linux 11-14-2018 08:21:06pm {}
Clean Scan: linux 11-14-2018 09:05:43pm {} 1542258358
Clean Scan: linux 11-16-2018 02:03:40pm {}
Clean Scan: linux 11-16-2018 09:35:14pm {} 1542432926
Clean Scan: linux 11-16-2018 09:35:32pm {} 1542432944
Clean Scan: linux 11-18-2018 12:47:23pm {} 1542574055
Clean Scan: linux 11-18-2018 12:48:12pm {} 1542575479
Clean Scan: linux 11-18-2018 02:03:20pm {} 1542579740
Clean Scan: linux 11-20-2018 01:25:38am {}
Virus Found: mswin 11-20-2018 01:59:50am {Recovery;EFI system partition;MSWIN6410;;Backups;;} 1542725039
Clean Scan: linux 11-20-2018 02:13:36pm {} 1542753136
Clean Scan: linux 11-22-2018 01:42:07pm {} 1542924356
Output
.....VirusScanLog.....
_____________________________________________________________________
Clean Scan: linux 11-07-2018 04:25:55pm {} 5
Clean Scan: linux 11-07-2018 05:01:49pm {} 5
Clean Scan: linux 11-07-2018 05:21:34pm {} 5
Clean Scan: linux 11-08-2018 01:21:37pm {} 5
Clean Scan: linux 11-11-2018 01:14:36pm {} 4
Clean Scan: linux 11-11-2018 01:38:24pm {} 4
Clean Scan: linux 11-12-2018 12:57:02pm {} 4
Clean Scan: linux 11-12-2018 08:44:07pm {} 3
Clean Scan: mswin 11-12-2018 08:45:36pm {;} 3
Clean Scan: linux 11-12-2018 09:04:34pm {} 3
Clean Scan: linux 11-13-2018 01:44:37pm {} 3
Clean Scan: linux 11-13-2018 02:33:04pm {} 3
Clean Scan: linux 11-13-2018 10:24:35pm {} 3
Clean Scan: linux 11-14-2018 01:46:56pm {} 3
Clean Scan: linux 11-14-2018 08:21:06pm {} 3
Clean Scan: linux 11-14-2018 09:05:43pm {} 3
Clean Scan: linux 11-16-2018 02:03:40pm {} 2
Clean Scan: linux 11-16-2018 09:35:14pm {} 2
Clean Scan: linux 11-16-2018 09:35:32pm {} 2
Clean Scan: linux 11-18-2018 12:47:23pm {} 1
Clean Scan: linux 11-18-2018 12:48:12pm {} 1
Clean Scan: linux 11-18-2018 02:03:20pm {} 1
Clean Scan: linux 11-20-2018 01:25:38am {} 1
Virus Found: mswin 11-20-2018 01:59:50am {Recovery;EFI 7143
Clean Scan: linux 11-20-2018 02:13:36pm {} 0
Clean Scan: linux 11-22-2018 01:42:07pm {} 0
I’m can’t find any code error. Unless someone finds the problem of the date conversion, I have to drop the idea in favor of an alternative idea. I’ll wait a few more days.
I took your advice. I did a complete redesign. The help menu shows the changes. Thanks to all for the information.
FYI, I tried to get ‘declare’ integer to work, use integers from the start. I kept getting errors. I’ll have to do more reading on the subject. Including the ‘’ ‘’ ‘=’ ‘==’ string operators.
scanvirus ‘view logs’ mask works, but I still have some coding on the rest of scanvirus before another release.
Scheduled scans? I’ll give that some thought.
Scan Virus
help commands
-------------
virus scan linux files
p1: -l or linux
p2: u freshclam update (optional)
p2: l low system priority (optional)
p2: p shutdown on finish + high system priority (optional)
virus scan windows files
p1: -m or -mswin
p2: m Move to Vault (optional)
p2: u freshclam update (optional)
p2: l low system priority (optional)
p2: p shutdown on finish + high system priority (optional)
open virus vault (KDE)
p1: -vf
view logs
p1: -vl
p2: l mask by linux scans
p2: m mask by mswin scans
p2: d mask by year and month p3: year p4: date
scanvirus -vl
scanvirus -vl m
scanvirus -vl l
scanvirus -vl d 2018 11
scanvirus -vl dm 2018 11
scanvirus -vl dl 2018 11
You’re giving yourself a hardtime in the date/time calculation. Instead of splitting up, better use the entire date/time string to get the right number, do the calculation, then reformat to your liking.
And, IMHO, the reason is, the way that UNIX® – and therefore Linux – handles time:
Basically it’s (currently) a 64 bit value (used to be a 32 bit value) which is the number of seconds since the UNIX® epoch: 00:00:00 UTC Thursday, 1st January 1970 …
Yes, at system programming levels we begin to talk about the “jiffy” which is determined by the kernel constant “HZ” which is often 4 ms.
You can also take a look at output of “/proc/timer_list” – on this system, CPU 0 – clock 0 – has a resolution of 1 ns …
[HR][/HR]The bottom line for scripts is, time is a 64 bit integer value representing the seconds since the UNIX® epoch …
In a script, simply handle everything which is dealing with time as a 64 bit integer value …
FYI, I’v been doing some formatting of the code to remove the single ’ =’ and consistent use of ‘’ and ‘]]’. No errors reported and it works.
#date --date="11/12/2018 09:04:34pm" '+%s'
This is the base code I found on a website. In my code, the larger the date difference, the worse the error. So, either this base code is the wrong method of date
conversion or the date command has a bug.
It looks like the bash ‘date’ command conversion isn’t taking into account extra days in some months. NOV 30 days, DEC 31 days. Unless, I missed something that code should work.
The bottom line for scripts is, time is a 64 bit integer value representing the seconds since the UNIX® epoch …
In a script, simply handle everything which is dealing with time as a 64 bit integer value …
Any attempt at using integers gives me errors and a lot of errors. Any recommended reads for integers?