/* ------------------------------------------------------------------------ Compile Switches ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ Include Files ------------------------------------------------------------------------ */ #include #include #include #include #include #include extern int errno; /* ------------------------------------------------------------------------ Defines ------------------------------------------------------------------------ */ #define VERSION_STR "pdate 0.9" #define TIME_LEN 64 /* ------------------------------------------------------------------------ DEBUGGING MACROS ------------------------------------------------------------------------ */ #define WRITEMSG \ printf ("File %s line %d: ", __FILE__, __LINE__); \ printf ("errmsg <%s>\n", strerror(errno)); fflush(stdout); #define WRITEVAR(VAL,FMT) \ printf ("File %s line %d: ", __FILE__, __LINE__); \ printf ("%s=",#VAL); printf (#FMT, VAL); printf ("\n"); \ fflush(stdout); /* ------------------------------------------------------------------------ Macros ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ Typedefs ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ Global Variables ------------------------------------------------------------------------ */ extern int daylight; /* ------------------------------------------------------------------------ Module Wide Variables ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ Local Function Prototypes ------------------------------------------------------------------------ */ void Usage(void); long tosec (char *timestr); /* ------------------------------------------------------------------------ Main ------------------------------------------------------------------------ */ int main (int argc, char *argv[]) { char optchar; int nopt=0; int nscan=0; char *date_format = "%Y-%m-%d-%H:%M"; char *time_increment = NULL; char *rounding_time = NULL; char *initial_time = NULL; time_t current_time = 0; time_t standard_time = 0; time_t time_diff = 0; int isdst = 0; struct tm *ts = NULL; char timestr[TIME_LEN]; while (-1 != (optchar=getopt(argc,argv,"d:f:hi:r:t:v"))) { nopt++; switch (optchar) { case '?': return 1; /* Use daylight savings time */ case 'd': isdst = atoi(optarg); break; case 'h': Usage(); return 0; case 'v': printf ("%s (compiled %s)\n", VERSION_STR, __DATE__); return 0; case 'f': date_format = strdup(optarg); break; case 't': initial_time = strdup(optarg); break; case 'i': time_increment = strdup(optarg); break; case 'r': rounding_time = strdup(optarg); break; default: return 1; } } /* Read input time */ if (initial_time) { ts = (struct tm *) calloc (1, sizeof(struct tm)); nscan = sscanf (initial_time, "%d-%d-%d-%d:%d", &ts->tm_year, &ts->tm_mon, &ts->tm_mday, &ts->tm_hour, &ts->tm_min ); if (nscan==5) { } else { if (nscan<5) nscan = sscanf (initial_time, "%d-%d-%d", &ts->tm_year, &ts->tm_mon, &ts->tm_mday ); ts->tm_hour = 0; ts->tm_min = 0; } if (nscan<3) { perror ("Initial time is in unrecognized format\n"); exit (1); } /* Internal representation for year is measured from 1900 */ ts->tm_year -= 1900; /* Internal representation for month ranges from 0 to 11 */ ts->tm_mon -= 1; /* Should we respect daylight savings time ? */ /* For example, if isdst = -1 then for end of DST interval (2:00am Oct 29, 2000) `pdate -t 2000-10-29-01:30 -i30m` yields 2000-10-29-01:00 which is 30min *before* rather than *after* (-i30m should give 30minutes after) Setting isdst=0 gives 'expected' value, 200-10-29-02:00 */ ts->tm_isdst = isdst; current_time = mktime(ts); } else { current_time = time(NULL); } /* Round time */ if (rounding_time) { current_time -= current_time % tosec(rounding_time); } /* Increment time */ if (time_increment) { current_time += tosec(time_increment); } /* Print time */ ts = localtime(¤t_time); strftime (timestr, TIME_LEN, date_format, ts); printf ("%s\n", timestr); /* All done */ return 0; } /* ------------------------------------------------------------------------ Functions ------------------------------------------------------------------------ */ /* Convert strings of form 10s, 21m, 102h, 7d to seconds where letters smhd denote seconds, minutes, hours, days */ long tosec (char *timestr) { int length = strlen(timestr); int unitchar = tolower (timestr[length-1]); long unit; long time; switch (unitchar) { case 'd': unit = 60*60*24; break; case 'h': unit = 60*60; break; case 'm': unit = 60; break; case 's': unit = 1; break; default: perror ("Invalid time unit\n"); exit(1); } return unit * atol(timestr); } void Usage (void) { printf("\n"); printf(" pdate [-hfitv]\n"); printf("\n"); printf(" Prints date and time. Without arguments prints\n"); printf(" current time in format YYYY-mm-dd-HH:MM such as\n"); printf(" 2000-08-14-01:43\n"); printf("\n"); printf(" -d daylight savings time - default 0\n"); printf(" (see 'man ctime' for info on tm_isdst field)\n"); printf(" -h Print help.\n"); printf(" -f Format string for time.\n"); printf(" -i Adds (negative) increment to time.\n"); printf(" Append letter s,m,h,d for to use units of\n"); printf(" seconds, minutes, hours or days.\n"); printf(" -r Round time to previous interval using same\n"); printf(" units as above. This is done before\n"); printf(" increment is added. For example, if\n"); printf(" time is 12:41, the '-r 30min' option would\n"); printf(" round the time to 12:30\n"); printf(" -t Use specified date/time instead of current\n"); printf(" time, must be in format YYYY-mm-dd-HH:MM.\n"); printf(" -v Print version.\n"); printf("\n"); exit(0); }