// // mjdsed - Replace "ctime" strings with MJD time stamps and prepend MJD to all lines. // // 24 Mar 2008 /tvb // #include #include #include #include #include #include #include int ctime_like (char *s); double ctime_to_mjd (char *s); // // Read stdin, substitude any ctime strings with MJD time stamps, write stdout. // void main (int argc, char *argv[]) { long count; char line[1000], *p; char buf[24 + 1]; double mjd; count = 0; mjd = 0.0; while (fgets(line, sizeof line, stdin) != NULL) { // Extract date/time from line and set new MJD. for (p = line; p <= line + strlen(line); p += 1) { if (ctime_like(p)) { buf[24] = '\0'; mjd = ctime_to_mjd(p); sprintf(buf, "--- MJD %12.6lf ---", mjd); assert(strlen(buf) == 24); // fprintf(stderr, "%d=strlen(%s) != 24\n", strlen(buf), buf); memcpy(p, buf, 24); count += 1; break; } } // Prepend MJD to all lines. fprintf(stdout, "%.6lf ", mjd); fputs(line, stdout); } fprintf(stderr, "%ld ctime substitutions\n", count); } // // Look for something like: "Mon Mar 24 11:25:41 2008" // int ctime_like (char *s) { // This is a pretty good but not perfect check. return strlen(s) >= 24 && isupper(*s++) && islower(*s++) && islower(*s++) && ' ' == *s++ && isupper(*s++) && islower(*s++) && islower(*s++) && ' ' == *s++ && isdigit(*s++) && isdigit(*s++) && ' ' == *s++ && isdigit(*s++) && isdigit(*s++) && ':' == *s++ && isdigit(*s++) && isdigit(*s++) && ':' == *s++ && isdigit(*s++) && isdigit(*s++) && ' ' == *s++ && isdigit(*s++) && isdigit(*s++) && isdigit(*s++) && isdigit(*s++); } // // Convert UTC ctime string to floating point MJD. // #define UNIX_TIME_TO_MJD(t) ( MJD_1970_01_01 + ((t) / 86400.0) ) #define MJD_1970_01_01 40587 double ctime_to_mjd (char *s) { static char month[12][3] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; int n; time_t t; struct tm tm; char wday[4], mon[4]; // Parse ctime string. n = sscanf(s, "%3s %3s %d %d:%d:%d %d", wday, mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year); // Set fields. if (n == 7) { tm.tm_year -= 1900; tm.tm_isdst = -1; for (tm.tm_mon = 0; tm.tm_mon <= 11; tm.tm_mon += 1) { if (strncmp(mon, month[tm.tm_mon], 3) == 0) { // Month matches; compute unix time_t and then MJD. t = mktime(&tm); return UNIX_TIME_TO_MJD(t); } } } return 0.0; }