Reputation: 187
I need to get last month date in format YYYY-MM-DD, suppose if run script in May on any date then it should return me Last date of April month in format 2018-04-30.
Would be good if can get the same work done with awk statement also.
I tried below code and able to get output in below form but i need in format YYYY-MM-DD
Apr 30 2018
Code:
#!/bin/bash
cur_month=`date +%m`
cur_year=`date +%Y`
prev_month=$(($cur_month-1))
# Check to see if this is January
if [ $prev_month -lt 1 ]
then
prev_year=$(($cur_year-1))
prev_month=12
LastDayOfpreviousMonth=`cal $prev_month $cur_year | grep -v "^$" | sed -n '1p;$p' | tr "\n" " " | awk '{print substr($1,1,3),$NF,$2}'`
else
LastDayOfpreviousMonth=`cal $prev_month $cur_year | grep -v "^$" | sed -n '1p;$p' | tr "\n" " " | awk '{print substr($1,1,3),$NF,$2}'`
fi
echo $LastDayOfpreviousMonth
Input file: In this file in column14 need to put value of date for last month in form YYYY-MM-DD(2018-04-30)
EPOS|EPOS_OUTWARD_B2B_OSR_TTML_TTSL_$LDPM_20180504_V1.0.txt|||AD|Outward|ANP|Receipt cum invoice|42018|37AAACT2438A1ZS|INV|TAX|IN37201800001452|2018-04-17||||1||||SOHANRAJ RAJ KUMAR||||37||||||9984||Telecommunication services||||300|0||9|27|9|27|||||354||||||||||
EPOS|EPOS_OUTWARD_B2B_OSR_TTML_TTSL_$LDPM_20180504_V1.0.txt|||AD|Outward|ANP|Receipt cum invoice|42018|37AAACT2438A1ZS|INV|TAX|IN37201800001426|2018-04-12||||1||||MOLLITE SIVARAMA KRISHNA||||37||||||9984||Telecommunication services||||300|0||9|27|9|27|||||354||||||||||
EPOS|EPOS_OUTWARD_B2B_OSR_TTML_TTSL_$LDPM_20180504_V1.0.txt|||GJ|Outward|GUJ|Receipt cum invoice|42018|24AAACT2438A1ZZ|INV|TAX|IN24201800000651|2018-04-07||||1||||AIREN LTD ||||24||||||9984||Telecommunication services||||500|0||9|45|9|45|||||590||||||||||
Upvotes: 2
Views: 1608
Reputation: 26471
Even though it is evident that the OP's dateformat is unix based, it is worth mentioning that there are two general calendars in play. The Julian calendar and the Gregorian calendar. Both calendars have a different concept of what a leap year is.
note: at this time, most countries adopt the Gregorian calendar. However, it was not at once officially adopted by all countries. This should be kept in mind when making historical research. In Great Britain, for instance , the change was made as late as in A.D. 1752, and in Turkey not before 1927. (Ref Astronomical Algorithms by Jean Meeus)
With this in mind, and depending whether your digital file is from Turkey from 1920 or 2011 or Great Britain from 1740 or 1789, I present two awk
solutions
In a leap year, the month February has 29 days, where in a common year it has 28 days.
In the Julian calendar, a year is a leap (or bissextile) year of 366 days if its numerical designation is divisible by 4. All other years are common years (365 days).
Using awk
, as this was the OP's request, we can write the following function that would do the requested conversion :
awk 'function julian(str, y,m,d) {
y=substr(str,1,4); m=substr(str,6,2)+0;
if (m==1) {y=y-1; m=12} else {m=m-1}
if (((m-1)%7)%2==0) {d=31} else {d=30}
if (m==2) { d = (y%4==0) ? 29 : 28 }
return sprintf("%0.4d-%0.2d-%0.2d",y,m,d)
}
{ print $14, julian($14) }' <file>
In the Gregorian calendar, the same rule holds as in the Julian calendar, with the following exception: the centurial years that are not divisible by 400 are common years.
awk 'function gregorian(str, y,m,d) {
y=substr(str,1,4); m=substr(str,6,2)+0;
if (m==1) {y=y-1; m=12} else {m=m-1}
if (((m-1)%7)%2==0) {d=31} else {d=30}
if (m==2) { d = (y%4!=0) ? 28 : (y%100==0 && y%400!=0 ? 28 : 29 ) }
return sprintf("%0.4d-%0.2d-%0.2d",y,m,d)
}
{ print $14, gregorian($14) }' <file>
As the UNIX calendar is Gregorian, we can also use the GNU Awk Time Functions. This however will only work from 1970-02-01 till 2038-01-19 for 32-bit systems and 292277026596-04-01 for 64-bit systems (see here)
awk 'function unix(str, tmp) {
tmp=substr(str,1,7)" 01 00 00 00"; gsub("-"," ",tmp);
return strftime("%Y-%m-%d",mktime(tmp) - 1) }
{ print $14, unix($14) }' <file>
Upvotes: 0
Reputation: 3449
GNU date itself is capable of handling this task perfectly and reliably, no need for other magic.
$ date -d "$(date +%Y-%m-01) - 1 day" "+%Y-%m-%d"
2018-04-30
Upvotes: 3