Walker News

Date Arithmetic In Linux Shell Scripts

How to write a Linux shell scripts that backup previous month data files on monthly basis? Of course, it involves date time calculation! Unless you’re using GNU Coreutils / GNU date, doing date arithmetic in shell scripts will not be that straight-forward as a novice think!

I just can’t recall that SCO Unix and Concurrent Real Time Unix (RTU) have GNU date installed, when I was exposed to Unix for the first time in year 2000. But, I believe that GNU Coreutils is a standard package that available on most Linux distributions as of today.

How to do date arithmetic in Linux shell scripts using GNU date command?

GNU date is one of the many common Linux programs in GNU Coreutils package. Here are some of the examples of performing date time arithmetic with GNU date command, using -d or --date option switch:

Return as last month in numeric format
date -d "last month" +%m

Return as last month in abbreviated month name
date -d "2 month ago" +%b

Return as last month in full month name
date -d "-2 month" +%B

Returns previous hour in 24-hours format (00-23)
date -d "-1 hours" +%H

Return the date and time of tomorrow
date -d "tomorrow"

Return the date of yesterday in dd MMM yy
date -d "yesterday" +"%d %B %y"

Return last week in abbreviated weekday name
date -d "last week" +%a

To avoid getting result of “July” when executing date -d "-1 month" +%B on 31 July 2006, because “2006-07-31 -1 month” might evaluate to 2006-07-01, because 2006-06-31 is an invalid date!
date -d "$(date +%Y-%m-15) -1 month" +'Last month was %B!'

Return the Unix Epoch time (the total seconds elapse since midnight of 1970-01-01), which is 1 secs in this case.
date -d "1970-01-01 00:00:01 UTC" +%s

Return the literal date format of the given Unix Epoch time.
date -d "1970-01-01 1234567890 sec" +"%F %T %z"

Isn’t it easier for date time calculation related shell scripts with GNU date installed? As said just now, GNU date is not a standard command in Unix variants.

In case GNU date is not available, you might need to write a rather long shell scripts to accommodate some simple date time calculations. Potentially, it could end up as a messy or hard to maintain shell scripts!

In case GNU Coreutils / GNU Date is not installed, you can write a simple C program in few lines of source code to satisfy the date arithmetic in shell scripts! The compiled C program is highly portable among Unix / Linux variants, as the date arithmetic library (time.h) is a standard C library!

How to write and compile a simple date arithmetic C program?

To compile the C program source code using GCC compiler, the general syntax for these simple source code is
gcc -o program_name program_source_code.c

For C/C++ tutorial or standard C/C++ library reference, I’m referring to cplusplus.com

Calculate the nth-day from today:
#include <stdio.h>
#include <time.h>

#define c_DaySecs 86400

int main (int argc, char ** argv)
{
   int Day;
   time_t TotSec;
   struct tm * TimeStruct;

   if ( argc != 2 )
   {
      printf("Syntax\n\t%s nth-Day\n",argv[0]);
      return 1;
   }
   else
   {
      Day = atoi( argv[1] );
      TotSec = time( NULL );
		
      TotSec = TotSec + ( Day * c_DaySecs );
      TimeStruct = localtime( &TotSec );

      printf("%i days is %s",Day,ctime(&TotSec));
      printf("%i days is %i-%i-%i\n", \
      Day, TimeStruct->tm_mday, \
      TimeStruct->tm_mon + 1, \
      TimeStruct->tm_year + 1900 );

      TimeStruct = NULL;

      return 0;
   }
}

Return the literal date of a given Unix Epoch time:
#include <stdio.h>
#include <time.h>

int main (int argc, char ** argv)
{
   time_t TimeNow;
   struct tm * TimeStruct;
	
   if ( argc < 2 || argc > 3)
   {
      printf("Syntax\n\t%s SEC FLAG\n",argv[0]);
      return 1;
   }
   else
   {
      TimeNow = atoi( argv[1] );

      if (argv[2] == NULL || atoi( argv[2] ) == 0)
      {
         TimeStruct = localtime( &TimeNow );
         printf( "%s in Local Timezone is %s", \
            argv[1], asctime( TimeStruct ) );
      }
      else
      {
         TimeStruct = gmtime( &TimeNow );
         printf( "%s in GMT is %s", \
            argv[1], asctime( TimeStruct ) );
      }

      return 0;
   }
}

To convert a give literal date to Unix Epoch Time (total seconds elapsed since midnight of 1970-01-01):
#include <stdio.h>
#include <time.h>

int main (int argc, char ** argv)
{
   int DD, MM, YYYY = 0;
   time_t TimeNow;
   struct tm * TimeStruct;
	
   if ( argc != 4 )
   {
      printf("Syntax\n\t%s DD MM YYYY\n",argv[0]);
      return 1;
   }
   else
   {
      DD = atoi( argv[1] );
      MM = atoi( argv[2] );
      YYYY = atoi( argv[3] );
      TimeNow = time( NULL );
      TimeStruct = localtime( &TimeNow );

      TimeStruct->tm_year = YYYY - 1900;
      TimeStruct->tm_mon = MM - 1;
      TimeStruct->tm_mday = DD;
		
      TimeNow = mktime( TimeStruct );
		
      printf( "%ld\n", TimeNow );	
      return 0;
   }
}


Custom Search

  1. CSS Hack Wraps Long Text In Pre Tag » Walker News 18-06-07@14:28

    […] these glitches perfectly!. Knowing that limitation, but without Googling for a trick, I posted a Date-Time calculation C program source code, with the first method! Imagine how stupid I was, to replace tonnes of &nbsp; in the C program […]

  2. Resolve Linux Shell Scripts Bad Interpreter Error – Walker News 03-08-07@16:02

    […] to different way of handling text file encoding, a Linux shell scripts might not working after transferring from one OS to another, in particularly from Windows to […]

  3. Using Linux od Command To View File In Bit – Walker News 21-09-07@00:13

    […] files in binary form or bit level (i.e. 0 and 1), fix Bad Interpreter error message when executing Linux Bash shell scripts, […]

  4. GNU Coreutils: GNU Date Is Easier For Date Time Calculation In Linux Shell Script – Walker News 29-08-08@23:47

    […] mentioned about date time calculation shell script in an earlier post. Though, the GNU date examples related to Unix Epoch time (a.k.a. Unix time, […]

  5. Amin Yuliastanto 21-11-08@17:26

    thank you for your examples, I just noticed that :D

  6. MT 29-08-09@05:43

    Thank you very much, it is helpful resouce.

  7. Marcus Friedman | ellipsys… 14-12-09@07:08

    Thank you very much for having shared this. It was something that I needed to do in a hurry, and your post really saved my day.

    Keep up the good work.

    Best regards,
    Marcus

  8. Dominique 31-08-11@21:40

    Simply awsome!

2014  •  Privacy Policy