SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
sddstimeconvert.c File Reference

Detailed Description

Perform time conversions on SDDS data.

This program enables users to perform various time-related operations on SDDS files. These operations include breaking down epoch times into components, converting date strings to epoch times, and specifying the major order of output data.

Usage

sddstimeconvert [<SDDSinput>] [<SDDSoutput>]
[-pipe=<input>[,<output>]]
[-majorOrder=row|column]
[-breakdown={column|parameter},<timeName>[,year=<newName>][,julianDay=<newName>][,month=<newName>][,day=<newName>][,hour=<newName>][,text=<newName>]]
[-dateToTime={column|parameter},<timeName>,<newName>,<stringName>,format=<formatString>]
[-epoch={column|parameter},<newName>,year=<name>,[julianDay=<name>|month=<name>,day=<name>],hour=<name>]

Options

Optional Description
-pipe Enable pipe-based input/output processing.
-majorOrder Specify output data order: row-major or column-major.
-breakdown= Break down epoch time into components such as year, month, day, hour, etc.
-dateToTime Convert date strings to epoch times based on a specified format string.
-epoch Generate a new epoch time column or parameter with optional qualifiers.

Incompatibilities

  • For -epoch, the following requirements must be met:
    • Specify either julianDay or both month and day names.
  • For -breakdown, at least one of the following must be specified:
    • year, julianDay, month, day, hour, or text qualifiers.
  • For -dateToTime, the format string is required.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
  • M. Borland
  • R. Soliday
  • H. Shang

Definition in file sddstimeconvert.c.

#include <ctype.h>
#include <time.h>
#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

void DoColumnEpochConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterEpochConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoColumnDateToTimeConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterDateToTimeConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoColumnBreakdownConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void DoParameterBreakdownConversion (SDDS_DATASET *SDDSout, SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion)
 
void InitializeOutput (SDDS_DATASET *SDDSout, char *outputfile, TIME_CONVERSION *conversion, long conversions, SDDS_DATASET *SDDSin, short columnMajorOrder)
 
void CheckEpochConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
void CheckBreakdownConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
void CheckDateConversionElements (SDDS_DATASET *SDDSin, TIME_CONVERSION *conversion, long conversions)
 
static const char * parseDateTime (const char *input, const char *format, struct tm *value)
 
int main (int argc, char **argv)
 

Function Documentation

◆ CheckBreakdownConversionElements()

void CheckBreakdownConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 671 of file sddstimeconvert.c.

671 {
672 while (conversions-- > 0) {
673 if (!(conversion[conversions].flags & DO_BREAKDOWN))
674 continue;
675 if (conversion->flags & IS_PARAMETER) {
676 if (SDDS_CheckParameter(SDDSin, conversion->epochName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
677 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
678 conversion->epochIndex = SDDS_GetParameterIndex(SDDSin, conversion->epochName);
679 } else {
680 if (SDDS_CheckColumn(SDDSin, conversion->epochName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
681 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
682 conversion->epochIndex = SDDS_GetColumnIndex(SDDSin, conversion->epochName);
683 }
684 conversion++;
685 }
686}
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.
Definition SDDS_utils.c:474
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.
#define SDDS_ANY_NUMERIC_TYPE
Special identifier used by SDDS_Check*() routines to accept any numeric type.
Definition SDDStypes.h:157

◆ CheckDateConversionElements()

void CheckDateConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 688 of file sddstimeconvert.c.

688 {
689 while (conversions-- > 0) {
690 if (!(conversion[conversions].flags & DO_DATECONVERSION))
691 continue;
692 if (conversion->flags & IS_PARAMETER) {
693 if (SDDS_CheckParameter(SDDSin, conversion->textName, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OK)
694 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
695 conversion->textIndex = SDDS_GetParameterIndex(SDDSin, conversion->textName);
696 } else {
697 if (SDDS_CheckColumn(SDDSin, conversion->textName, NULL, SDDS_STRING, stderr) != SDDS_CHECK_OK)
698 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
699 conversion->textIndex = SDDS_GetColumnIndex(SDDSin, conversion->textName);
700 }
701 if (conversion->textIndex < 0) {
702 fprintf(stderr, "Error: '%s' does not exist in input file.\n", conversion->textName);
703 exit(EXIT_FAILURE);
704 }
705 conversion++;
706 }
707}
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85

◆ CheckEpochConversionElements()

void CheckEpochConversionElements ( SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion,
long conversions )

Definition at line 624 of file sddstimeconvert.c.

624 {
625 while (conversions-- > 0) {
626 if (!(conversion[conversions].flags & DO_EPOCH))
627 continue;
628 if (conversion->flags & IS_PARAMETER) {
629 if (SDDS_CheckParameter(SDDSin, conversion->yearName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK ||
630 (conversion->jDayName &&
631 SDDS_CheckParameter(SDDSin, conversion->jDayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
632 (conversion->dayName &&
633 SDDS_CheckParameter(SDDSin, conversion->dayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
634 (conversion->monthName &&
635 SDDS_CheckParameter(SDDSin, conversion->monthName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
636 SDDS_CheckParameter(SDDSin, conversion->hourName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
637 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
638 conversion->yearIndex = SDDS_GetParameterIndex(SDDSin, conversion->yearName);
639 conversion->hourIndex = SDDS_GetParameterIndex(SDDSin, conversion->hourName);
640 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
641 if (conversion->dayName)
642 conversion->dayIndex = SDDS_GetParameterIndex(SDDSin, conversion->dayName);
643 if (conversion->jDayName)
644 conversion->jDayIndex = SDDS_GetParameterIndex(SDDSin, conversion->jDayName);
645 if (conversion->monthName)
646 conversion->monthIndex = SDDS_GetParameterIndex(SDDSin, conversion->monthName);
647 } else {
648 if (SDDS_CheckColumn(SDDSin, conversion->yearName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK ||
649 (conversion->jDayName &&
650 SDDS_CheckColumn(SDDSin, conversion->jDayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
651 (conversion->dayName &&
652 SDDS_CheckColumn(SDDSin, conversion->dayName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
653 (conversion->monthName &&
654 SDDS_CheckColumn(SDDSin, conversion->monthName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK) ||
655 SDDS_CheckColumn(SDDSin, conversion->hourName, NULL, SDDS_ANY_NUMERIC_TYPE, stderr) != SDDS_CHECK_OK)
656 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
657 conversion->yearIndex = SDDS_GetColumnIndex(SDDSin, conversion->yearName);
658 conversion->hourIndex = SDDS_GetColumnIndex(SDDSin, conversion->hourName);
659 conversion->dayIndex = conversion->jDayIndex = conversion->monthIndex = -1;
660 if (conversion->dayName)
661 conversion->dayIndex = SDDS_GetColumnIndex(SDDSin, conversion->dayName);
662 if (conversion->jDayName)
663 conversion->jDayIndex = SDDS_GetColumnIndex(SDDSin, conversion->jDayName);
664 if (conversion->monthName)
665 conversion->monthIndex = SDDS_GetColumnIndex(SDDSin, conversion->monthName);
666 }
667 conversion++;
668 }
669}

◆ DoColumnBreakdownConversion()

void DoColumnBreakdownConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 935 of file sddstimeconvert.c.

935 {
936 double *hour, *epochTime;
937 short *month, *day, *jDay, *year;
938 char **text;
939 int64_t row, rows;
940
941 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
942 return;
943
944 if (!(epochTime = SDDS_GetColumnInDoubles(SDDSin, conversion->epochName)))
945 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
946
947 hour = NULL;
948 month = day = jDay = year = NULL;
949 text = 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))))
956 SDDS_Bomb("Memory allocation failure");
957
958 for (row = 0; row < rows; row++) {
959 if (text)
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]) ||
962 (text && !TimeEpochToText(text[row], epochTime[row])))
963 SDDS_Bomb("Problem performing time breakdown");
964 }
965
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)))
972 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
973 if (hour)
974 free(hour);
975 if (year)
976 free(year);
977 if (epochTime)
978 free(epochTime);
979 if (jDay)
980 free(jDay);
981 if (month)
982 free(month);
983 if (day)
984 free(day);
985 if (text) {
986 for (row = 0; row < rows; row++)
987 free(text[row]);
988 free(text);
989 }
990}
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.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
double * SDDS_GetColumnInDoubles(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves the data of a specified numerical column as an array of doubles, considering only rows mark...
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
short TimeEpochToBreakdown(short *year, short *jDay, short *month, short *day, double *hour, double epochTime)
Breaks down epoch time into its constituent components.
short TimeEpochToText(char *text, double epochTime)
Converts epoch time to a formatted text string.

◆ DoColumnDateToTimeConversion()

void DoColumnDateToTimeConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 899 of file sddstimeconvert.c.

899 {
900 double hour;
901 double month = 0, day = 0, year = 0, jDay = 0, *epochTime;
902 int64_t row, rows;
903 char **timestr = NULL;
904 struct tm tm = {0};
905 /* Note that tm struct:
906 tm_year: years since 1900
907 tm_mon: months since January (0-11)
908 */
909 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
910 return;
911
912 if (!(timestr = SDDS_GetColumn(SDDSin, conversion->textName)))
913 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
914
915 if (!(epochTime = (double *)malloc(sizeof(*epochTime) * rows)))
916 SDDS_Bomb("Memory allocation failure");
917
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);
921 exit(EXIT_FAILURE);
922 }
923 year = tm.tm_year + 1900;
924 month = tm.tm_mon + 1;
925 day = tm.tm_mday;
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);
928 }
929 if (!SDDS_SetColumnFromDoubles(SDDSout, SDDS_BY_NAME, epochTime, rows, conversion->epochName))
930 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
931 SDDS_FreeStringArray(timestr, rows);
932 free(epochTime);
933}
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.
void * SDDS_GetColumn(SDDS_DATASET *SDDS_dataset, char *column_name)
Retrieves a copy of the data for a specified column, including only rows marked as "of interest".
int32_t SDDS_FreeStringArray(char **string, int64_t strings)
Frees an array of strings by deallocating each individual string.
short TimeBreakdownToEpoch(short year, short jDay, short month, short day, double hour, double *epochTime)
Converts a broken-down time into epoch time.

◆ DoColumnEpochConversion()

void DoColumnEpochConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 863 of file sddstimeconvert.c.

863 {
864 double *hour;
865 double *month, *day, *jDay, *year, *epochTime;
866 int64_t row, rows;
867
868 year = NULL;
869
870 if (!(rows = SDDS_CountRowsOfInterest(SDDSin)))
871 return;
872
873 jDay = month = day = NULL;
874 if (!(hour = SDDS_GetColumnInDoubles(SDDSin, conversion->hourName)) ||
875 !(year = SDDS_GetColumnInDoubles(SDDSin, conversion->yearName)) ||
876 (conversion->jDayName && !(jDay = SDDS_GetColumnInDoubles(SDDSin, conversion->jDayName))) ||
877 (conversion->monthName && !(month = SDDS_GetColumnInDoubles(SDDSin, conversion->monthName))) ||
878 (conversion->dayName && !(day = SDDS_GetColumnInDoubles(SDDSin, conversion->dayName))))
879 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
880
881 if (!(epochTime = (double *)malloc(sizeof(*epochTime) * rows)))
882 SDDS_Bomb("Memory allocation failure");
883
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);
886 if (!SDDS_SetColumnFromDoubles(SDDSout, SDDS_BY_NAME, epochTime, rows, conversion->epochName))
887 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
888 free(hour);
889 free(year);
890 free(epochTime);
891 if (jDay)
892 free(jDay);
893 if (month)
894 free(month);
895 if (day)
896 free(day);
897}

◆ DoParameterBreakdownConversion()

void DoParameterBreakdownConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 806 of file sddstimeconvert.c.

806 {
807 double hour, epochTime;
808 short year, jDay, month, day;
809 char text[30];
810
811 if (!SDDS_GetParameterAsDouble(SDDSin, conversion->epochName, &epochTime))
812 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
813 TimeEpochToBreakdown(&year, &jDay, &month, &day, &hour, epochTime);
814 TimeEpochToText(text, epochTime);
815 if ((conversion->yearName &&
816 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
817 conversion->yearIndex, (double)year, -1)) ||
818 (conversion->dayName &&
819 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
820 conversion->dayIndex, (double)day, -1)) ||
821 (conversion->jDayName &&
822 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
823 conversion->jDayIndex, (double)jDay, -1)) ||
824 (conversion->monthName &&
825 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
826 conversion->monthIndex, (double)month, -1)) ||
827 (conversion->hourName &&
828 !SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE,
829 conversion->hourIndex, (double)hour, -1)) ||
830 (conversion->textName &&
831 !SDDS_SetParameters(SDDSout, SDDS_BY_INDEX | SDDS_PASS_BY_VALUE, conversion->textIndex, text, -1)))
832 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
833}
int32_t SDDS_SetParametersFromDoubles(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
int32_t SDDS_SetParameters(SDDS_DATASET *SDDS_dataset, int32_t mode,...)
double * SDDS_GetParameterAsDouble(SDDS_DATASET *SDDS_dataset, char *parameter_name, double *memory)
Retrieves the value of a specified parameter as a double from the current data table of an SDDS datas...

◆ DoParameterDateToTimeConversion()

void DoParameterDateToTimeConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 835 of file sddstimeconvert.c.

835 {
836 double hour;
837 double month = 0, day = 0, jDay = 0, year, epochTime;
838 char *timestr = NULL;
839 struct tm tm = {0};
840 /* Note that tm struct:
841 tm_year: years since 1900
842 tm_mon: months since January (0-11)
843 */
844
845 if (!SDDS_GetParameter(SDDSin, conversion->textName, &timestr)) {
846 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
847 exit(EXIT_FAILURE);
848 }
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);
851 exit(EXIT_FAILURE);
852 }
853 year = tm.tm_year + 1900;
854 month = tm.tm_mon + 1;
855 day = tm.tm_mday;
856 hour = tm.tm_hour + tm.tm_min / 60.0 + tm.tm_sec / 3600.0;
857
858 TimeBreakdownToEpoch((short)year, (short)jDay, (short)month, (short)day, hour, &epochTime);
859 if (!SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_NAME | SDDS_PASS_BY_VALUE, conversion->epochName, epochTime, NULL))
860 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
861}
void * SDDS_GetParameter(SDDS_DATASET *SDDS_dataset, char *parameter_name, void *memory)
Retrieves the value of a specified parameter from the current data table of a data set.

◆ DoParameterEpochConversion()

void DoParameterEpochConversion ( SDDS_DATASET * SDDSout,
SDDS_DATASET * SDDSin,
TIME_CONVERSION * conversion )

Definition at line 788 of file sddstimeconvert.c.

788 {
789 double hour;
790 double month = 0, day = 0, jDay = 0, year, epochTime;
791
792 jDay = 0;
793 if (!SDDS_GetParameterAsDouble(SDDSin, conversion->hourName, &hour) ||
794 !SDDS_GetParameterAsDouble(SDDSin, conversion->yearName, &year) ||
795 (conversion->jDayName && !SDDS_GetParameterAsDouble(SDDSin, conversion->jDayName, &jDay)) ||
796 (conversion->monthName && !SDDS_GetParameterAsDouble(SDDSin, conversion->monthName, &month)) ||
797 (conversion->dayName && !SDDS_GetParameterAsDouble(SDDSin, conversion->dayName, &day))) {
798 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
799 exit(EXIT_FAILURE);
800 }
801 TimeBreakdownToEpoch((short)year, (short)jDay, (short)month, (short)day, hour, &epochTime);
802 if (!SDDS_SetParametersFromDoubles(SDDSout, SDDS_BY_NAME | SDDS_PASS_BY_VALUE, conversion->epochName, epochTime, NULL))
803 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
804}

◆ InitializeOutput()

void InitializeOutput ( SDDS_DATASET * SDDSout,
char * outputfile,
TIME_CONVERSION * conversion,
long conversions,
SDDS_DATASET * SDDSin,
short columnMajorOrder )

Definition at line 709 of file sddstimeconvert.c.

710 {
711 if (!SDDS_InitializeCopy(SDDSout, SDDSin, outputfile, "w"))
712 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
713 if (columnMajorOrder != -1)
714 SDDSout->layout.data_mode.column_major = columnMajorOrder;
715 else
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) {
720 if ((conversion->epochIndex = SDDS_DefineParameter(SDDSout, conversion->epochName,
721 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, NULL)) < 0)
722 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
723 } else {
724 if ((conversion->epochIndex = SDDS_DefineColumn(SDDSout, conversion->epochName,
725 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, 0)) < 0)
726 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
727 }
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,
732 SDDS_SHORT, NULL)) < 0) ||
733 (conversion->dayName &&
734 (conversion->dayIndex = SDDS_DefineParameter(SDDSout, conversion->dayName, NULL, NULL, "Day of month",
735 NULL, SDDS_SHORT, NULL)) < 0) ||
736 (conversion->monthName &&
737 (conversion->monthIndex = SDDS_DefineParameter(SDDSout, conversion->monthName, NULL, NULL, "Month", NULL,
738 SDDS_SHORT, NULL)) < 0) ||
739 (conversion->jDayName &&
740 (conversion->jDayIndex = SDDS_DefineParameter(SDDSout, conversion->jDayName, NULL, NULL, "Julian day",
741 NULL, SDDS_SHORT, NULL)) < 0) ||
742 (conversion->hourName &&
743 (conversion->hourIndex = SDDS_DefineParameter(SDDSout, conversion->hourName, NULL, NULL, "Hour of day",
744 NULL, SDDS_DOUBLE, NULL)) < 0) ||
745 (conversion->textName &&
746 (conversion->textIndex = SDDS_DefineParameter(SDDSout, conversion->textName, NULL, NULL, "Timestamp",
747 NULL, SDDS_STRING, NULL)) < 0))
748 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
749 } else {
750 if ((conversion->yearName &&
751 (conversion->yearIndex = SDDS_DefineColumn(SDDSout, conversion->yearName, NULL, NULL, "Year", NULL,
752 SDDS_SHORT, 0)) < 0) ||
753 (conversion->dayName &&
754 (conversion->dayIndex = SDDS_DefineColumn(SDDSout, conversion->dayName, NULL, NULL, "Day of month",
755 NULL, SDDS_SHORT, 0)) < 0) ||
756 (conversion->monthName &&
757 (conversion->monthIndex = SDDS_DefineColumn(SDDSout, conversion->monthName, NULL, NULL, "Month", NULL,
758 SDDS_SHORT, 0)) < 0) ||
759 (conversion->jDayName &&
760 (conversion->jDayIndex = SDDS_DefineColumn(SDDSout, conversion->jDayName, NULL, NULL, "Julian day",
761 NULL, SDDS_SHORT, 0)) < 0) ||
762 (conversion->hourName &&
763 (conversion->hourIndex = SDDS_DefineColumn(SDDSout, conversion->hourName, NULL, NULL, "Hour of day",
764 NULL, SDDS_DOUBLE, 0)) < 0) ||
765 (conversion->textName &&
766 (conversion->textIndex = SDDS_DefineColumn(SDDSout, conversion->textName, NULL, NULL, "Timestamp",
767 NULL, SDDS_STRING, 0)) < 0))
768 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
769 }
770 } else {
771 /* Date to time conversion */
772 if (conversion->flags & IS_PARAMETER) {
773 if ((conversion->epochIndex = SDDS_DefineParameter(SDDSout, conversion->epochName,
774 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, NULL)) < 0)
775 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
776 } else {
777 if ((conversion->epochIndex = SDDS_DefineColumn(SDDSout, conversion->epochName,
778 NULL, "s", "Time since start of epoch", NULL, SDDS_DOUBLE, 0)) < 0)
779 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
780 }
781 }
782 conversion++;
783 }
784 if (!SDDS_WriteLayout(SDDSout))
785 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors | SDDS_EXIT_PrintErrors);
786}
int32_t SDDS_InitializeCopy(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source, char *filename, char *filemode)
Definition SDDS_copy.c:40
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.
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37

◆ main()

int main ( int argc,
char ** argv )

Definition at line 428 of file sddstimeconvert.c.

428 {
429 SDDS_DATASET SDDSin, SDDSout;
430 long i_arg, iconv;
431 SCANNED_ARG *s_arg;
432 char *input, *output;
433 TIME_CONVERSION *conversion;
434 long conversions;
435 unsigned long pipeFlags, majorOrderFlag;
436 short columnMajorOrder = -1;
437
439 argc = scanargs(&s_arg, argc, argv);
440 if (argc < 3) {
441 fprintf(stderr, "%s", USAGE);
442 exit(EXIT_FAILURE);
443 }
444
445 input = output = NULL;
446 conversions = 0;
447 conversion = NULL;
448 pipeFlags = 0;
449
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:
454 majorOrderFlag = 0;
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;
465 break;
466 case SET_EPOCH:
467 if (s_arg[i_arg].n_items < 4)
468 SDDS_Bomb("Invalid -epoch syntax");
469 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
470 SDDS_Bomb("Memory allocation failure");
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;
475 if (!scanItemList(&conversion[conversions].flags,
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))
484 SDDS_Bomb("invalid -epoch syntax");
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");
497 conversions++;
498 break;
499 case SET_BREAKDOWN:
500 if (s_arg[i_arg].n_items < 4)
501 SDDS_Bomb("Invalid -breakdown syntax");
502 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
503 SDDS_Bomb("Memory allocation failure");
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;
508 if (!scanItemList(&conversion[conversions].flags,
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))
518 SDDS_Bomb("invalid -breakdown syntax");
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");
526 conversions++;
527 break;
528 case SET_DATE:
529 if (s_arg[i_arg].n_items < 4)
530 SDDS_Bomb("Invalid -dateToTime syntax");
531 if (!(conversion = SDDS_Realloc(conversion, sizeof(*conversion) * (conversions + 1))))
532 SDDS_Bomb("Memory allocation failure");
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;
538 if (!scanItemList(&conversion[conversions].flags,
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))
543 SDDS_Bomb("invalid -dateToTime syntax");
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");
551 conversions++;
552 break;
553 case SET_PIPE:
554 if (!processPipeOption(s_arg[i_arg].list + 1, s_arg[i_arg].n_items - 1, &pipeFlags))
555 SDDS_Bomb("Invalid -pipe syntax");
556 break;
557 default:
558 fprintf(stderr, "Error: Unknown option: %s\n", s_arg[i_arg].list[0]);
559 SDDS_Bomb(NULL);
560 break;
561 }
562 } else {
563 if (!input)
564 input = s_arg[i_arg].list[0];
565 else if (!output)
566 output = s_arg[i_arg].list[0];
567 else {
568 fprintf(stderr, "Error: Argument '%s' is invalid: too many filenames (sddstimeconvert)\n", s_arg[i_arg].list[0]);
569 exit(EXIT_FAILURE);
570 }
571 }
572 }
573
574 processFilenames("sddstimeconvert", &input, &output, pipeFlags, 0, NULL);
575
576 if (!SDDS_InitializeInput(&SDDSin, input)) {
577 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
578 exit(EXIT_FAILURE);
579 }
580
581 CheckEpochConversionElements(&SDDSin, conversion, conversions);
582 CheckBreakdownConversionElements(&SDDSin, conversion, conversions);
583 CheckDateConversionElements(&SDDSin, conversion, conversions);
584
585 InitializeOutput(&SDDSout, output, conversion, conversions, &SDDSin, columnMajorOrder);
586
587 while (SDDS_ReadPage(&SDDSin) > 0) {
588 if (!SDDS_CopyPage(&SDDSout, &SDDSin)) {
589 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
590 exit(EXIT_FAILURE);
591 }
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);
596 else
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);
601 else
602 DoColumnBreakdownConversion(&SDDSout, &SDDSin, conversion + iconv);
603 } else {
604 /* Convert date string to double time */
605 if (conversion[iconv].flags & IS_PARAMETER)
606 DoParameterDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
607 else
608 DoColumnDateToTimeConversion(&SDDSout, &SDDSin, conversion + iconv);
609 }
610 }
611 if (!SDDS_WritePage(&SDDSout)) {
612 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
613 exit(EXIT_FAILURE);
614 }
615 }
616 if (!SDDS_Terminate(&SDDSin) || !SDDS_Terminate(&SDDSout)) {
617 SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors);
618 exit(EXIT_FAILURE);
619 }
620
621 return EXIT_SUCCESS;
622}
int32_t SDDS_CopyPage(SDDS_DATASET *SDDS_target, SDDS_DATASET *SDDS_source)
Definition SDDS_copy.c:578
int32_t SDDS_InitializeInput(SDDS_DATASET *SDDS_dataset, char *filename)
Definition SDDS_input.c:50
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_ReadPage(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:743
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)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:357
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:391
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.

◆ parseDateTime()

static const char * parseDateTime ( const char * input,
const char * format,
struct tm * value )
static

Definition at line 423 of file sddstimeconvert.c.

423 {
424 return strptime(input, format, value);
425}