Subtracting 30 days from current date in awk Unix command - shell

I want to modify this command to subtract 30 days from current date automatically
$ awk -v t=$(date +%Y-%m-%d) -F "'" '$1 < t' myname.dat
When I try
$ awk -v t=$(date "--date=$(date) -30days" +%Y-%m-%d) -F "'" '$1 < t' myname.dat
I get the following error; date: illegal option
I want to do this without having to convert the dates to epoch time in the file.

#edit: The following will work with GNU date only:
You can always subtract seconds.
date --date=#$(($(date +%s) - 30 * 24 * 3600)) +%Y-%m-%d
If you are interested in subtracting 30 days form "now", just:
date --date="-30days" +%Y-%m-%d
date date formatting is so broad, it's good to specify the exact date with for example -I option, from man date:
-I[FMT], --iso-8601[=FMT]
output date/time in ISO 8601 format. FMT='date' for date only
(the default), 'hours', 'minutes', 'seconds', or 'ns' for date
and time to the indicated precision. Example:
2006-08-14T02:34:56-06:00
The following:
date --date="$(date -I) -30days" +%Y-%m-%d
works on my system as expected.

Related

bash: substract a day from a date stored in a variable [duplicate]

I have the following in a shell script. How can I subtract one hour while retaining the formatting?
DATE=`date "+%m/%d/%Y -%H:%M:%S"`
The following command works on recent versions of GNU date:
date -d '1 hour ago' "+%m/%d/%Y -%H:%M:%S"
date -v-60M "+%m/%d/%Y -%H:%M:%S"
DATE=`date -v-60M "+%m/%d/%Y -%H:%M:%S"`
If you have bash version 4.4+ you can use bash's internal date printing and arithmetics:
printf "current date: %(%m/%d/%Y -%H:%M:%S)T\n"
printf "date - 60min: %(%m/%d/%Y -%H:%M:%S)T\n" $(( $(printf "%(%s)T") - 60 * 60 ))
The $(printf "%(%s)T") prints the epoch seconds, the $(( epoch - 60*60 )) is bash-aritmetics - subtracting 1hour in seconds. Prints:
current date: 04/20/2017 -18:14:31
date - 60min: 04/20/2017 -17:14:31
if you need substract with timestamp :
timestamp=$(date +%s -d '1 hour ago');
This work on my Ubuntu 16.04 date:
date --date="#$(($(date +%s) - 3600))" "+%m/%d/%Y -%H:%M:%S"
And the date version is date (GNU coreutils) 8.25
$ date +%Y-%m-%d-%H
2019-04-09-20
$ date -v-1H +%Y-%m-%d-%H
2019-04-09-19
But in shell use as like date +%Y-%m-%d-%H, date -v-1H +%Y-%m-%d-%H
Convert to timestamp (a long integer), subtract the right number of milliseconds, reformat to the format you need.
Hard to give more details since you don't specify a programming language...
If you need change timezone before subtraction with new format too:
$(TZ=US/Eastern date -d '1 hour ago' '+%Y-%m-%d %H:%M')
Here another way to subtract 1 hour.
yesterdayDate=`date -d '2018-11-24 00:09 -1 hour' +'%Y-%m-%d %H:%M'`
echo $yesterdayDate
Output:
2018-11-23 23:09
I hope that it can help someone.
DATE=date -1H "+%m/%d/%Y -%H:%M:%S"

Add 30 Mins Time to DateTime format YYYY-MM-DD hh:mm:ss in AIX 5.0

I'm running AIX with coreutils 5.0. I need to advance an arbitrary date (or time) as given conformative to ISO-8601 format YYYY-MM-DD hh:mm:ss.
For example:
Value of D1 is: 2017-07-08 19:20:01, and I need to add 30 minutes.
In a modern UNIX-system I could probably write something like
date -d "$D1 + 30 minutes" +'%H:%M'
but, alas, I need it to work on an old AIX.
Try
$ date -d "$(date -d "$D1") + 30 minutes" +'%H:%M'
This works in bash, but not in ksh.
The inner call to date will parse D1 to a date, and present it in date's "native" format.
$ date -d "$D1"
Sat Jul 8 19:20:01 CEST 2017
This output will be used with + 30 minutes to create the date that you want, with the outer call to date.
The inner call to date will be expanded so that
$ date -d "$(date -d "$D1") + 30 minutes" +'%H:%M'
will be equivalent to
$ date -d "Sat Jul 8 19:20:01 CEST 2017 + 30 minutes" +'%H:%M'
which will be
19:50
date -d #$(($(date -d "$D1" +%s) + 30 * 60)) +%H:%M
$(date -d "$D1" +%s) echoes the epoch
$((epoch + value)) calculates the wanted time
date -d#epoch +fmt formats it
If you are running AIX from 2003 you are in dire straits, my friend, but if you only need the time, not the full date, as your question implies, I think #RamanSailopal got us half way there.
echo $D1 | awk -F "[: ]" '{
m = $3+30;
h = ($2+int(m/60)) % 24;
printf("%02i:%02i\n", h, m%60)
}'
awk splits the input in different fields, with the splitter pattern given in the -F argument. The pattern denotes : or space .
The input will be split in
$1 = 2017-07-08
$2 = 19
$3 = 20
$4 = 01
Then the script calculates a fake minute value (that can be more than or equal to 60) and stores it in m. From that value it calculates the hour, modulo 24, and the actual minutes, m modulo 60.
This could fail if you hit a leap second, so if you need second precision at all times, you should use some other method.
Awk solution:
awk -F '[-: ]' '{
ram=(mktime($1" "$2" "$3" "$4" "$5" "$6)+(30*60));
print strftime("%Y-%m-%d %T",ram)
}' <<< "$D1"
Convert the date to a date string using awk's mktime function. Add 30 minutes (30*60) and then convert back to a date string with the required format using strftime.

Reading date with hour and incrementing it in shell script

I have a file with date '2015-06-01-12', how can I get it to increment the hour in shell script? The result I want is '2015-06-01-13'. If its the 23rd hour it has to move forward a date and get 00 as hour.
I was able to do it to date but have so far had not any luck with incrementing hours.
currDate=2015-06-02
nextDate=`date '+%Y-%m-%d' -d "$currDate+1 days"`
echo $nextDate
It is reasonably easy if you keep your date as an epoch (number of seconds since January 1, 1970):
$ currDate=$( date +%s -d "2015-06-02 23:00:00" )
$ echo $currDate
1433300400
$ date +%Y-%m-%d-%H -d #$currDate
2015-06-02-23
$ nextDate=$(( $currDate + 3600 )) #adding an hour's worth of seconds
$ date +%Y-%m-%d-%H -d #$nextDate
2015-06-03-00

bash shell scripting: create an endtime from a starttime

I am mediating some data from one file-format to another and am using bash to perform the mediation steps. Part of the process involves taking a timestamp from the filename to create a starttime and then adding 5 minutes to that to create the endtime. The filename gives me a date in this format YYYYmmddHHMMSS. I can easily add 500 to each starttime to get an endtime that works for all starttimes except 55 mins past the hour but this obviously not correct so I have tried to use the date --date= code to add the 5minutes like this:
date --date='$starttime +5 minutes' '+%Y%m%d%H%M%S'
for example:
date --date='20140220125500 +5 minutes' '+%Y%m%d%H%M%S'
However I get an error like this every time:
date: invalid date `20140220125500 +5 minutes'
Can anyone suggest what I need to change in my date statement or if there is a similar alternative syntax available?
This worked to me:
$ date --date='20140220 12:55:00 CET +5 minutes' '+%Y%m%d%H%M%S'
20140220130000
That is, the problem is that YYYYYMMDDHHMMSS alone is not understandable for date. Instead, give it on the YYYYYMMDD HH:MM:SS format.
As you are receiving the data on that YYYYYMMDDHHMMSS format, you can parse it with sed as follows:
$ file="YYYYmmddHHMMSS"
$ new_name=$(sed -e 's/^\(.\{8\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)/\1 \2:\3:\4/' <<< "$file")
$ echo "$new_name"
YYYYmmdd HH:MM:SS
So in your case:
$ file="20140220125500"
$ new_name=$(sed -e 's/^\(.\{8\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)/\1 \2:\3:\4/' <<< "$file")
$ echo "$new_name"
20140220 12:55:00
$ date --date="$new_name CET + 5 minutes"
Thu Feb 20 13:00:00 CET 2014
Note I used
$ date --date="$new_name CET +5 minutes" '+%Y%m%d%H%M%S'
^ ^
note the double quotes to have the var expanded

Bash: subtracting 10 mins from a given time

In a bash script, if I have a number that represents a time, in the form hhmmss (or hmmss), what is the best way of subtracting 10 minutes?
ie, 90000 -> 85000
This is a bit tricky. Date can do general manipulations, i.e. you can do:
date --date '-10 min'
Specifying hour-min-seconds (using UTC because otherwise it seems to assume PM):
date --date '11:45:30 UTC -10 min'
To split your date string, the only way I can think of is substring expansion:
a=114530
date --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
And if you want to just get back hhmmss:
date +%H%M%S --date "${a:0:2}:${a:2:2}:${a:4:2} UTC -10 min"
why not just use epoch time and then take 600 off of it?
$ echo "`date +%s` - 600"| bc; date
1284050588
Thu Sep 9 11:53:08 CDT 2010
$ date -d '1970-01-01 UTC 1284050588 seconds' +"%Y-%m-%d %T %z"
2010-09-09 11:43:08 -0500
Since you have a 5 or 6 digit number, you have to pad it before doing string manipulation:
$ t=90100
$ while [ ${#t} -lt 6 ]; do t=0$t; done
$ echo $t
090100
$ date +%H%M%S --utc -d"today ${t:0:2}:${t:2:2}:${t:4:2} UTC - 10 minutes"
085100
Note both --utc and UTC are required to make sure the system's timezone doesn't affect the results.
For math within bash (i.e. $(( and ((), leading zeros will cause the number to be interpreted as octal. However, your data is more string-like (with a special format) than number-like, anyway. I've used a while loop above because it sounds like you're treating it as a number and thus might get 100 for 12:01 am.
My version of bash doesn't support -d or --date as used above. However, assuming a correctly 0-padded input, this does work
$ input_time=130503 # meaning "1:05:03 PM"
# next line calculates epoch seconds for today's date at stated time
$ epoch_seconds=$(date -jf '%H%M%S' $input_time '+%s')
# the 600 matches the OP's "subtract 10 minutes" spec. Note: Still relative to "today"
$ calculated_seconds=$(( epoch_seconds - 600 )) # bc would work here but $((...)) is builtin
# +%H%M%S formats the result same as input, but you can do what you like here
$ echo $(date -r $calculated_seconds '+%H%M%S')
# output is 125503: Note that the hour rolled back as expected.
For MacOS users you can do the following:
$(date -v -10M +"%H:%M:%S")
Date time without a specific format:
$(date -v -10M)
For non-macOS users:
Date time without a specific format:
date --date '-10 min'

Resources