67char *option[N_OPTIONS] = {
78 " sddstimeconvert [<SDDSinput>] [<SDDSoutput>] \n"
79 " [-pipe=<input>[,<output>]] \n"
80 " [-majorOrder=row|column]\n"
81 " [-breakdown={column|parameter},<timeName>[,year=<newName>]\n"
82 " [,julianDay=<newName>]\n"
83 " [,month=<newName>]\n"
85 " [,hour=<newName>]\n"
86 " [,text=<newName>]]\n"
87 " [-dateToTime={column|parameter},<timeName>,<newName>,<stringName>,format=<formatString>]\n"
88 " [-epoch={column|parameter},<newName>,year=<name>,[julianDay=<name>|month=<name>,day=<name>],hour=<name>]\n"
90 " -pipe Enable standard SDDS Toolkit pipe processing.\n"
91 " -majorOrder Specify output file order: row or column major.\n"
92 " -breakdown Break down epoch time into components.\n"
93 " -epoch Create a new epoch time column or parameter.\n"
94 " -dateToTime Convert date string to epoch time.\n\n"
95 "Program by Michael Borland. (" __DATE__
" " __TIME__
", SVN revision: " SVN_VERSION
")\n";
97#define IS_COLUMN 0x0001U
98#define IS_PARAMETER 0x0002U
99#define EPOCH_GIVEN 0x0004U
100#define YEAR_GIVEN 0x0008U
101#define JDAY_GIVEN 0x0010U
102#define MONTH_GIVEN 0x0020U
103#define DAY_GIVEN 0x0040U
104#define HOUR_GIVEN 0x0080U
105#define DO_BREAKDOWN 0x0100U
106#define DO_EPOCH 0x0200U
107#define TEXT_GIVEN 0x0400U
108#define FORMAT_GIVEN 0x0800U
109#define DO_DATECONVERSION 0x1000U
113 char *epochName, *yearName, *jDayName, *monthName, *dayName, *hourName;
114 char *textName, *format;
115 long epochIndex, yearIndex, jDayIndex, monthIndex, dayIndex, hourIndex;
142static const char *parseDateNumber(
const char *input,
int minimumDigits,
int maximumDigits,
143 int minimumValue,
int maximumValue,
int *value) {
144 int digits = 0, result = 0;
146 while (digits < maximumDigits && isdigit((
unsigned char)*input)) {
147 result = 10 * result + (*input -
'0');
151 if (digits < minimumDigits || result < minimumValue || result > maximumValue)
157static int dateTextMatches(
const char *input,
const char *text) {
160 while (text[length]) {
161 if (!input[length] ||
162 tolower((
unsigned char)input[length]) != tolower((
unsigned char)text[length]))
169static const char *parseDateName(
const char *input,
const char *
const *names,
int namesCount,
int *index) {
172 for (i = 0; i < namesCount; i++) {
173 if ((length = dateTextMatches(input, names[i]))) {
175 return input + length;
181static const char *parseWindowsDateFormat(
const char *input,
const char *format, DATE_PARSE_STATE *state) {
182 static const char *
const abbreviatedMonth[] = {
183 "Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
184 "Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
186 static const char *
const fullMonth[] = {
187 "January",
"February",
"March",
"April",
"May",
"June",
188 "July",
"August",
"September",
"October",
"November",
"December"
190 static const char *
const abbreviatedWeekday[] = {
191 "Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
193 static const char *
const fullWeekday[] = {
194 "Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
196 static const char *
const meridiem[] = {
"AM",
"PM"};
201 if (isspace((
unsigned char)*format)) {
202 while (isspace((
unsigned char)*format))
204 while (isspace((
unsigned char)*input))
208 if (*format !=
'%') {
209 if (*input != *format)
217 if (*format ==
'E' || *format ==
'O')
228 if (!(input = parseDateNumber(input, 1, 4, 0, 9999, &value)))
230 state->value->tm_year = value - 1900;
233 if (!(input = parseDateNumber(input, 1, 2, 0, 99, &state->century)))
237 if (!(input = parseDateNumber(input, 1, 2, 0, 99, &state->shortYear)))
241 if (!(input = parseDateNumber(input, 1, 2, 1, 12, &value)))
243 state->value->tm_mon = value - 1;
247 if (!(input = parseDateName(input, abbreviatedMonth, 12, &value)))
249 state->value->tm_mon = value;
252 if (!(input = parseDateName(input, fullMonth, 12, &value)))
254 state->value->tm_mon = value;
257 if (!(input = parseDateNumber(input, 1, 2, 1, 31, &state->value->tm_mday)))
261 while (*input ==
' ')
263 if (!(input = parseDateNumber(input, 1, 2, 1, 31, &state->value->tm_mday)))
268 while (*input ==
' ')
270 if (!(input = parseDateNumber(input, 1, 2, 0, 23, &state->value->tm_hour)))
275 while (*input ==
' ')
277 if (!(input = parseDateNumber(input, 1, 2, 1, 12, &state->value->tm_hour)))
279 state->twelveHour = 1;
282 if (!(input = parseDateNumber(input, 1, 2, 0, 59, &state->value->tm_min)))
286 if (!(input = parseDateNumber(input, 1, 2, 0, 60, &state->value->tm_sec)))
290 if (!(input = parseDateNumber(input, 1, 3, 1, 366, &state->julianDay)))
292 state->value->tm_yday = state->julianDay - 1;
295 if (!(input = parseDateName(input, abbreviatedWeekday, 7, &state->value->tm_wday)))
299 if (!(input = parseDateName(input, fullWeekday, 7, &state->value->tm_wday)))
303 if (!(input = parseDateNumber(input, 1, 1, 0, 6, &state->value->tm_wday)))
307 if (!(input = parseDateNumber(input, 1, 1, 1, 7, &value)))
309 state->value->tm_wday = value % 7;
313 if (!(input = parseDateName(input, meridiem, 2, &state->meridiem)))
318 while (isspace((
unsigned char)*input))
322 if (!(input = parseWindowsDateFormat(input,
"%m/%d/%y", state)))
326 if (!(input = parseWindowsDateFormat(input,
"%Y-%m-%d", state)))
330 if (!(input = parseWindowsDateFormat(input,
"%H:%M", state)))
335 if (!(input = parseWindowsDateFormat(input,
"%H:%M:%S", state)))
339 if (!(input = parseWindowsDateFormat(input,
"%I:%M:%S %p", state)))
343 if (!(input = parseWindowsDateFormat(input,
"%m/%d/%y", state)))
347 if (!(input = parseWindowsDateFormat(input,
"%a %b %e %H:%M:%S %Y", state)))
352 while (isalpha((
unsigned char)*input) || *input ==
'_' || *input ==
'/')
364static int dateMonthDayFromJulianDay(
int julianDay,
int year,
int *month,
int *day) {
365 static const int daysPerMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
368 for (i = 0; i < 12; i++) {
369 days = daysPerMonth[i];
370 if (i == 1 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
372 if (julianDay <= days) {
382static const char *parseDateTime(
const char *input,
const char *format,
struct tm *value) {
383 DATE_PARSE_STATE state;
388 memset(&state, 0,
sizeof(state));
391 state.shortYear = -1;
394 if (!(result = parseWindowsDateFormat(input, format, &state)))
397 if (state.shortYear >= 0) {
398 if (state.century >= 0)
399 year = state.century * 100 + state.shortYear;
401 year = state.shortYear <= 68 ? 2000 + state.shortYear : 1900 + state.shortYear;
402 value->tm_year = year - 1900;
403 }
else if (state.century >= 0) {
404 value->tm_year = state.century * 100 - 1900;
407 if (state.twelveHour && state.meridiem >= 0) {
408 value->tm_hour %= 12;
410 value->tm_hour += 12;
413 if (state.julianDay) {
414 year = value->tm_year + 1900;
415 if (!dateMonthDayFromJulianDay(state.julianDay, year, &month, &day))
417 value->tm_mon = month - 1;
418 value->tm_mday = day;
423static const char *parseDateTime(
const char *input,
const char *format,
struct tm *value) {
424 return strptime(input, format, value);
428int main(
int argc,
char **argv) {
432 char *input, *output;
435 unsigned long pipeFlags, majorOrderFlag;
436 short columnMajorOrder = -1;
439 argc =
scanargs(&s_arg, argc, argv);
441 fprintf(stderr,
"%s", USAGE);
445 input = output = NULL;
450 for (i_arg = 1; i_arg < argc; i_arg++) {
451 if (s_arg[i_arg].arg_type == OPTION) {
452 switch (
match_string(s_arg[i_arg].list[0], option, N_OPTIONS, 0)) {
453 case SET_MAJOR_ORDER:
455 s_arg[i_arg].n_items--;
456 if (s_arg[i_arg].n_items > 0 &&
457 (!
scanItemList(&majorOrderFlag, s_arg[i_arg].list + 1, &s_arg[i_arg].n_items, 0,
458 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
459 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL)))
460 SDDS_Bomb(
"invalid -majorOrder syntax/values");
461 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
462 columnMajorOrder = 1;
463 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
464 columnMajorOrder = 0;
467 if (s_arg[i_arg].n_items < 4)
469 if (!(conversion =
SDDS_Realloc(conversion,
sizeof(*conversion) * (conversions + 1))))
471 memset((
char *)(conversion + conversions), 0,
sizeof(*conversion));
472 conversion[conversions].epochName = s_arg[i_arg].list[2];
473 s_arg[i_arg].list[2] = s_arg[i_arg].list[1];
474 s_arg[i_arg].n_items -= 2;
476 s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
477 "column", -1, NULL, 0, IS_COLUMN,
478 "parameter", -1, NULL, 0, IS_PARAMETER,
479 "year",
SDDS_STRING, &conversion[conversions].yearName, 1, YEAR_GIVEN,
480 "julianday",
SDDS_STRING, &conversion[conversions].jDayName, 1, JDAY_GIVEN,
481 "month",
SDDS_STRING, &conversion[conversions].monthName, 1, MONTH_GIVEN,
482 "day",
SDDS_STRING, &conversion[conversions].dayName, 1, DAY_GIVEN,
483 "hour",
SDDS_STRING, &conversion[conversions].hourName, 1, HOUR_GIVEN, NULL))
485 conversion[conversions].flags |= EPOCH_GIVEN | DO_EPOCH;
486 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
487 SDDS_Bomb(
"Specify 'column' or 'parameter' qualifier with -epoch");
488 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
489 SDDS_Bomb(
"Specify only one of 'column' or 'parameter' qualifier with -epoch");
490 if (!(conversion[conversions].flags & YEAR_GIVEN))
491 SDDS_Bomb(
"Specify year name with -epoch");
492 if (!(conversion[conversions].flags & JDAY_GIVEN) &&
493 (conversion[conversions].flags & (MONTH_GIVEN | DAY_GIVEN)) != (MONTH_GIVEN | DAY_GIVEN))
494 SDDS_Bomb(
"Specify either julianDay name, or both month and day names with -epoch");
495 if (conversion[conversions].flags & JDAY_GIVEN && conversion[conversions].flags & (MONTH_GIVEN | DAY_GIVEN))
496 SDDS_Bomb(
"Invalid combination of julianDay name with month or day name for -epoch");
500 if (s_arg[i_arg].n_items < 4)
502 if (!(conversion =
SDDS_Realloc(conversion,
sizeof(*conversion) * (conversions + 1))))
504 memset((
char *)(conversion + conversions), 0,
sizeof(*conversion));
505 conversion[conversions].epochName = s_arg[i_arg].list[2];
506 s_arg[i_arg].list[2] = s_arg[i_arg].list[1];
507 s_arg[i_arg].n_items -= 2;
509 s_arg[i_arg].list + 2, &s_arg[i_arg].n_items, 0,
510 "column", -1, NULL, 0, IS_COLUMN,
511 "parameter", -1, NULL, 0, IS_PARAMETER,
512 "year",
SDDS_STRING, &conversion[conversions].yearName, 1, YEAR_GIVEN,
513 "julianday",
SDDS_STRING, &conversion[conversions].jDayName, 1, JDAY_GIVEN,
514 "month",
SDDS_STRING, &conversion[conversions].monthName, 1, MONTH_GIVEN,
515 "day",
SDDS_STRING, &conversion[conversions].dayName, 1, DAY_GIVEN,
516 "hour",
SDDS_STRING, &conversion[conversions].hourName, 1, HOUR_GIVEN,
517 "text",
SDDS_STRING, &conversion[conversions].textName, 1, TEXT_GIVEN, NULL))
519 conversion[conversions].flags |= EPOCH_GIVEN | DO_BREAKDOWN;
520 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
521 SDDS_Bomb(
"Specify 'column' or 'parameter' qualifier with -breakdown");
522 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
523 SDDS_Bomb(
"Specify only one of 'column' or 'parameter' qualifier with -breakdown");
524 if (!(conversion[conversions].flags & (YEAR_GIVEN | JDAY_GIVEN | MONTH_GIVEN | DAY_GIVEN | HOUR_GIVEN | TEXT_GIVEN)))
525 SDDS_Bomb(
"Specify at least one of year, julianDay, month, day, hour, or text qualifiers with -breakdown");
529 if (s_arg[i_arg].n_items < 4)
531 if (!(conversion =
SDDS_Realloc(conversion,
sizeof(*conversion) * (conversions + 1))))
533 memset((
char *)(conversion + conversions), 0,
sizeof(*conversion));
534 conversion[conversions].textName = s_arg[i_arg].list[3];
535 conversion[conversions].epochName = s_arg[i_arg].list[2];
536 s_arg[i_arg].list[3] = s_arg[i_arg].list[1];
537 s_arg[i_arg].n_items -= 3;
539 s_arg[i_arg].list + 3, &s_arg[i_arg].n_items, 0,
540 "column", -1, NULL, 0, IS_COLUMN,
541 "parameter", -1, NULL, 0, IS_PARAMETER,
542 "format",
SDDS_STRING, &conversion[conversions].format, 1, FORMAT_GIVEN, NULL))
544 conversion[conversions].flags |= DO_DATECONVERSION;
545 if (!(conversion[conversions].flags & (IS_COLUMN | IS_PARAMETER)))
546 SDDS_Bomb(
"Specify 'column' or 'parameter' qualifier with -dateToTime");
547 if (conversion[conversions].flags & IS_COLUMN && conversion[conversions].flags & IS_PARAMETER)
548 SDDS_Bomb(
"Specify only one of 'column' or 'parameter' qualifier with -dateToTime");
549 if (!(conversion[conversions].flags & FORMAT_GIVEN))
550 SDDS_Bomb(
"Format string not provided for date to time conversion");
554 if (!
processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
558 fprintf(stderr,
"Error: Unknown option: %s\n", s_arg[i_arg].list[0]);
564 input = s_arg[i_arg].list[0];
566 output = s_arg[i_arg].list[0];
568 fprintf(stderr,
"Error: Argument '%s' is invalid: too many filenames (sddstimeconvert)\n", s_arg[i_arg].list[0]);
581 CheckEpochConversionElements(&SDDSin, conversion, conversions);
582 CheckBreakdownConversionElements(&SDDSin, conversion, conversions);
583 CheckDateConversionElements(&SDDSin, conversion, conversions);
585 InitializeOutput(&SDDSout, output, conversion, conversions, &SDDSin, columnMajorOrder);
592 for (iconv = 0; iconv < conversions; iconv++) {
593 if (conversion[iconv].flags & DO_EPOCH) {
594 if (conversion[iconv].flags & IS_PARAMETER)
595 DoParameterEpochConversion(&SDDSout, &SDDSin, conversion + iconv);
597 DoColumnEpochConversion(&SDDSout, &SDDSin, conversion + iconv);
598 }
else if (conversion[iconv].flags & DO_BREAKDOWN) {
599 if (conversion[iconv].flags & IS_PARAMETER)
600 DoParameterBreakdownConversion(&SDDSout, &SDDSin, conversion + iconv);
602 DoColumnBreakdownConversion(&SDDSout, &SDDSin, conversion + iconv);
605 if (conversion[iconv].flags & IS_PARAMETER)
606 DoParameterDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
608 DoColumnDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
625 while (conversions-- > 0) {
626 if (!(conversion[conversions].flags & DO_EPOCH))
628 if (conversion->flags & IS_PARAMETER) {
630 (conversion->jDayName &&
632 (conversion->dayName &&
634 (conversion->monthName &&
640 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
641 if (conversion->dayName)
643 if (conversion->jDayName)
645 if (conversion->monthName)
649 (conversion->jDayName &&
651 (conversion->dayName &&
653 (conversion->monthName &&
659 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
660 if (conversion->dayName)
662 if (conversion->jDayName)
664 if (conversion->monthName)
672 while (conversions-- > 0) {
673 if (!(conversion[conversions].flags & DO_BREAKDOWN))
675 if (conversion->flags & IS_PARAMETER) {
689 while (conversions-- > 0) {
690 if (!(conversion[conversions].flags & DO_DATECONVERSION))
692 if (conversion->flags & IS_PARAMETER) {
701 if (conversion->textIndex < 0) {
702 fprintf(stderr,
"Error: '%s' does not exist in input file.\n", conversion->textName);
713 if (columnMajorOrder != -1)
714 SDDSout->layout.data_mode.column_major = columnMajorOrder;
716 SDDSout->layout.data_mode.column_major = SDDSin->layout.data_mode.column_major;
717 while (conversions-- > 0) {
718 if (conversion->flags & DO_EPOCH) {
719 if (conversion->flags & IS_PARAMETER) {
721 NULL,
"s",
"Time since start of epoch", NULL,
SDDS_DOUBLE, NULL)) < 0)
725 NULL,
"s",
"Time since start of epoch", NULL,
SDDS_DOUBLE, 0)) < 0)
728 }
else if (conversion->flags & DO_BREAKDOWN) {
729 if (conversion->flags & IS_PARAMETER) {
730 if ((conversion->yearName &&
731 (conversion->yearIndex =
SDDS_DefineParameter(SDDSout, conversion->yearName, NULL, NULL,
"Year", NULL,
733 (conversion->dayName &&
734 (conversion->dayIndex =
SDDS_DefineParameter(SDDSout, conversion->dayName, NULL, NULL,
"Day of month",
736 (conversion->monthName &&
737 (conversion->monthIndex =
SDDS_DefineParameter(SDDSout, conversion->monthName, NULL, NULL,
"Month", NULL,
739 (conversion->jDayName &&
740 (conversion->jDayIndex =
SDDS_DefineParameter(SDDSout, conversion->jDayName, NULL, NULL,
"Julian day",
742 (conversion->hourName &&
743 (conversion->hourIndex =
SDDS_DefineParameter(SDDSout, conversion->hourName, NULL, NULL,
"Hour of day",
745 (conversion->textName &&
746 (conversion->textIndex =
SDDS_DefineParameter(SDDSout, conversion->textName, NULL, NULL,
"Timestamp",
750 if ((conversion->yearName &&
751 (conversion->yearIndex =
SDDS_DefineColumn(SDDSout, conversion->yearName, NULL, NULL,
"Year", NULL,
753 (conversion->dayName &&
754 (conversion->dayIndex =
SDDS_DefineColumn(SDDSout, conversion->dayName, NULL, NULL,
"Day of month",
756 (conversion->monthName &&
757 (conversion->monthIndex =
SDDS_DefineColumn(SDDSout, conversion->monthName, NULL, NULL,
"Month", NULL,
759 (conversion->jDayName &&
760 (conversion->jDayIndex =
SDDS_DefineColumn(SDDSout, conversion->jDayName, NULL, NULL,
"Julian day",
762 (conversion->hourName &&
763 (conversion->hourIndex =
SDDS_DefineColumn(SDDSout, conversion->hourName, NULL, NULL,
"Hour of day",
765 (conversion->textName &&
766 (conversion->textIndex =
SDDS_DefineColumn(SDDSout, conversion->textName, NULL, NULL,
"Timestamp",
772 if (conversion->flags & IS_PARAMETER) {
774 NULL,
"s",
"Time since start of epoch", NULL,
SDDS_DOUBLE, NULL)) < 0)
778 NULL,
"s",
"Time since start of epoch", NULL,
SDDS_DOUBLE, 0)) < 0)
790 double month = 0, day = 0, jDay = 0, year, epochTime;
807 double hour, epochTime;
808 short year, jDay, month, day;
815 if ((conversion->yearName &&
817 conversion->yearIndex, (
double)year, -1)) ||
818 (conversion->dayName &&
820 conversion->dayIndex, (
double)day, -1)) ||
821 (conversion->jDayName &&
823 conversion->jDayIndex, (
double)jDay, -1)) ||
824 (conversion->monthName &&
826 conversion->monthIndex, (
double)month, -1)) ||
827 (conversion->hourName &&
829 conversion->hourIndex, (
double)hour, -1)) ||
830 (conversion->textName &&
831 !
SDDS_SetParameters(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE, conversion->textIndex, text, -1)))
837 double month = 0, day = 0, jDay = 0, year, epochTime;
838 char *timestr = NULL;
849 if (parseDateTime(timestr, conversion->format, &tm) == NULL) {
850 fprintf(stderr,
"Error: Failed to parse date string '%s' with format '%s'\n", timestr, conversion->format);
853 year = tm.tm_year + 1900;
854 month = tm.tm_mon + 1;
856 hour = tm.tm_hour + tm.tm_min / 60.0 + tm.tm_sec / 3600.0;
865 double *month, *day, *jDay, *year, *epochTime;
873 jDay = month = day = NULL;
881 if (!(epochTime = (
double *)malloc(
sizeof(*epochTime) * rows)))
884 for (row = 0; row < rows; row++)
885 TimeBreakdownToEpoch((
short)year[row], jDay ? (
short)jDay[row] : 0, month ? (
short)month[row] : 0, day ? (
short)day[row] : 0, hour[row], epochTime + row);
901 double month = 0, day = 0, year = 0, jDay = 0, *epochTime;
903 char **timestr = NULL;
915 if (!(epochTime = (
double *)malloc(
sizeof(*epochTime) * rows)))
918 for (row = 0; row < rows; row++) {
919 if (parseDateTime(timestr[row], conversion->format, &tm) == NULL) {
920 fprintf(stderr,
"Error: Failed to parse date string '%s' with format '%s'\n", timestr[row], conversion->format);
923 year = tm.tm_year + 1900;
924 month = tm.tm_mon + 1;
926 hour = tm.tm_hour + tm.tm_min / 60.0 + tm.tm_sec / 3600.0;
927 TimeBreakdownToEpoch((
short)year, (
short)jDay, (
short)month, (
short)day, hour, epochTime + row);
936 double *hour, *epochTime;
937 short *month, *day, *jDay, *year;
948 month = day = jDay = year = NULL;
950 if ((conversion->hourName && !(hour = (
double *)malloc(
sizeof(*hour) * rows))) ||
951 (conversion->monthName && !(month = (
short *)malloc(
sizeof(*month) * rows))) ||
952 (conversion->dayName && !(day = (
short *)malloc(
sizeof(*day) * rows))) ||
953 (conversion->jDayName && !(jDay = (
short *)malloc(
sizeof(*jDay) * rows))) ||
954 (conversion->textName && !(text = (
char **)malloc(
sizeof(*text) * rows))) ||
955 (conversion->yearName && !(year = (
short *)malloc(
sizeof(*year) * rows))))
958 for (row = 0; row < rows; row++) {
960 text[row] = malloc(
sizeof(**text) * 30);
961 if (!
TimeEpochToBreakdown(year ? year + row : NULL, jDay ? jDay + row : NULL, month ? month + row : NULL, day ? day + row : NULL, hour ? hour + row : NULL, epochTime[row]) ||
963 SDDS_Bomb(
"Problem performing time breakdown");
966 if ((year && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, year, rows, conversion->yearName)) ||
967 (day && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, day, rows, conversion->dayName)) ||
968 (month && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, month, rows, conversion->monthName)) ||
969 (jDay && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, jDay, rows, conversion->jDayName)) ||
970 (hour && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, hour, rows, conversion->hourName)) ||
971 (text && !
SDDS_SetColumn(SDDSout, SDDS_BY_NAME, text, rows, conversion->textName)))
986 for (row = 0; row < rows; row++)
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetColumnFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode, double *data, int64_t rows,...)
Sets the values for a single data column using double-precision floating-point numbers.
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
int32_t SDDS_GetParameterIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named parameter in the SDDS dataset.
int32_t SDDS_GetColumnIndex(SDDS_DATASET *SDDS_dataset, char *name)
Retrieves the index of a named column in the SDDS dataset.
int32_t SDDS_CheckColumn(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a column exists in the SDDS dataset with the specified name, units, and type.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
int32_t SDDS_CheckParameter(SDDS_DATASET *SDDS_dataset, char *name, char *units, int32_t type, FILE *fp_message)
Checks if a parameter exists in the SDDS dataset with the specified name, units, and type.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
#define SDDS_STRING
Identifier for the string data type.
#define SDDS_SHORT
Identifier for the signed short integer data type.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
#define SDDS_DOUBLE
Identifier for the double data type.
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
long processPipeOption(char **item, long items, unsigned long *flags)
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.
short TimeEpochToBreakdown(short *year, short *jDay, short *month, short *day, double *hour, double epochTime)
Breaks down epoch time into its constituent components.
short TimeBreakdownToEpoch(short year, short jDay, short month, short day, double hour, double *epochTime)
Converts a broken-down time into epoch time.
short TimeEpochToText(char *text, double epochTime)
Converts epoch time to a formatted text string.