subtract minutes from time

i have the time 20100421043335 in format (date +%Y%m%d%H%M%S),and i want to be able to get the previous time 2 minutes ago,which is

20100421043135

if you have GNU date

D="20100421043335"
date -d "${D:0:8} ${D:8:2}:${D:10:2}:${D:12:2} 2 minutes ago"

Frans,
i am having difficulty using it in a script.
Please how do i go about it

type

date -d "now 2 minutes ago"

if that works : you have GNU date and the snippet should work.
For use it in a script, show us first how your script looks like.

Frans,
my script looks like this

#!/bin/ksh
D=`date +%Y%m%d%H%M%S`
D1=`date -d "now 2 minutes ago"`
echo $D1

But it does not work for me. i need D1 to be 2 minutes ago

If you are using ksh93 the following works

printf "%(%Y%m%d%H%M%S)T" "${D:0:4}-${D:4:2}-${D:6:2} ${D:8:2}:${D:10:2}:${D:12:2} 2 minutes ago"

If neither GNU date or ksh93 are available to you the following short C utility will do the job
(see usage string for arguments):

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>


int
main(int argc, char* argv[])
{
   struct tm tm1, *tm2;

   char buf[80];
   char format[50];
   char tmp[80];
   char date[80];
   char seconds[10];
   char *s, *d;

   time_t t1, t2;

   int c;
   int debug = 0;
   int errflg = 0;

   extern char *optarg;
   extern int optind, optopt;

   while ((c = getopt(argc, argv, "dh")) != -1) {
        switch(c) {
        case 'd':
            debug = 1;
            break;
        case 'h':
            errflg++;
            break;
        case '?':
            fprintf(stderr, "Unknown option: -%c\n", optopt);
            errflg++;
        }
   }
   if (errflg || (argc < 2)) {
       fprintf(stderr, "Usage: subtime [-d] datestr seconds\n");
       exit(1);
   }

   strcpy(tmp, argv[optind]);
   optind++;
   strcpy(seconds, argv[optind]);

   strcpy(format, "%Y %m %d %H %M %S");

   /* reformat date string to place a space betwen each token */
   /* strptime specification requires a space */
   s = tmp;
   d = date;
   c = 0;
   while(*s) {
      if (c == 4 || c == 6 || c == 8 || c == 10 || c == 12 || c == 14) {
         *d++ = ' ';
      }
      c++;
      *d++ = *s++;
   }
   *d = '\0';

   if (debug) {
       fprintf(stderr, "Format: %s\n", format);
       fprintf(stderr, "Date: %s\n", date);
       fprintf(stderr, "Seconds: %s\n", seconds);
   }

   if (!strptime(date, format, &tm1)) {
       fprintf(stderr, "strptime() error\n");
       exit(1);
   }
   strftime(buf, 50, "%a %Y %H:%M:%S", &tm1);

   if ((t1 = mktime(&tm1)) == -1) {
      fprintf(stderr, "mktime() error\n");
      exit(1);
   }

   t1 = t1 - atoi(seconds);
   tm2 = localtime(&t1);

   if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", tm2) == 0) {
      fprintf(stderr, "strftime() error\n");
      exit(1);
   }

   printf("%s", buf);

   exit(0);
}

i dont seem to get the printf code working.
may be you can help by completing the code i sent,so i can echo out the new date.

This probably is related to the other question you asked, and since you've used Perl in the other one, I guess you can solve this problem by using the Date::Calc Perl module -

perl -M"Date::Calc qw(:all)" -le '$x="20100421043335"; printf("%4d%02d%02d%02d%02d%02d\n",Add_Delta_DHMS(unpack("A4A2A2A2A2A2",$x),0,0,-2,0))'

Test run:

$
$
$ perl -M"Date::Calc qw(:all)" -le '$x="20100421043335"; printf("%4d%02d%02d%02d%02d%02d\n",Add_Delta_DHMS(unpack("A4A2A2A2A2A2",$x),0,0,-2,0))'
20100421043135
$
$

tyler_durden

how do i get or start using the date cal per module

From the one-and-only stop aka CPAN (the Comprehensive Perl Archive Network, in case you didn't know).

Installing CPAN Modules

tyler_durden

Ok, that was the short answer.

I don't know what OS you are on, but if it's a Linux flavor or Windows, then it's pretty easy. CPAN, besides the website, is a Perl module as well and is packaged as an rpm or deb file for Linux. You can use your Linux flavor's package-manager program (yum, apt-get, yast etc.) to install cpan. Once it is done, log in as root and run the cpan command, which opens up the cpan shell. Installing any Perl module from there is just a matter of firing the "install <module_name>" command.

Windows is easier than that. ActiveState has its own package-manager for Perl called "ppm". It's a graphical tool and extremely easy to navigate. You fire it up with the "ppm" command. To install a module, select it from the list and click on the "Install" button. (I've never used Strawberry Perl on Windows, so can't comment on that.)

If you cannot install by either of these methods, then life would be tough. You'll have to build and compile from the sources, and I'd suggest you talk to your SysAdmin about it.

HTH,
tyler_durden