/* Advance to time indicated by timestring, of the format "HH:MM". */ TimedAdvance::TimedAdvance(std::string timestring, uint16 r) : TimedCallback(NULL, NULL, 1000/TIMEADVANCE_PER_SECOND, true), clock(Game::get_game()->get_clock()), minutes_this_hour(0), minutes(0) { uint8 hour = 0, minute = 0; get_time_from_string(hour, minute, timestring); // set stop time // set number of hours and minutes to advance uint16 advance_h = (clock->get_hour() == hour) ? 24 : (clock->get_hour() < hour) ? (hour-clock->get_hour()) : (24-(clock->get_hour()-hour)); uint16 advance_m; if(clock->get_minute()<=minute) advance_m = minute - clock->get_minute(); else { advance_m = (60 - (clock->get_minute()-minute)); if(advance_h > 0) advance_h -= 1; else advance_h = 23; } // go init((advance_h * 60) + advance_m, r); }
bool cdkey_ban_list::banned_client::load(CInifile* ini, shared_str const & name_sect) { if (!ini->line_exist(name_sect, CLIENT_HEX_DIGEST_KEY) || !ini->line_exist(name_sect, CLIENT_BAN_END_TIME_KEY)) { return false; } client_hexstr_digest = ini->r_string(name_sect, CLIENT_HEX_DIGEST_KEY); LPCSTR tmp_string = ini->r_string(name_sect, CLIENT_BAN_END_TIME_KEY); ban_end_time = get_time_from_string(tmp_string); if (ban_end_time == 0) { Msg("! ERROR bad ban_end_time in section [%s]", name_sect.c_str()); return false; } tmp_string = ini->r_string(name_sect, CLIENT_BAN_START_TIME_KEY); if (tmp_string) ban_start_time = get_time_from_string(tmp_string); tmp_string = ini->r_string(name_sect, CLIENT_NAME_KEY); if (tmp_string) client_name = tmp_string; tmp_string = ini->r_string(name_sect, CLIENT_IP_KEY); if (tmp_string) client_ip_addr.set(tmp_string); tmp_string = ini->r_string(name_sect, ADMIN_NAME_KEY); if (tmp_string) admin_name = tmp_string; tmp_string = ini->r_string(name_sect, ADMIN_IP_KEY); if (tmp_string) admin_ip_addr.set(tmp_string); tmp_string = ini->r_string(name_sect, ADMIN_HEX_DIGEST_KEY); if (tmp_string) admin_hexstr_digest = tmp_string; return true; }
int main( int argc, char **argv) { FILE *ifile = fopen( argc == 1 ? "get_test.txt" : argv[1], "rb"); if( ifile) { char buff[80]; double jd = 0; int i; unsigned time_format = 0; setvbuf( stdout, NULL, _IONBF, 0); while( fgets( buff, sizeof( buff), ifile)) { for( i = 0; buff[i] >= ' '; i++) ; buff[i] = '\0'; if( !memcmp( buff, "format", 6)) { sscanf( buff + 6, "%x", &time_format); printf( "%s\n", buff); } else if( *buff != ';') { char obuff[80]; int is_ut; jd = get_time_from_string( jd, buff, (int)time_format, &is_ut); full_ctime( obuff, jd, FULL_CTIME_MILLISECS | CALENDAR_JULIAN_GREGORIAN); printf( "%s %d %s\n", obuff, is_ut, buff); } else printf( "%s\n", buff); } fclose( ifile); } return( ifile ? 0 : -1); }
int main( const int argc, const char **argv) { char tbuff[300], mpc_code[20]; char **summary_lines = NULL; const char *separate_residual_file_name = NULL; const char *mpec_path = NULL; int n_ids, i, starting_object = 0; int n_processes = 1; OBJECT_INFO *ids; int total_objects = 0; FILE *ifile; extern int process_count; int n_lines_written = 0; FILE *summary_ofile = NULL; extern int forced_central_body; extern int use_config_directory; /* miscell.c */ int element_precision = 5; bool all_heliocentric = true; bool use_colors = true; bool show_processing_steps = true; int ephemeris_output_options = OPTION_SHOW_SIGMAS | OPTION_ROUND_TO_NEAREST_STEP; time_t update_time, t0; double ephem_end_jd = 0.; extern bool is_default_ephem; bool drop_single_obs = true; const char *ephem_option_string = NULL; #ifdef FORKING int child_status; #endif if( !strcmp( argv[0], "fo")) use_config_directory = true; else use_config_directory = false; *mpc_code = '\0'; for( i = 1; i < argc; i++) /* check to see if we're debugging: */ if( argv[i][0] == '-') { const char *arg = get_arg( argc, argv, i); switch( argv[i][1]) { case 'a': { extern int separate_periodic_comet_apparitions; separate_periodic_comet_apparitions ^= 1; } break; case 'b': separate_residual_file_name = arg; break; case 'c': { extern int combine_all_observations; combine_all_observations = 1; } break; case 'C': strlcpy( mpc_code, arg, sizeof( mpc_code)); break; case 'd': debug_level = atoi( arg); if( !debug_level) debug_level = 1; debug_printf( "fo: debug_level = %d; %s %s\n", debug_level, __DATE__, __TIME__); break; case 'e': { extern const char *ephemeris_filename; ephemeris_filename = arg; is_default_ephem = false; } break; case 'E': ephem_option_string = arg; break; case 'f': /* obj desig specified; fall through */ break; case 'h': /* show planet-centric orbits */ all_heliocentric = false; break; #ifdef FORKING case 'k': unlink_partial_files = false; break; #endif case 'i': { extern int ignore_prev_solns; ignore_prev_solns = 1; } break; case 'm': mpec_path = arg; break; case 'M': { extern const char *mpcorb_dot_sof_filename; mpcorb_dot_sof_filename = arg; } break; case 'n': starting_object = atoi( arg); break; case 'O': /* write output files to specified dir */ { extern const char *output_directory; output_directory = arg; } break; case 'o': /* obj designation / ephemeris from orbital */ break; /* elems: fall through, handle below */ case 'p': { FILE *ifile = fopen_ext( "dummy.txt", "tfcw"); fclose( ifile); n_processes = atoi( arg); } break; case 'q': /* "quiet" */ show_processing_steps = false; break; #ifdef FORKING case 'r': { /* set 'soft' & 'hard' limits for CPU */ struct rlimit r; /* run time, in seconds, to avoid */ int soft_limit, hard_limit; /* runaway processes */ if( sscanf( arg, "%d,%d", &soft_limit, &hard_limit) == 2) { r.rlim_cur = (rlim_t)soft_limit; r.rlim_max = (rlim_t)hard_limit; setrlimit( RLIMIT_CPU, &r); } } break; #endif case 's': sanity_test_observations( argv[1]); printf( "Sanity check complete\n"); return( 0); case 'S': { char curr_time[50]; full_ctime( curr_time, current_jd( ), FULL_CTIME_YMD); summary_ofile = fopen( arg, "wb"); assert( summary_ofile); ifile = fopen_ext( "summ.htm", "fcrb"); assert( ifile); while( fgets( tbuff, sizeof( tbuff), ifile)) { text_search_and_replace( tbuff, "%TIME%", curr_time); fputs( tbuff, summary_ofile); } fclose( ifile); } break; case 't': if( argv[i][2] == 'e' || argv[i][2] == 'E') { double jd = get_time_from_string( curr_jd( ), argv[i] + 3, CALENDAR_JULIAN_GREGORIAN | FULL_CTIME_YMD | FULL_CTIME_TWO_DIGIT_YEAR, NULL); if( argv[i][2] == 'e') ephem_end_jd = jd; else { extern double override_epoch_shown; override_epoch_shown = jd; } } else total_objects = atoi( arg); break; case 'v': use_colors = false; break; case 'z': use_config_directory = true; break; default: printf( "Unknown command-line option '%s'\n", argv[i]); return( -1); } } for( i = 1; i < argc; i++) { const char *tptr = strchr( argv[i], '='); if( tptr && argv[i][0] != '-') { const size_t len = tptr - argv[i]; memcpy( tbuff, argv[i], len); tbuff[len] = '\0'; set_environment_ptr( tbuff, argv[i] + len + 1); } } /* get_defaults( ) collects a lot of data that's for the */ /* interactive find_orb program. But it also sets some */ /* important internal values for blunder detection, etc. */ /* So we still call it: */ get_defaults( &ephemeris_output_options, NULL, &element_precision, NULL, NULL); if( all_heliocentric) forced_central_body = 0; if( ephem_option_string) ephemeris_output_options = (int)parse_bit_string( ephem_option_string); load_up_sigma_records( "sigma.txt"); if( debug_level) debug_printf( "%d sigma recs read\n", i); if( argc < 2) { printf( "'fo' needs the name of an input file of MPC-formatted\n"); printf( "astrometry as a command-line argument.\n"); return( -2); } if( reset_astrometry_filename( argc, argv)) drop_single_obs = false; ids = find_objects_in_file( argv[1], &n_ids, NULL); if( n_ids <= 0) { /* no objects found, or file not found */ const char *err_msg; if( n_ids == -1) err_msg = "Couldn't locate the file"; else err_msg = "No objects found in file"; printf( "%s '%s'\n", err_msg, argv[1]); return( -1); } if( drop_single_obs) n_ids = remove_single_observation_objects( ids, n_ids); if( show_processing_steps) printf( "Processing %d objects\n", n_ids); if( !total_objects) total_objects = n_ids; t0 = update_time = time( NULL); #ifdef FORKING while( process_count < n_processes - 1) { const pid_t childpid = fork( ); if( childpid == -1) /* fork( ) returns -1 on failure */ { perror("fork"); /* display error message */ exit(0); } else if( childpid == 0) /* we're a child process */ { // printf( "Hi! I'm child %d. My PID is %d; parent's is %d\n", // process_count, getpid( ), getppid( )); } else break; /* break out of loop, signalling we're a parent */ process_count++; } if( n_processes > 1) process_count++; if( show_processing_steps) printf( "Process count %d\n", process_count); #endif if( summary_ofile) summary_lines = (char **)calloc( n_ids - starting_object + 1, sizeof( char *)); ifile = fopen( argv[1], "rb"); if( total_objects > n_ids - starting_object) total_objects = n_ids - starting_object; for( i = starting_object; i < starting_object + total_objects; i++) if( n_processes == 1 || i % n_processes == process_count - 1) { const char *orbit_constraints = ""; OBSERVE FAR *obs; const int n_obs = ids[i].n_obs; if( n_processes == 1 && show_processing_steps) printf( "%d: %s", i + 1, ids[i].obj_name); if( n_obs < 2 && drop_single_obs) printf( "; skipping\n"); else { extern int append_elements_to_element_file; extern int n_obs_actually_loaded; extern char orbit_summary_text[]; long file_offset = ids[i].file_offset - 40L; int element_options = ELEM_OUT_ALTERNATIVE_FORMAT; double epoch_shown, curr_epoch, orbit[12]; if( all_heliocentric) element_options |= ELEM_OUT_HELIOCENTRIC_ONLY; /* Start a bit ahead of the actual data, just in case */ /* there's a #Sigma: or similar command in there: */ if( file_offset < 0L) file_offset = 0L; fseek( ifile, file_offset, SEEK_SET); obs = load_object( ifile, ids + i, &curr_epoch, &epoch_shown, orbit); if( (n_obs_actually_loaded > 1 || !drop_single_obs) && curr_epoch > 0.) { int n_obs_included = 0; unsigned j = 0; write_out_elements_to_file( orbit, curr_epoch, epoch_shown, obs, n_obs_actually_loaded, orbit_constraints, element_precision, 0, element_options); strcpy( tbuff, orbit_summary_text); if( use_colors) colorize_text( tbuff); if( show_processing_steps) { if( n_processes > 1) { if( process_count == 1 && time( NULL) != update_time) { int elapsed, n_done = i - starting_object + 1; update_time = time( NULL); elapsed = (int)update_time - (int)t0; printf( "%d seconds elapsed, %d remain\n", elapsed, elapsed * (total_objects - n_done) / n_done); } printf( "(%d) %d: %s", process_count, i + 1, ids[i].obj_name); } printf( "; %s ", tbuff); } if( separate_residual_file_name) { extern bool residual_file_in_config_dir; residual_file_in_config_dir = false; write_residuals_to_file( separate_residual_file_name, argv[1], n_obs_actually_loaded, obs, RESIDUAL_FORMAT_PRECISE | RESIDUAL_FORMAT_COMPUTER_FRIENDLY | RESIDUAL_FORMAT_FOUR_DIGIT_YEARS | RESIDUAL_FORMAT_EXTRA); residual_file_in_config_dir = true; } if( !mpec_path) append_elements_to_element_file = 1; if( mpec_path || !is_default_ephem) { int n_orbits_in_ephem = 1; int n_ephemeris_steps = 50; char ephemeris_step_size[20]; extern const char *ephemeris_filename; extern const char *residual_filename; extern int available_sigmas; extern double ephemeris_mag_limit; double *orbits_to_use = orbit; const double jd_start = get_time_from_string( curr_jd( ), get_environment_ptr( "EPHEM_START"), CALENDAR_JULIAN_GREGORIAN | FULL_CTIME_YMD | FULL_CTIME_TWO_DIGIT_YEAR, NULL); sscanf( get_environment_ptr( "EPHEM_STEPS"), "%d %9s", &n_ephemeris_steps, ephemeris_step_size); if( ephem_end_jd) { n_ephemeris_steps = 1; snprintf( ephemeris_step_size, sizeof( ephemeris_step_size), "%f", ephem_end_jd - jd_start); } if( !*mpc_code) sscanf( get_environment_ptr( "CONSOLE_OPTS"), "%9s", mpc_code); create_obs_file( obs, n_obs_actually_loaded, 0); ephemeris_mag_limit = 999.; if( available_sigmas == COVARIANCE_AVAILABLE) { n_orbits_in_ephem = 2; compute_variant_orbit( orbit + 6, orbit, 1.); } if( available_sigmas == SR_SIGMAS_AVAILABLE) { extern double *sr_orbits; extern unsigned n_sr_orbits; orbits_to_use = sr_orbits; n_orbits_in_ephem = n_sr_orbits; } if( !ephemeris_in_a_file_from_mpc_code( ephemeris_filename, orbits_to_use, obs, n_obs_actually_loaded, curr_epoch, jd_start, ephemeris_step_size, n_ephemeris_steps, mpc_code, ephemeris_output_options, n_orbits_in_ephem)) { write_residuals_to_file( residual_filename, argv[1], n_obs_actually_loaded, obs, RESIDUAL_FORMAT_SHORT); if( mpec_path) { char fullpath[100]; sprintf( fullpath, "%s/%s.htm", mpec_path, ids[i].packed_desig); text_search_and_replace( fullpath, " ", ""); make_pseudo_mpec( fullpath, ids[i].obj_name); get_summary_info( tbuff, fullpath); if( summary_ofile) { FILE *ephemeris_ifile = fopen_ext( ephemeris_filename, "tfcrb"); char new_line[420]; tbuff[14] = '\0'; snprintf( new_line, sizeof( new_line), "<a href=\"%s\">%s</a>%s", fullpath, tbuff, tbuff + 15); memset( tbuff, 0, sizeof( tbuff)); while( j < 4 && fgets_trimmed( tbuff, sizeof( tbuff), ephemeris_ifile)) j++; if( j == 4) { tbuff[23] = tbuff[39] = tbuff[73] = '\0'; sprintf( new_line + strlen( new_line), " %s %s %s", tbuff + 15, tbuff + 30, tbuff + 57); /* now add sigma from end of ephem: */ while( fgets_trimmed( tbuff, sizeof( tbuff), ephemeris_ifile)) ; tbuff[73] = '\0'; sprintf( new_line + strlen( new_line), "%s", tbuff + 68); } fclose( ephemeris_ifile); summary_lines[n_lines_written] = (char *)malloc( strlen( new_line) + 1); strcpy( summary_lines[n_lines_written], new_line); n_lines_written++; } } } } for( j = 0; j < (unsigned)n_obs_actually_loaded; j++) if( obs[j].is_included) n_obs_included++; if( n_obs_included != n_obs_actually_loaded && show_processing_steps) { if( use_colors) /* reverse colors to draw attn */ printf( "\033[30;47m"); printf( " %d /", n_obs_included); } } else printf( "; not enough observations\n"); unload_observations( obs, n_obs_actually_loaded); } object_comment_text( tbuff, ids + i); /* Abbreviate 'observations:' to 'obs:' */ text_search_and_replace( tbuff, "ervations", ""); if( show_processing_steps) printf( " %s\n", tbuff); if( use_colors) printf( "\033[0m"); } free( ids); if( summary_ofile) { int pass; for( pass = 0; pass < 4; pass++) { const char *headers[4] = { "<h3><a name=\"desig\">Sorted by designation</a></h3>", "<h3><a name=\"unc\">Sorted by current ephemeris uncertainty</a></h3>", "<h3><a name=\"moid\">Sorted by Earth MOID</a></h3>", "<h3><a name=\"mag\">Sorted by magnitude</a></h3>" }; const char *ephem_header = "Object Semimajor axis Eccentricity Incl " "MOID RA dec Elong mag Sig1 Sig2"; fprintf( summary_ofile, "\n%s\n", headers[pass]); fprintf( summary_ofile, "%s\n\n", ephem_header); if( pass) { static int columns[] = { 0, 123, 77, 118 }; summ_sort_column = columns[pass]; qsort( summary_lines, n_lines_written, sizeof( char *), summ_compare); } for( i = 0; summary_lines[i]; i++) { fprintf( summary_ofile, "%s%s", summary_lines[i], ( i % 5 == 4) ? "\n\n" : "\n"); } } for( i = 0; summary_lines[i]; i++) free( summary_lines[i]); free( summary_lines); fprintf( summary_ofile, "</body> </html>\n"); fclose( summary_ofile); } fclose( ifile); #ifdef FORKING if( show_processing_steps) printf( "Process %d is done\n", process_count); wait( &child_status); /* wait for child to exit, and store its status */ if( process_count == 1) { extern const char *elements_filename; extern const char *mpc_fmt_filename; combine_element_files( elements_filename, n_processes); combine_element_files( mpc_fmt_filename, n_processes); combine_element_files( sof_filename, n_processes); combine_element_files( sofv_filename, n_processes); for( i = 0; i < n_processes; i++) { /* clean up temp files: */ process_count = i + 1; unlink_config_file( "monte.txt"); unlink_config_file( "guide.txt"); unlink_config_file( "covar.txt"); unlink_config_file( "sr_elems.txt"); unlink_config_file( "mpc_sr.txt"); // unlink_config_file( sof_filename); } } #ifdef TEST_PLANET_CACHING_HASH_FUNCTION if( process_count == 0) { extern int64_t planet_ns; extern long total_n_searches, total_n_probes, max_probes_required; printf( " tp:%ld.%09ld\n", (long)( planet_ns / (int64_t)1000000000), (long)( planet_ns % (int64_t)1000000000)); printf( "%ld searches; %ld probes; %ld max probes\n", total_n_searches, total_n_probes, max_probes_required); } #endif #endif clean_up_find_orb_memory( ); return( 0); }
int main( const int argc, const char **argv) { FILE *ifile = fopen( argv[1], "rb"); char buff[200], results[6][100]; char exp_text[100]; double roll_ang = 0.; assert( ifile); *exp_text = '\0'; printf( "# (J95) Great Shefford logs, processed with j95_xvt.c (q.v.)\n"); #ifdef __TIMESTAMP__ printf( "# Source file date %s\n", __TIMESTAMP__); #else printf( "# Version %s %s\n", __DATE__, __TIME__); #endif printf( "# Input file '%s'\n", argv[1]); while( fgets( buff, sizeof( buff), ifile)) { size_t i, j, k; double jd; char *time_str = results[1]; for( i = j = 0; buff[i]; i++) /* remove quote marks */ if( buff[i] != '"') buff[j++] = buff[i]; buff[j] = '\0'; for( i = j = 0; i < 6; i++) { k = j; while( buff[k] != ',' && buff[k] >= ' ') k++; assert( k > j); assert( buff[k] == ',' || i == 5); memcpy( results[i], buff + j, k - j); results[i][k - j] = '\0'; j = k + 1; /* skip the comma */ } jd = get_time_from_string( 0., time_str, FULL_CTIME_DMY, NULL); if( jd > 2e+6) { const double exposure_time = atof( results[4]) / seconds_per_day; const double ra = get_angle( results[2]) * 15.; const double dec = get_angle( results[3]); const double new_roll_ang = atof( results[5]); if( strcmp( exp_text, results[4])) { strcpy( exp_text, results[4]); printf( "# Exposure: %s s\n", exp_text); } if( fabs( roll_ang - new_roll_ang) > .5) { roll_ang = new_roll_ang; printf( "# Tilt: %.1f\n", roll_ang); } jd += exposure_time / 2.; full_ctime( time_str, jd, FULL_CTIME_YMD | FULL_CTIME_MILLISECS | FULL_CTIME_MONTHS_AS_DIGITS | FULL_CTIME_LEADING_ZEROES); time_str[4] = time_str[7] = '-'; time_str[10] = 'T'; printf( "%.3f,%.3f,%s,J95,%s\n", ra, dec, time_str, results[0]); } } fclose( ifile); return( 0); }
double DLL_FUNC get_time_from_string( double initial_jd, const char *time_str, const int time_format, int *is_ut) { const double J2000 = 2451544.5; /* 1.0 Jan 2000 = JD 2451544.5 */ const int calendar = (time_format & CALENDAR_MASK); /* Certain solar-lunar calendars can have 13 months in a year: */ const int max_month = ((calendar == CALENDAR_HEBREW || calendar == CALENDAR_CHINESE) ? 13 : 12); int iday, month, hour, minute, n_bytes; int ival, i, colon_found = 0, is_bc = 0; int am_pm_indicator = AM_PM_UNSET; long year; double sec, dday; double rval = 0., offset = 0., tval; char buff[80]; char symbol = 0; char *str = buff; if( is_ut) *is_ut = 0; while( *time_str == ' ') /* skip leading spaces */ time_str++; if( strlen( time_str) >= sizeof( buff) || !*time_str) return( initial_jd); /* check/avoid possible buffer overflow */ /* Ensure spaces between letters and digits. For example, */ /* if time_str="11Nov 1918", set str="11 Nov 1918". */ /* 'Q' is an exception to avoid '1q' becoming '1 q'. */ *str = tolower( *time_str++); i = 1; while( (size_t)i < sizeof( buff) - 1 && *time_str) { if( (isalpha( *time_str) && isdigit( time_str[-1])) || (isdigit( *time_str) && isalpha( time_str[-1]))) if( *time_str != 'q' && *time_str != 'Q') str[i++] = ' '; str[i++] = (char)tolower( *time_str++); } str[i] = '\0'; remove_trailing_spaces( str); while( *str && (tval = collect_time_offset( str)) != 0.) { remove_trailing_spaces( str); offset += tval; } i = strlen( str); if( i > 1) { const int phase = get_phase_idx( str + i - 2); if( phase != PHASE_IDX_UNDEFINED) { str[i - 2] = '\0'; rval = get_time_from_string( initial_jd, str, time_format, NULL); if( rval && is_ut) *is_ut = 1; return( set_from_lunar( phase, rval) + offset); } } is_bc = check_for_bc( str); if( *str == 'j') /* decimal JD */ { /* may begin with 'j' or 'jd' */ if( str[1] == 'd') str++; rval = atof( str + 1); if( rval && is_ut) *is_ut = 1; } if( *str == 'y') /* decimal years */ rval = J2000 + (atof( str + 1) - 2000.) * 365.25; if( !memcmp( str, "mjd", 3)) /* modified JD */ { rval = atof( str + 3) + 2400000.5; if( is_ut) *is_ut = 1; } if( !memcmp( str, "now", 3)) { static const double jan_1970 = 2440587.5; str += 3; while( *str == ' ') str++; initial_jd = jan_1970 + (double)time( NULL) / 86400.; } if( !*str) rval = initial_jd; if( rval) return( rval + offset); /* The common European format of separating day/month/year */ /* with .s causes trouble, because the code wants to see */ /* those as decimal numbers. So if the input string starts */ /* with three integers separated by dots, we change both */ /* dots to '/' characters, then proceed normally: */ if( sscanf( str, "%d.%d.%d%n", &iday, &month, &hour, &n_bytes) == 3) for( i = 0; i < n_bytes; i++) if( str[i] == '.') str[i] = '/'; sec = split_time( initial_jd, &year, &month, &iday, &hour, &minute, calendar); /* FITS times are always in the form YYYY-MM-DDTHH:MM:SS, */ /* sometimes followed by .S. This is handled separately, */ /* in part to ensure that the month and day don't get */ /* swapped around: they are _always_ in that order. Also */ /* note that after spaces are added and the 'T' lowercased, */ /* it actually reads YYYY-MM-DD t HH:MM:SS. */ i = strlen( str); if( i > 18 && str[11] == 't') if( str[4] == '-' && str[7] == '-' && str[15] == ':') { symbol = 'f'; sscanf( str, "%ld-%d-%d", &year, &month, &iday); } if( i >= 4) { const char *search_text[4] = { " am", " a.m.", " pm", " p.m." }; int j; for( j = 0; j < 4; j++) { const int slen = 3 + ((j & 1) << 1); if( !strcmp( str + i - slen, search_text[j])) { i -= slen; str[i] = '\0'; am_pm_indicator = (j >= 2 ? AM_PM_SET_TO_PM : AM_PM_SET_TO_AM); j = 4; /* break out of loop */ } } } /* If the input text ends with something containing ':'s, */ /* assume there is a time to be extracted. Back up along the */ /* string, looking for the start of the time string (which */ /* may be the beginning of the string, or just after a space, */ /* or (for FITS input) just after a 'T'... for simplicity, */ /* that last test just checks for any alphabetical char.) */ for( i = strlen( str); i && str[i - 1] != ' ' && !isalpha( str[i - 1]); i--) if( str[i - 1] == ':') colon_found = 1; if( strcmp( str + i, ":")) { const int saved_hour = hour; minute = hour = 0; sec = 0.; if( colon_found) { double dminute = 0.; if( str[i] != ':') { sscanf( str + i, "%d:%lf:%lf", &hour, &dminute, &sec); sec += dminute * 60.; if( am_pm_indicator == AM_PM_SET_TO_AM) if( hour == 12) hour = 0; if( am_pm_indicator == AM_PM_SET_TO_PM) if( hour != 12) hour += 12; } else /* :MM:SS means "leave the hour unchanged" */ { hour = saved_hour; sscanf( str + i + 1, "%lf:%lf", &dminute, &sec); sec += dminute * 60.; } } } if( colon_found) /* lop the time off, leaving only the date: */ str[i ? i - 1 : 0] = '\0'; dday = (double)iday; i = 0; if( *str && symbol != 'f') { for( i = 1; str[i] && !strchr( "-:/ ", str[i]); i++) ; symbol = str[i]; } switch( symbol) { case 'f': /* FITS-format time: see above */ break; case ':': /* time of day */ break; case '-': /* dash-delimited such as '2009-01-20' */ case ' ': /* space-delimited format such as "25 dec 1980" */ case '/': /* common day/month/year dividing symbol */ { int month_found = 0, n_fields_found = 2; int year_found = 0, day_found = 0; char tstr[80]; double ivals[3]; memcpy( tstr, str, i); tstr[i] = '\0'; ival = month_name_to_index( tstr); if( ival) /* month given first, such as 'jan 25' */ { month_found = 1; ivals[0] = (double)ival; } else { ivals[0] = atof( tstr); if( strchr( tstr, '.')) /* decimal day given */ day_found = 1; } str += i + 1; for( i = 0; str[i] && str[i] != symbol && str[i] != ' '; i++) ; memcpy( tstr, str, i); tstr[i] = '\0'; str += i; ival = month_name_to_index( tstr); if( ival) /* month given second, such as '25-jan' */ { month_found = 2; ivals[1] = (double)ival; } else { ivals[1] = atof( tstr); if( strchr( tstr, '.')) /* decimal day given */ day_found = 2; } if( *str == symbol) /* maybe a third field was entered, but */ { /* could be a time; check for a ':' */ str++; if( sscanf( str, "%79s", tstr) == 1) if( (ival = month_name_to_index( tstr)) != 0) { month_found = 3; n_fields_found = 3; ivals[2] = (double)ival; str += strlen( tstr); } if( n_fields_found == 2) if( sscanf( str, "%lf%n", &ivals[2], &n_bytes) == 1) if( str[n_bytes] != ':') { str += n_bytes; if( strchr( tstr, '.')) day_found = 3; n_fields_found = 3; } } /* if one of the fields is negative, or if it's */ /* greater than 32 and is the largest entry, it */ /* can be assumed to be the year: */ for( i = 0; i < n_fields_found; i++) if( ivals[i] < 0.) { year_found = i + 1; /* if we see a negative number, */ i = n_fields_found; /* we can stop looking further: */ } else if( ivals[i] > 32.) if( !year_found || ivals[i] > ivals[year_found - 1]) year_found = i + 1; if( year_found || n_fields_found == 2) for( i = 0; i < n_fields_found; i++) if( ivals[i] > (double)max_month + .0001 && ivals[i] < 32. && i + 1 != year_found) day_found = i + 1; if( n_fields_found == 2) { if( month_found) { double dval = ivals[2 - month_found]; month = (int)ivals[month_found - 1]; if( dval > .999 && dval < 32.) dday = dval; else year = (int)dval; } else if( year_found) /* year/day of year format: */ { year = (int)ivals[year_found - 1]; month = 1; dday = ivals[2 - year_found]; } else if( day_found) /* day/month, order is clear from */ { /* the day being > 12 or having a decimal*/ dday = ivals[day_found - 1]; month = (int)ivals[2 - day_found]; } else /* can't tell what's day/month/year solely from input: */ if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') { month = (int)ivals[0]; dday = (int)ivals[1]; } else /* day/month */ { month = (int)ivals[1]; dday = (int)ivals[0]; } } else /* three fields entered: */ { const int year_first = (time_format & FULL_CTIME_YEAR_FIRST); if( !year_found) { if( !month_found) { if( !day_found || day_found == 2) { year_found = (year_first ? 1 : 3); if( !day_found) /* must rely solely on time format */ { /* settings; no fields autofound */ day_found = (year_first ? 2 : 1); if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') day_found++; /* ymd or mdy case */ } } else /* if day is 1st or last, year is last or 1st */ year_found = 4 - day_found; } else if( !day_found) /* only the month was found: */ { if( month_found == 2) year_found = (year_first ? 1 : 3); else /* if month is 1st or last, year must be last/1st */ year_found = 4 - month_found; } } else /* year_found... */ if( !month_found && !day_found) /* ...but nothing else */ { if( (time_format & FULL_CTIME_MONTH_DAY) || symbol == 'f') month_found = (year_found == 1 ? 2 : 1); else day_found = (year_found == 1 ? 2 : 1); } /* We now have the year nailed down. If either the day */ /* or month is still not nailed down, we can find it */ /* easily, since the 'found' values must sum up to 6: */ if( !day_found) day_found = 6 - year_found - month_found; else if( !month_found) month_found = 6 - year_found - day_found; year = (int)floor( ivals[year_found - 1] + .5); dday = ivals[day_found - 1]; month = (int)( ivals[month_found - 1] + .5); } if( year > 0 && year < 100 && !is_bc) if( time_format & FULL_CTIME_TWO_DIGIT_YEAR) year += (year < 40 ? 2000 : 1900); } break; case '\0': /* no dividing symbols found */ if( *str) { ival = month_name_to_index( str); if( ival) month = ival; else if( (ival = day_of_week_name_to_index( str)) >= 0) { ival -= ((long)(initial_jd + 1.5)) % 7; if( ival < -3) ival += 7; else if( ival > 3) ival -= 7; dday += ival; } else { n_bytes = 0; if( sscanf( str, "%d%n", &ival, &n_bytes) == 1) { double tval = 0.; str += n_bytes; if( *str == '.') /* also a fractional part to this: */ { int n_bytes_in_fraction; sscanf( str, "%lf%n", &tval, &n_bytes_in_fraction); str += n_bytes_in_fraction; } tval += (double)ival; switch( n_bytes) { case 1: case 2: /* reset day */ dday = tval; break; case 3: /* reset day of year */ dday = tval; month = 1; break; case 4: /* reset year, which may be */ case 5: /* four or five digits long */ if( (double)ival == tval) { /* set 1 Jan of the year */ dday = 1.; month = 1; year = ival; } else /* true decimal year */ return( J2000 + (tval - 2000.) * 365.25 + offset); break; case 7: /* JD */ if( is_ut) *is_ut = 1; return( tval + offset); case 6: /* YYMMDD(.DD) */ case 8: /* YYYYMMDD(.DD) */ year = ival / 10000L; if( n_bytes == 6) year += (year < 40 ? 2000 : 1900); month = (ival / 100) % 100L; dday = (double)( ival % 100L); dday += tval - (double)ival; break; } } else /* couldn't make sense of input text */ return( 0.); } } break; default: return( 0.); // break; } if( is_bc) year = 1 - year; iday = (int)dday; dday -= (double)iday; rval = (double)dmy_to_day( iday, month, year, calendar) + dday - .5 + (double)hour / 24. + (double)minute / 1440. + sec / 86400.; return( rval + offset); }