I am using Sun OS, I want my script to read date from a file(in format %Y%m%d) and add 1 day to that date - date

I am working in Sun OS environment, I want to add a functionality to my existing unix ksh script where it allows to read a date(in %Y%m%d format) from a file and add 1 day and rewrite the same into that file. [please note: not adding day to current date instead i want to add 1 day to i/p date present in a file].
Eg:DateFile.dat
20200620
I want my script to change it to 20200621 at the end of run.
My code as below:
#!/bin/ksh
ip_dte</home/{file_Path}
echo $ip_dte
dte_add=`TZ=AEST-24 "$ip_dte"`
echo $dte_add

Something like that ? :
#!/bin/ksh
# Starting date, YYYYMMDD (yes I should verify the format :) )
FIRST_DATE=$1
[[ -z $FIRST_DATE ]] && FIRST_DATE=$(date +"%Y%m%d")
# 1 day in seconds
PERIOD=86400
# Transform the starting date in second and add 1 day
SECOND_DATE=$(( $(date -d "$FIRST_DATE" +"%s")+$PERIOD ))
# Transform the second date from second to human date format
print "Second date is $(date -d #"$SECOND_DATE" +"%Y%m%d")"

We can let date do the calculations and formatting for us:
$ date1='20200415'
$ date -d "${date1}+1 day" # add 1 day, use default output format
Thu Apr 16 00:00:00 UTC 2020
$date -d "${date1}+1 day" '+%Y%m%d' # add 1 day, change to YYYYMMDD format
20200416
$ date2=$(date -d "${date1}+1 day" '+%Y%m%d') # save new date in variable in YYYYMMDD format
$ echo "${date2}"
20200416
Here's a ksh fiddle of the above.

The other answers will work if you have ‎CSWcoreutils or SUNWgnu-coreutils installed. You may have to run gdate or /usr/gnu/bin/date.
But if you have a recent version of Solaris, ksh will be ksh93, and you can use the %T format in printf:
$ cat ddd
20200620
$ ip_dte=`cat ddd`
$ printf "%(%Y%m%d)T\n" "$ip_dte tomorrow"
20200621

If you have perl with the Time::Local module on the old Solaris server, try this:
#!/bin/ksh
ip_dte=20200531 # or read date from file into ip_dte
echo $ip_dte
timestamp=`perl -MTime::Local=timelocal -e '($y,$m,$d) = $ARGV[0] =~ /(\d\d\d\d)(\d\d)(\d\d)/; $m=$m-1; print timelocal(1,1,1,$d,$m,$y);' $ip_dte`
dte_add=`perl -MPOSIX=strftime -e 'print strftime("%Y%m%d", localtime($ARGV[0] +86400));' $timestamp`
echo $dte_add

Related

How to get Unix Time stamp as 00:00:00

Is there any command to get Timestamp as 00:00:00
Basically i need Current Date with Time stamp as 00:00:00 in unix
I tried
$(date '+%Y-%m-%d' 00:00:00)
But i need actual command in unix for it instead of appending 0
If you want a string in the format 2020-02-05 00:00:00 then how about just using echo to print the date output of the date command and then appending the time?
Like
echo "$(date '+%Y-%m-%d') 00:00:00"

How to convert a long date to short date from SSL certificates | Unix KSH

I'm wondering if is possible to convert a date as show Oct 31 00:00:00 2013 GMT to 10-31-2013.
I'm getting the date as follow:
NotBeforeDate=$(openssl x509 -noout -in ${CERTIFICATE} -dates | grep "notBefore")
The date that I'm getting is Oct 31 00:00:00 2013 GMT and I wanted to convert it to 10-31-2013.
There's any command that could do that? Or do I have to do it all manually?
If so, the best way is create my own function and send the long date as parameter and return a short date.
The openssl command will make the NotBeforeDate variable to have the value (at least in the bash version I'm using):
notBefore=Oct 31 00:00:00 2013 GMT
So, first we need to remove the notBefore= part:
dateStr=${NotBeforeDate/notBefore=/}
Then you can use the date command:
date --date="$dateStr" --utc +"%m-%d-%Y"
The --date option tells the command to use the dateStr value, --utc tells that the date is in UTC (as specified by GMT part) and +"%m-%d-%Y" formats the date to the desired format.
The output is:
10-31-2013
PS: the options can vary according to your Linux version.
You can check all the available ones with date --help or man date.
For example, the long options --date and --utc might not be available, but the equivalent short versions might be (just an example, I'm not sure if date command has such variations between different unix versions):
date -d "$dateStr" -u +"%m-%d-%Y"
Unfortunately I don't have the exact same environment you're using (ksh in unix), but that should work.
The -d options seems to be GNU specific, so if it's not available, you'll have to manually parse the string. Assuming that dateStr has the value Oct 31 00:00:00 2013 GMT, you can run:
printf '%s\n' "$dateStr" | awk '{ printf "%02d-%02d-%04d\n", (index("JanFebMarAprMayJunJulAugSepOctNovDec",$1)+2)/3, $2, $4}'
The output is:
10-31-2013
This script works for me when checking a url with certificate.
date --date="$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:$PORT | openssl x509 -noout -enddate | awk -F '=' '{print $NF}' )" --iso-8601
PORT is 443 by default.
Not to duplicate the explanations for the date command in previous answers, here's a compact Bash function that reads a certificate file and outputs either the start or end date in either ISO format or as a Unix timestamp (useful for integer comparison), and can be used on Linux or macOS:
# cert_date <date_type> <out_format> <cert_file> [openssl_opts...]
# date_type: start|end
# out_format: iso|unix
cert_date() {
local type=$1 out=$2 args date opts fmt
[ "$type" == start ] && args=(-startdate) || args=(-enddate)
date=$(openssl x509 "${args[#]}" -noout -in "${#:3}")
[[ "$OSTYPE" == darwin* ]] && opts=(-juf "%b %d %T %Y %Z") || opts=(-ud)
[ "$out" == unix ] && fmt="%s" || fmt="%Y-%m-%dT%TZ"
date "${opts[#]}" "${date/*=/}" +"$fmt"
}
Of course, you can enhance by changing fmt to suit your output format needs, and even add a case statement to accept more formats.
Examples:
cert_date start iso ${CERTIFICATE}
cert_date end unix ${CERTIFICATE} -inform der
I made a bash OneLiner from the ideas above. Maybe it is useful for somebody:
(Use 'cut -c 10-' when greeping notAfter)
date -d "`openssl x509 -dates -noout -in /path/to/cert.pem | grep notBefore | cut -c 11-`" +%Y.%m.%d
I know this post is old but I search how to convert date and especially the end date. And inspired by the command lines posted here I made this one :
date --date="$(echo | openssl x509 -noout -in my_file.crt -enddate | cut -d'=' -f 2)" --utc +'%Y-%m-%d %H:%M:%S'
Cutting is easier because as I only want the end date, I use the "enddate" parameter of the openssl command
In new version of openssl this option is build in:
openssl x509 -noout -in ${CERTIFICATE} -enddate -dateopt iso_8601
notBefore=2021-04-15 09:23:07Z
It returns date and time, however cutting the time part should be no challenge.
And it looks like, you really need the most recent version of openssl: --dateopt option does not work

take date from file in unix

I wanna take the date from a .txt file like this :
933|Mahinda|Perera|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox
1129|Carmen|Lepland|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer
4194|Hồ Chí|Do|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer
8333|Chen|Wang|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer
and compare it to a date that the user gives as input with this command :
./tool.sh --born-since <dateA> --born-until <dateB> -f <file>
and print out the lines with the dates between those who are input..
i use this code :
dateA= date -d "$2" +%Y%m%d
dateB= date -d "$4" +%Y%m%d
echo $2
awk -F'|' -v from=$2 -v to=$4 '{gsub("-","",$5);
gsub("-","",from); gsub("-","",to)}
from <= $5 && $5 <= to ' persons.dat.txt
but it just prints out :
19820529
20100101
1982-05-29
when i run
./tool.sh --born-since 1982-05-29 --born-until 1/1/2010
As far as I can tell in my brief experiment, you don't need the gsub since gawk can compare strings by lexical order (and if your dates are YYYY-MM-DD and LANG=C, lexical and date are the same).
So I ran
gawk -F'|' -v from='1982-05-29' -v to='2010-01-01' '(from<=$5) && ($5<=to)' persons.dat.txt
and got
933|Mahinda|Perera|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox
1129|Carmen|Lepland|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer
4194|Hồ Chí|Do|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer
which looks like what you want to me.
The rest of your code tries to assign to dateA and dateB, but doesn't use it anywhere. Also, it looks like you're missing a $() there: if your intention is to put the result of your date command into dateA, use dateA=$(date -d "$2" +%Y%m%d) though given that you have YYYY-MM-DD on file, dateA=$(date -d "$2" +%Y-%m-%d) look slike a better plan.

Calculating number of days given date in UNIX

I have tried to calculate number of days from January 1st to given date in same year.
Option -d for UNIX command isn't working
date -d
date: illegal option -- d
Usage: date [-u] [+format]
date [-u] [mmddhhmm[[cc]yy]]
date [-a [-]sss.fff]
I'm using this script but is too long.
Is there a simple way to calculate a nuber of days?
EDIT
Result of a script:
$ ksh datecalc -a 2013 2 5 - 2013 1 1
$ 35
OK so this may be a bit far fetched, but mysql client (or other DB clients) can come in handy for this as they have reliable and well documented date functions.
$ mysql ..... --silent -e "select datediff('2013-02-05', '2013-01-01') from dual;"
35
$
where ..... are your connection options.
If you have Perl installed, you can do:
perl -MPOSIX=strftime -le 'print strftime("%j",localtime)'
For a specific day, e.g. Feb 5:
perl -MPOSIX=strftime -le '
#d=(2013,2,5);
print strftime("%j",0,0,0,$d[2],$d[1]-1,$d[0]-1900)
'
036

How do I pass Shell parameters to Perl script?

I am trying to find dates with in a certain format, I have done it before with perl(strftime), but that time I mentioned a static time, this time i need a variable $CURRENT_DAY here.
Below is the issue, when equate the CURRENT_DAY by using DAYHOUR=86400 and an integer, the variable is giving the right time, but once I put $CURRENT_DAY variable in the statement, the date would not decrease.
$ DAYHOUR=86400
$ DAY=1
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'`
$ echo $DD
20
$ DAY=`echo $(($DAY+1))`
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ DD=`perl -e 'use POSIX; print strftime "%d", localtime time - $CURRENT_DAY;'`
$ echo $DD
20
$ DAY=`echo $(($DAY+1))`
$ echo $DAY
3
$ CURRENT_DAY=`echo $(($DAYHOUR*$DAY))`
$ echo $CURRENT_DAY
259200
$ echo `perl -e 'use POSIX; print strftime "%d", localtime time - 259200;'`
17
Your principal problem is that $CURRENT_DAY is a Perl script variable. By enclosing your Perl script in single quotes, there is no visibility to the shell's variable of the same name. Had you enabled warnings (e.g. with -w) you would have seen this.
There are a couple of ways to circumvent your problem. One is to use double quotes to encapsulate your Perl thus allowing the shell to first expand its variable's value before the Perl is run:
CURRENT_DAY=3
perl -MPOSIX -wle "print strftime qq(%d),localtime time-(86400*$CURRENT_DAY);print $CURRENT_DAY"
17
Another is:
export CURRENT_DAY=3
perl -MPOSIX -wle 'print strftime qq(%d),localtime time-(86400*$ENV{CURRENT_DAY})'
Be advised that adding or subtracting 24-hours from a time to calculate yesterday or tomorrow will not correctly account for daylight saving changes. See this faq
You may pass them as arguments in #ARGV:
$ dd_seconds_ago () { perl -MPOSIX -e 'print strftime q(%d), localtime(time - shift)' "$#"; }
$ DD=$(dd_seconds_ago 86400)
Without an argument and in the above context, shift shifts #ARGV, which is handy for shell one-liners like this
Like Perl, sh doesn't interpolate in single quoted strings, so Perl sees $CURRENT_DAY instead of the actual number, and you've never assigned anything to that Perl variable. You could switch to a double-quoted string.
perl -MPOSIX -e"print strftime '%d', localtime time-$CURRENT_DAY;"
That's fine since $CURRENT_DAY is a number, but if you wanted to pass an arbitrary string, you'd use an env var or an argument.
export CURRENT_DAY
perl -MPOSIX -e'print strftime "%d", localtime time-$ENV{CURRENT_DAY};'
or
perl -MPOSIX -e'print strftime "%d", localtime time-$ARGV[0];' -- "$CURRENT_DAY"
Note that your code is buggy, though. There are two hours every year for which your code will give the wrong answer because not all days have 86400 seconds. Some have 82800, and others have 90000. (And that's assuming leap seconds don't factor in.) A Perl solution that doesn't suffer from that problem follows:
perl -MDateTime -e'print
DateTime->today(time_zone=>"local")
->subtract(days=>$ARGV[0])
->strftime("%d")' -- "$DAY"
Or you could use date.
date -d "$DAY days ago" +%d
I am assuming you want to pass the number of days in the past in the shell variable DAY and that you want the answer in the shell variable DD
So if it is the 20th of the month and the DAY is 1, then DD should be set to 19
You could modify your Perl command as follows:
DD=`perl -e 'use POSIX; print strftime "%d", localtime( time - ($ENV{DAY}* 86400))';
Alternatively, you could use the GNU date command that is widely available
DD=`date -d "$DAY days ago" +%d`
Using date is probably better at dealing with leap days, etc