Skip to main content
fix [[ -> (( error
Source Link
icarus
  • 19.1k
  • 1
  • 42
  • 57

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") # start in seconds since 1 Jan 1970 e=$(date +%s -d "1/1/$(($2+1))") # start of end year +1 in seconds days=$(((e-s)/(24*3600))) # number of days from start to end factor=$((32767/$days)) # RANDOM is 0 to 32767. See how many toobig=$(($factor*$days)) # exact multiples of days. # if RANDOM is too large, draw again for((i=0;i<${3:-1};i++)) # produce $3 random dates do r=$RANDOM # find a random number < toobig while [[(( r >= toobig ]])) # if toobig, then loop. do r=$RANDOM done offset=$(($r/$factor)) # get (0,days) from (0,factor*days) # output horrible day/month/year for N days past start date date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias. If a random number source could give you 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 equally and you want a random number between 0 and 3 inclusive, then if you get 0 or 1 from the source you report 0, if you get 2 or 3, then you report 1, if you get 4 or 5 you report 2, if you get 6 or 7 you report 3, and if you get 8 or 9 you ignore this number from the source.

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") # start in seconds since 1 Jan 1970 e=$(date +%s -d "1/1/$(($2+1))") # start of end year +1 in seconds days=$(((e-s)/(24*3600))) # number of days from start to end factor=$((32767/$days)) # RANDOM is 0 to 32767. See how many toobig=$(($factor*$days)) # exact multiples of days. # if RANDOM is too large, draw again for((i=0;i<${3:-1};i++)) # produce $3 random dates do r=$RANDOM # find a random number < toobig while [[ r >= toobig ]] # if toobig, then loop. do r=$RANDOM done offset=$(($r/$factor)) # get (0,days) from (0,factor*days) # output horrible day/month/year for N days past start date date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias. If a random number source could give you 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 equally and you want a random number between 0 and 3 inclusive, then if you get 0 or 1 from the source you report 0, if you get 2 or 3, then you report 1, if you get 4 or 5 you report 2, if you get 6 or 7 you report 3, and if you get 8 or 9 you ignore this number from the source.

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") # start in seconds since 1 Jan 1970 e=$(date +%s -d "1/1/$(($2+1))") # start of end year +1 in seconds days=$(((e-s)/(24*3600))) # number of days from start to end factor=$((32767/$days)) # RANDOM is 0 to 32767. See how many toobig=$(($factor*$days)) # exact multiples of days. # if RANDOM is too large, draw again for((i=0;i<${3:-1};i++)) # produce $3 random dates do r=$RANDOM # find a random number < toobig while (( r >= toobig )) # if toobig, then loop. do r=$RANDOM done offset=$(($r/$factor)) # get (0,days) from (0,factor*days) # output horrible day/month/year for N days past start date date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias. If a random number source could give you 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 equally and you want a random number between 0 and 3 inclusive, then if you get 0 or 1 from the source you report 0, if you get 2 or 3, then you report 1, if you get 4 or 5 you report 2, if you get 6 or 7 you report 3, and if you get 8 or 9 you ignore this number from the source.

added 874 characters in body
Source Link
icarus
  • 19.1k
  • 1
  • 42
  • 57

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") # start in seconds since 1 Jan 1970 e=$(date +%s -d "1/1/$(($2+1))") # start of end year +1 in seconds days=$(((e-s)/(24*3600))) # number of days from start to end factor=$((32767/$days)) # RANDOM is 0 to 32767. See how many toobig=$(($factor*$days)) # exact multiples of days. # if RANDOM is too large, draw again for((i=0;i<${3:-1};i++)) # produce $3 random dates do r=$RANDOM # find a random number < toobig while [[ r >>= toobig ]] # if toobig, then loop. do r=$RANDOM done offset=$(($r/$factor)) # get (0,days) from (0,factor*days) # output horrible day/month/year for N days past start date date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias. If a random number source could give you 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 equally and you want a random number between 0 and 3 inclusive, then if you get 0 or 1 from the source you report 0, if you get 2 or 3, then you report 1, if you get 4 or 5 you report 2, if you get 6 or 7 you report 3, and if you get 8 or 9 you ignore this number from the source.

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") e=$(date +%s -d "1/1/$(($2+1))") days=$(((e-s)/(24*3600))) factor=$((32767/$days)) toobig=$(($factor*$days)) for((i=0;i<${3:-1};i++)) do r=$RANDOM while [[ r > toobig ]] do r=$RANDOM done offset=$(($r/$factor)) date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias.

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") # start in seconds since 1 Jan 1970 e=$(date +%s -d "1/1/$(($2+1))") # start of end year +1 in seconds days=$(((e-s)/(24*3600))) # number of days from start to end factor=$((32767/$days)) # RANDOM is 0 to 32767. See how many toobig=$(($factor*$days)) # exact multiples of days. # if RANDOM is too large, draw again for((i=0;i<${3:-1};i++)) # produce $3 random dates do r=$RANDOM # find a random number < toobig while [[ r >= toobig ]] # if toobig, then loop. do r=$RANDOM done offset=$(($r/$factor)) # get (0,days) from (0,factor*days) # output horrible day/month/year for N days past start date date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias. If a random number source could give you 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 equally and you want a random number between 0 and 3 inclusive, then if you get 0 or 1 from the source you report 0, if you get 2 or 3, then you report 1, if you get 4 or 5 you report 2, if you get 6 or 7 you report 3, and if you get 8 or 9 you ignore this number from the source.

Source Link
icarus
  • 19.1k
  • 1
  • 42
  • 57

If the difference in the number of years is less than about 90 you can use the $RANDOM variable in bash to give you an offset in number of days and use the limited ability of the date command to do the calculation.

#!/bin/bash s=$(date +%s -d "1/1/$1") e=$(date +%s -d "1/1/$(($2+1))") days=$(((e-s)/(24*3600))) factor=$((32767/$days)) toobig=$(($factor*$days)) for((i=0;i<${3:-1};i++)) do r=$RANDOM while [[ r > toobig ]] do r=$RANDOM done offset=$(($r/$factor)) date -d "$offset days 1/1/$1" +%d/%m/%Y done 

The inner loop to select the random number attempts to correct for bias.