Esempio n. 1
0
/*
 * Compute the conversion factor between two unit-structures.
 */
int
utConvert(
    const utUnit	*from,
    const utUnit	*to,
    double		*slope,
    double		*intercept)
{
    int			status;
    cv_converter*	converter = ut_get_converter(from->unit2, to->unit2);

    if (converter == NULL) {
	status = ut_get_status();

	if (status == UT_BAD_ARG) {
	    status = UT_EINVALID;
	}
	else if (status == UT_NOT_SAME_SYSTEM) {
	    status = UT_ENOINIT;
	}
	else if (status == UT_MEANINGLESS) {
	    status = UT_ECONVERT;
	}
	else {
	    status = UT_EALLOC;
	}
    }
    else {
	*intercept = cv_convert_double(converter, 0.0);
	*slope = cv_convert_double(converter, 1.0) - *intercept;
	status = 0;
    }
    return status;
}
Esempio n. 2
0
static double
compositeConvertDouble(
    const cv_converter* const	conv,
    const double		value)
{
    return
        cv_convert_double(conv->composite.second,
                          cv_convert_double(((CompositeConverter*)conv)->first, value));
}
Esempio n. 3
0
NFtimeLine_p NCtimeLineExpand (NCaxis_p timeAxis, NFtime_p beginTime, NFtime_p endTime, cv_converter *cvConverter, NFtimeLine_p timeLine) {
	size_t timeStep = 0;
	NFtime_p timePtr = (NFtime_p) NULL;
	double variable;

	if ((timePtr = (NFtimeCreate ())) == (NFtime_p) NULL) {
		CMmsgPrint (CMmsgAppError,"Time object creation error in %s:%d!\n",__FILE__,__LINE__);
		return ((NFtimeLine_p) NULL);
	}
	if (timeLine == (NFtimeLine_p) NULL) timeLine = NFtimeLineCreate ();
	
	for (timeStep = 0;timeStep < timeAxis->N; ++timeStep) {
		variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2]);
		if (NFtimeSetFromVariable (timePtr, variable) == false) {
			CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__);
			NFtimeLineFree (timeLine);
			return ((NFtimeLine_p) NULL);
		}
		if (NFtimeCompare (beginTime, timePtr) <= 0) break;
	}
	if (timeStep < timeAxis->N) {
		for ( ;timeStep < timeAxis->N; ++timeStep) {
			variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2]);
			if (NFtimeSetFromVariable (timePtr, variable) == false) {
				CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__);
				NFtimeLineFree (timeLine);
				return ((NFtimeLine_p) NULL);
			}
			if (NFtimeLineAddStep (timeLine,timePtr) == false) {
				CMmsgPrint (CMmsgAppError, "Time step insertion error in %s:%d!\n",__FILE__,__LINE__);
				return ((NFtimeLine_p) NULL);
			}
			variable = cv_convert_double (cvConverter, timeAxis->Bounds [timeStep * 2 + 1]);
			if (NFtimeSetFromVariable (timePtr, variable) == false) {
				CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__);
				NFtimeLineFree (timeLine);
				return ((NFtimeLine_p) NULL);
			}
			if (NFtimeCompare (endTime, timePtr) < 0) break;			
		}
		if (NFtimeSetFromVariable (timePtr, variable) == false) {
			CMmsgPrint (CMmsgAppError, "Time reading error in %s:%d!\n",__FILE__,__LINE__);
			NFtimeLineFree (timeLine);
			return ((NFtimeLine_p) NULL);
		}
		NFtimeCopy (timePtr,timeLine->TimeLine [timeLine->TimeStepNum]);
	}
	else {
		CMmsgPrint (CMmsgAppError, "Time axis outside of time period in %s:%d!\n",__FILE__,__LINE__);
		NFtimeLineFree (timeLine);
		return ((NFtimeLine_p) NULL);
	}
	if (timePtr != (NFtime_p) NULL) NFtimeFree (timePtr);
	return (timeLine);
}
Esempio n. 4
0
/*
 *	Convert a date into a temporal value.  The date is assumed to
 *	use the Gregorian calendar if on or after noon, October 15, 1582;
 *	otherwise, the date is assumed to use the Julian calendar.
 */
int
utInvCalendar(
    int			year,
    int			month,
    int			day,
    int			hour,
    int			minute,
    double		second,
    const utUnit	*unit,
    double		*value)
{
    int		status = 0;	/* success */

    cv_converter* converter = ut_get_converter(encodedTimeUnit, unit->unit2);
    if (converter == NULL) {
	status = encodedTimeUnit == NULL ? UT_ENOINIT : UT_EINVALID;
    }
    else {
	double	encodedTime =
	    ut_encode_time(year, month, day, hour, minute, second);

	*value = cv_convert_double(converter, encodedTime);
	cv_free(converter);
    }
    return status;
}
Esempio n. 5
0
/*
 * Convert a temporal value into a UTC Gregorian date and time.
 */
int
utCalendar(
    double		value,
    const utUnit	*unit,
    int			*year,
    int			*month,
    int			*day,
    int			*hour,
    int			*minute,
    float		*second)
{
    int		status = 0;	/* success */

    cv_converter* converter = ut_get_converter(unit->unit2, encodedTimeUnit);
    if (converter == NULL) {
	status = encodedTimeUnit == NULL ? UT_ENOINIT : UT_EINVALID;
    }
    else {
	double	encodedTime = cv_convert_double(converter, value);
	double	sec, res;

	ut_decode_time(encodedTime, year, month, day, hour, minute, &sec, &res);
	*second = (float)sec;
	cv_free(converter);
    }
    return status;
}
Esempio n. 6
0
 void udunits::convert(viennamini::dense_values& values, std::string const& source_unit, std::string const& target_unit)
 {
   cv_converter* converter = this->get_converter(source_unit, target_unit);
   for(viennamini::dense_values::iterator iter = values.begin(); iter != values.end(); iter++)
     *iter = cv_convert_double(converter, *iter);
   cv_free(converter);
 }
Esempio n. 7
0
value ml_cv_convert_double( value converter, value x ) {
    CAMLparam2( converter, x );

    double result;
    result = cv_convert_double( UD_cv_converter_val( converter ), Double_val( x ) );

    CAMLreturn( caml_copy_double( result ) );
}
Esempio n. 8
0
void harp_unit_converter_convert_array(const harp_unit_converter *unit_converter, long num_values, double *value)
{
    double *value_end;

    for (value_end = value + num_values; value != value_end; value++)
    {
        *value = cv_convert_double(unit_converter->converter, *value);
    }
}
Esempio n. 9
0
// MEMBER FUNCTION
int DPC_UnitConvDataStream::get(double* timestamp, double* paramValue) {
    double time, value;
    int ret ;

    ret = source_ds->get(&time, &value) ;
    *timestamp  = time;
    *paramValue = cv_convert_double(cf, value) ;;
    return ret ;
}
Esempio n. 10
0
// MEMBER FUNCTION
int DPC_UnitConvDataStream::peek(double* timestamp, double* paramValue) {
    double time, value;

    if (! source_ds->peek(&time, &value) ) {
        *timestamp  = time;
        *paramValue = cv_convert_double(cf, value) ;;
        return (0);
    } else {
        return (-1);
    }
}
Esempio n. 11
0
/*==========================================================================================
 * The user specified some origin to the time units. For example, if the units string
 * were "days since 2005-10-15", then the origin date is 2005-10-15.  This routine
 * deduces the specified origin date from the passed units structure 
 */
static void get_origin( ut_unit *dataunits, int *y0, int *mon0, int *d0, int *h0, int *min0, double *s0 )
{
	double		s0lib, rez, tval, tval_conv, resolution;
	cv_converter	*conv_user_date_to_ref_date;
	ut_unit		*tmpu;
	int		y0lib, mon0lib, d0lib, h0lib, min0lib;
	char		ustr[1024];

	static ut_unit 	*udu_ref_date=NULL;	/* Saved between invocations */

	if( udu_ref_date == NULL ) {

		/* Make a timestamp units that refers to the udunits2 library's intrinsic
		 * time origin.  The first thing we do is parse a timestampe unit
		 * (any old timestamp unit) and immediately discard the result, to account
		 * for a bug in the udunits-2 library that fails to set the library's
		 * time origin unless this step is done first.  Without this, a call to
		 * ut_decode_time with tval==0 returns year=-4713 rather than 2001.
		 */
		if( (tmpu = ut_parse( ut_get_system(dataunits), "days since 2010-01-09", UT_ASCII )) == NULL ) {
			fprintf( stderr, "Internal error in routnie utCalendar2/get_origin: failed to parse temp timestamp string\n" );
			exit(-1);
			}
		ut_free( tmpu );

		tval = 0.0;
		ut_decode_time( tval, &y0lib, &mon0lib, &d0lib, &h0lib, &min0lib, &s0lib, &rez );
		sprintf( ustr, "seconds since %04d-%02d-%02d %02d:%02d:%f",
			y0lib, mon0lib, d0lib, h0lib, min0lib, s0lib );
		udu_ref_date = ut_parse( ut_get_system(dataunits), ustr, UT_ASCII );
		if( udu_ref_date == NULL ) {	
			fprintf( stderr, "internal error in routine utCalendar2/get_origin: could not parse origin string \"%s\"\n",
				ustr );
			exit(-1);
			}
		}

	/* Get converter from passed units to the library's intrinsic time units */
	conv_user_date_to_ref_date = ut_get_converter( dataunits, udu_ref_date );

	/* convert tval=0 to ref date */
	tval = 0.0;
	tval_conv = cv_convert_double( conv_user_date_to_ref_date, tval );

	/* Now decode the converted value */
	ut_decode_time( tval_conv, y0, mon0, d0, h0, min0, s0, &resolution );

	cv_free( conv_user_date_to_ref_date );
}
Esempio n. 12
0
void cmor_convert_value( char *units, char *ctmp, double *tmp ) {
/* -------------------------------------------------------------------- */
/*      Local variables                                                 */
/* -------------------------------------------------------------------- */
    ut_unit *user_units = NULL, *cmor_units = NULL;
    cv_converter *ut_cmor_converter = NULL;
    double value;
    char msg[CMOR_MAX_STRING];


    cmor_add_traceback( "cmor_convert_value" );

    value = *tmp;
    if( units[0] != '\0' ) {
	cmor_prep_units( ctmp, units, &cmor_units, &user_units,
			 &ut_cmor_converter );
	*tmp = cv_convert_double( ut_cmor_converter, value );
	if( ut_get_status(  ) != UT_SUCCESS ) {
	    snprintf( msg, CMOR_MAX_STRING,
		      "Udunits: Error converting units from %s to %s",
		      units, ctmp );
	    cmor_handle_error( msg, CMOR_CRITICAL );
	}

	cv_free( ut_cmor_converter );
	if( ut_get_status(  ) != UT_SUCCESS ) {
	    snprintf( msg, CMOR_MAX_STRING,
		      "Udunits: Error freeing converter" );
	    cmor_handle_error( msg, CMOR_CRITICAL );
	}
	ut_free( cmor_units );
	if( ut_get_status(  ) != UT_SUCCESS ) {
	    snprintf( msg, CMOR_MAX_STRING,
		      "Udunits: Error freeing units" );
	    cmor_handle_error( msg, CMOR_CRITICAL );
	}
	ut_free( user_units );
	if( ut_get_status(  ) != UT_SUCCESS ) {
	    snprintf( msg, CMOR_MAX_STRING,
		      "Udunits: Error freeing units" );
	    cmor_handle_error( msg, CMOR_CRITICAL );
	}
    } else
	*tmp = value;
    cmor_pop_traceback(  );
    return;
}
Esempio n. 13
0
double harp_unit_converter_convert(const harp_unit_converter *unit_converter, double value)
{
    return cv_convert_double(unit_converter->converter, value);
}
Esempio n. 14
0
/*!
 * Returns \a value (which is expressed in the converter's from unit) converted
 * to this converter's to unit. If the converter is invalid, the behaviour is undefined.
 */
qreal UdUnitConverter::convert(qreal value)
{
    return cv_convert_double(m_converter, value);
}
Esempio n. 15
0
int udu_calc_tgran( int fileid, NCVar *v, int dimid )
{
	ut_unit		*unit, *seconds;
	int		ii, retval;
	int		verbose, has_bounds;
	double		tval0_user, tval0_sec, tval1_user, tval1_sec, delta_sec, bound_min, bound_max;
	char		cval0[1024], cval1[1024];
	nc_type 	rettype;
	size_t		cursor_place[MAX_NC_DIMS];
	cv_converter	*convert_units_to_sec;

	NCDim *d;
	d = *(v->dim+dimid);

	/* Not enough data to analyze */
	if( d->size < 3 )
		return(TGRAN_SEC);

	verbose = 0;

	if( ! valid_udunits_pkg )
		return( 0 );

	if( (unit = ut_parse( unitsys, d->units, UT_ASCII )) == NULL ) {
		fprintf( stderr, "internal error: udu_calc_tgran with invalid unit string: %s\n",
			d->units );
		exit( -1 );
		}

	if( (seconds = ut_parse( unitsys, "seconds", UT_ASCII )) == NULL ) {
		fprintf( stderr, "internal error: udu_calc_tgran can't parse seconds unit string!\n" );
		exit( -1 );
		}
	
	/* Get converter to convert from "units" to "seconds" */
	if( ut_are_convertible( unit, seconds ) == 0 ) {
		/* Units are not convertible */
		return( TGRAN_SEC );
		}
	if( (convert_units_to_sec = ut_get_converter( unit, seconds )) == NULL ) {
		/* This shouldn't happen */
		return( TGRAN_SEC );
		}

	/* Get a delta time to analyze */
	for( ii=0L; ii<v->n_dims; ii++ )
		cursor_place[ii] = (int)((*(v->size+ii))/2.0);
	rettype = fi_dim_value( v, dimid, 1L, &tval0_user, cval0, &has_bounds, &bound_min, &bound_max, cursor_place );
	rettype = fi_dim_value( v, dimid, 2L, &tval1_user, cval1, &has_bounds, &bound_min, &bound_max, cursor_place );

	/* Convert time vals from user units to seconds */
	tval0_sec = cv_convert_double( convert_units_to_sec, tval0_user );
	tval1_sec = cv_convert_double( convert_units_to_sec, tval1_user );

	/* Free our units converter storage */
	cv_free( convert_units_to_sec );

	delta_sec = fabs(tval1_sec - tval0_sec);
	
	if( verbose ) 
		printf( "units: %s  t1: %lf t2: %lf delta-sec: %lf\n", d->units, tval0_user, tval1_user, delta_sec );

	if( delta_sec < 57. ) {
		if(verbose)
			printf("data is TGRAN_SEC\n");
		retval = TGRAN_SEC;
		}
	else if( delta_sec < 3590. ) {
		if(verbose)
			printf("data is TGRAN_MIN\n");
		retval = TGRAN_MIN;
		}
	else if( delta_sec < 86300. ) {
		if(verbose)
			printf("data is TGRAN_HOUR\n");
		retval = TGRAN_HOUR;
		}
	else if( delta_sec < 86395.*28. ) {
		if(verbose)
			printf("data is TGRAN_DAY\n");
		retval = TGRAN_DAY;
		}
	else if(  delta_sec < 86395.*365. ) {
		if(verbose)
			printf("data is TGRAN_MONTH\n");
		retval = TGRAN_MONTH;
		}
	else
		{
		if(verbose)
			printf("data is TGRAN_YEAR\n");
		retval = TGRAN_YEAR;
		}

	return( retval );
}
Esempio n. 16
0
static int
handleRequest(void)
{
    int		success = 0;

    if (getInputValue()) {
	if (getOutputRequest()) {
	    if (_wantDefinition) {
                char	        buf[256];
                ut_unit*        unit = ut_scale(_haveUnitAmount, _haveUnit);
                int	        nbytes = ut_format(unit, buf, sizeof(buf),
                        _formattingOptions);

                if (nbytes >= sizeof(buf)) {
                    errMsg("Resulting unit specification is too long");
                }
                else if (nbytes >= 0) {
                    buf[nbytes] = 0;

                    (void)printf("    %s\n", buf);
                }

                ut_free(unit);
	    }
	    else if (!ut_are_convertible(_wantUnit, _haveUnit)) {
		errMsg("Units are not convertible");
	    }
	    else {
		cv_converter*	conv = ut_get_converter(_haveUnit, _wantUnit);

		if (conv == NULL) {
		    errMsg("Couldn't get unit converter");
		}
		else {
                    char        haveExp[_POSIX_MAX_INPUT+1];
                    char        exp[_POSIX_MAX_INPUT+1];
                    char        whiteSpace[] = " \t\n\r\f\v\xa0";
		    int	        needsParens =
                        strpbrk(_wantSpec, whiteSpace) != NULL;
                    int         n;

		    (void)printf(
			needsParens
			    ? "    %g %s = %g (%s)\n"
			    : "    %g %s = %g %s\n",
                        _haveUnitAmount,
			_haveUnitSpec,
			cv_convert_double(conv, _haveUnitAmount),
                        _wantSpec);

                    (void)sprintf(haveExp,
                        strpbrk(_haveUnitSpec, whiteSpace) ||
                                strpbrk(_haveUnitSpec, "/")
                            ? "(x/(%s))"
                            : "(x/%s)",
                        _haveUnitSpec);

                    n = cv_get_expression(conv, exp, sizeof(exp), haveExp);

                    if (n >= 0)
                        (void)printf(
                            strpbrk(_wantSpec, whiteSpace) ||
                                    strpbrk(_wantSpec, "/")
                                ?  "    x/(%s) = %*s\n"
                                :  "    x/%s = %*s\n",
                        _wantSpec, n, exp);

                    cv_free(conv);
		}
	    }

	    success = 1;
	}
    }

    return success;
}
Esempio n. 17
0
/*========================================================================================
 * Turn the passed Y/M/D date into a value in the user's units
 */
int utInvCalendar2_cal( int year, int month, int day, int hour, int minute, double second,
	ut_unit *user_unit, double *value, const char *calendar_name )
{
	int	jday, ierr, diff_in_days;
	double	fdiff_in_days, val_days, val_partdays, fdiff_in_partdays, fpartday;
	calcalcs_cal *cal2use;

	/* Following vars are static and retained between invocations for efficiency */
	static	ut_unit *prev_units=NULL;
	static int	y0, mon0, d0, h0, min0, jday0;
	static double	s0, fpartday0;
	static	cv_converter *conv_days_to_user_units=NULL;
	static char 	*prev_calendar=NULL;

	if( have_initted == 0 ) 
		initialize( ut_get_system(user_unit) );

	/* Get the calendar we will be using, based on the passed name
	 */
	cal2use = getcal( calendar_name );
	if( cal2use == NULL ) {
		unknown_cal_emit_warning( calendar_name );
		cal2use = getcal( "Standard" );
		}

	if( (prev_units != NULL) && (prev_calendar != NULL) 
			&& (strcmp(prev_calendar,cal2use->name)==0) 
			&& (ut_compare( prev_units, user_unit ) == 0)) {
		/* Units are same as used last call */
		}
	else
		{
		if( prev_units != NULL )
			ut_free( prev_units );

		if( prev_calendar != NULL )
			free( prev_calendar );

		if( conv_days_to_user_units != NULL ) 
			cv_free( conv_days_to_user_units );

		/* Get origin day of the data units */
		get_origin( user_unit, &y0, &mon0, &d0, &h0, &min0, &s0 );	/* Note: static vars */

		/* Convert the origin day to Julian Day number in the specified calendar */
		if( (ierr = ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) {
			fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) );
			return( UT_EINVALID );
			}

		/* Get the origin's HMS in fractional (floating point) part of a Julian day */
		fpartday0 = (double)h0/24.0 + (double)min0/1440.0 + s0/86400.0;

		/* Get converter for turning days into user's units */
		conv_days_to_user_units = get_day_to_user_converter( user_unit, y0, mon0, d0, h0, min0, s0 );

		/* Save these units so we can reuse our time-consuming
		 * calculations next time if they are the same units
		 */
		prev_units = ut_clone( user_unit );
		if( ut_compare( prev_units, user_unit ) != 0 ) {
			fprintf( stderr, "error, internal error in udunits2 library found in routine utInvCalendar2: a clone of the user's units does not equal the original units!\n" );
			exit(-1);
			}

		prev_calendar = (char *)malloc( sizeof(char) * (strlen(cal2use->name)+1 ));
		strcpy( prev_calendar, cal2use->name );
		}

	/* Turn passed date into a Julian day */
	if( (ierr = ccs_date2jday( cal2use, year, month, day, &jday )) != 0 ) {
		fprintf( stderr, "Error in utInvCalendar2: %s\n", ccs_err_str(ierr) );
		return( UT_EINVALID );
		}

	/* jday and jday0 can be very large and nearly equal, so we difference
	 * them first to keep the precision high
	 */
	diff_in_days = jday - jday0;
	fdiff_in_days = (double)diff_in_days;

	/* Get the fractional (floating point) part of a Julian day difference
	 */
	fpartday = (double)hour/24.0 + (double)minute/1440.0 + second/86400.0;
	fdiff_in_partdays = fpartday - fpartday0;

	/* Convert days and partial days to user's units */
	val_days     = cv_convert_double( conv_days_to_user_units, fdiff_in_days     );
	val_partdays = cv_convert_double( conv_days_to_user_units, fdiff_in_partdays );

	/* Hopefully this will minimize the roundoff errors */
	*value = val_days + val_partdays;

	return(0);
}
Esempio n. 18
0
 void udunits::convert(viennamini::numeric& value, std::string const& source_unit, std::string const& target_unit)
 {
   cv_converter* converter = this->get_converter(source_unit, target_unit);
   value = cv_convert_double(converter, value);
   cv_free(converter);
 }
Esempio n. 19
0
/*========================================================================================
 * Turns the passed value into a Y/M/D date 
 */
int utCalendar2_cal( double val, ut_unit *dataunits, int *year, int *month, int *day, int *hour,
                                int *minute, double *second, const char *calendar_name )
{

	int	jdnew, ndinc, ierr, iorig, iround;
	double	fdays, extra_seconds, tot_extra_seconds;
	int	ndays;
	calcalcs_cal	*cal2use;

	/* Following vars are saved between invocations and reused if the
	 * passed units are the same as last time.
	 */
	static	ut_unit *prev_units=NULL;
	static	cv_converter *conv_user_units_to_days=NULL;
	static	int	y0, mon0, d0, h0, min0, jday0;
	static	double  s0, extra_seconds0;
	static	char *prev_calendar=NULL;

	if( dataunits == NULL ) {
		fprintf( stderr, "Error, utCalendar2 passed a NULL units\n" );
		return( UT_ENOINIT );
		}

	if( have_initted == 0 ) 
		initialize( ut_get_system(dataunits) );

	/* Get the calendar we will be using, based on the passed name
	 */
	cal2use = getcal( calendar_name );
	if( cal2use == NULL ) {
		unknown_cal_emit_warning( calendar_name );
		cal2use = getcal( "Standard" );
		}

	/* See if we are being passed the same units and calendar as last time.  If so,
	 * we can optimize by not recomputing all this junk 
	 */
	if( (prev_units != NULL) && (prev_calendar != NULL) 
			&& (strcmp(prev_calendar,cal2use->name)==0) 
			&& (ut_compare( prev_units, dataunits ) == 0)) {
		/* Units and calendar are same as used last call */
		}
	else
		{
		/* Units/calendar combo are different from previously saved units, must redo calcs */

		if( prev_units != NULL ) 
			ut_free( prev_units );

		if( prev_calendar != NULL )
			free( prev_calendar );

		/* Get origin day of the data units */
		get_origin( dataunits, &y0, &mon0, &d0, &h0, &min0, &s0 );	/* Note: static vars */

		/* Number of seconds into the specified origin day */
		extra_seconds0 = h0*3600.0 + min0*60.0 + s0;			/* Note: static vars */

		/* Convert the origin day to Julian Day number in the specified calendar */
		if( (ierr = ccs_date2jday( cal2use, y0, mon0, d0, &jday0 )) != 0 ) {
			fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) );
			return( UT_EINVALID );
			}

		/* Get converter from user-specified units to "days" */
		if( conv_user_units_to_days != NULL ) 
			cv_free( conv_user_units_to_days );
		conv_user_units_to_days = get_user_to_day_converter( dataunits, y0, mon0, d0, h0, min0, s0 );

		/* Save these units so we can reuse our time-consuming
		 * calculations next time if they are the same units
		 */
		prev_units = ut_clone( dataunits );
		if( ut_compare( prev_units, dataunits ) != 0 ) {
			fprintf( stderr, "error, internal error in udunits2 library found in routine utCalendar2: a clone of the user's units does not equal the original units!\n" );
			exit(-1);
			}

		prev_calendar = (char *)malloc( sizeof(char) * (strlen(cal2use->name)+1 ));
		strcpy( prev_calendar, cal2use->name );
		}

	/* Convert user value of offset to floating point days */
	fdays = cv_convert_double( conv_user_units_to_days, val );

	/* Get integer number of days and seconds past that */
	ndays = fdays;	
	extra_seconds = (fdays - ndays)*86400.0;

	/* Get new Julian day */
	jdnew = jday0 + ndays;

	/* Handle the sub-day part */
	tot_extra_seconds = extra_seconds0 + extra_seconds;
	ndinc = tot_extra_seconds / 86400.0;
	jdnew += ndinc;
	tot_extra_seconds -= ndinc*86400.0;
	if( tot_extra_seconds < 0.0 ) {
		tot_extra_seconds += 86400.0;
		jdnew--;
		}

	/* Convert to a date */
	if( (ierr = ccs_jday2date( cal2use, jdnew, year, month, day )) != 0 ) {
		fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) );
		return( UT_EINVALID );
		}

	*hour = tot_extra_seconds / 3600.0;
	tot_extra_seconds -= *hour * 3600.0;
	*minute = tot_extra_seconds / 60.0;
	tot_extra_seconds -= *minute * 60.0;
	*second = tot_extra_seconds;

	/* Handle the rouding issues */
	iorig  = *second;			/* Integer conversion */
	iround = *second + sec_rounding_value;	
	if( iround > iorig ) {
		/* printf( "rounding alg invoked, orig date: %04d-%02d-%02d %02d:%02d:%.20lf\n", *year, *month, *day, *hour, *minute, *second ); */
		*second = (double)iround;
		if( *second >= 60.0 ) {
			*second -= 60.0;
			*minute += 1.0;
			if( *minute >= 60.0 ) {
				*minute -= 60.0;
				*hour += 1.0;
				if( *hour >= 24.0 ) {
					*hour -= 24.0;
					if( (ierr = ccs_jday2date( cal2use, jdnew+1, year, month, day )) != 0 ) {
						fprintf( stderr, "Error in utCalendar2: %s\n", ccs_err_str(ierr) );
						return( UT_EINVALID );
						}
					}
				}
			}
		/* printf( "after rounding alg here is new date: %04d-%02d-%02d %02d:%02d:%02.20lf\n", *year, *month, *day, *hour, *minute, *second ); */
		}

	return(0);
}
Esempio n. 20
0
int /* [rcd] Return code */
nco_cln_clc_dff /* [fnc] UDUnits2 Compute difference between two coordinate units */
(const char *fl_unt_sng, /* I [ptr] units attribute string from disk */
 const char *fl_bs_sng, /* I [ptr] units attribute string from disk */
 double crr_val,
 double *og_val) /* O [] Difference between two units strings */
{
  const char fnc_nm[]="nco_cln_clc_dff()"; /* [sng] Function name */
  
  cv_converter *ut_cnv; /* UDUnits converter */

  int ut_rcd; /* [enm] UDUnits2 status */
  
  ut_system *ut_sys;
  ut_unit *ut_sct_in; /* [sct] UDUnits structure, input units */
  ut_unit *ut_sct_out; /* [sct] UDUnits structure, output units */
  
  /* Quick return if units identical */
  if(!strcasecmp(fl_unt_sng,fl_bs_sng)){
    *og_val=crr_val;  
    return NCO_NOERR;
  } /* end if */
  
  /* When empty, ut_read_xml() uses environment variable UDUNITS2_XML_PATH, if any
     Otherwise it uses default initial location hardcoded when library was built */
  if(nco_dbg_lvl_get() >= nco_dbg_vrb) ut_set_error_message_handler(ut_write_to_stderr); else ut_set_error_message_handler(ut_ignore);
  ut_sys=ut_read_xml(NULL);
  if(ut_sys == NULL){
    (void)fprintf(stdout,"%s: %s() failed to initialize UDUnits2 library\n",nco_prg_nm_get(),fnc_nm);
    return NCO_ERR; /* Failure */
  } /* end if err */ 
  
  /* Units string to convert from */
  ut_sct_in=ut_parse(ut_sys,fl_unt_sng,UT_ASCII); 
  if(!ut_sct_in){ /* Problem with 'units' attribute */
    ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */
    if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"ERROR: empty units attribute string\n");
    if(ut_rcd == UT_SYNTAX) (void)fprintf(stderr,"ERROR: units attribute \"%s\" has a syntax error\n",fl_unt_sng);
    if(ut_rcd == UT_UNKNOWN) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is not listed in UDUnits2 SI system database\n",fl_unt_sng);
    return NCO_ERR; /* Failure */
  } /* endif coordinate on disk has no units attribute */

  /* Units string to convert to */
  ut_sct_out=ut_parse(ut_sys,fl_bs_sng,UT_ASCII); 
  if(!ut_sct_out){ /* Problem with 'units' attribute */
    ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */
    if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"ERROR: Empty units attribute string\n");
    if(ut_rcd == UT_SYNTAX) (void)fprintf(stderr,"ERROR: units attribute  \"%s\" has a syntax error\n",fl_bs_sng);
    if(ut_rcd == UT_UNKNOWN) (void)fprintf(stderr,"ERROR: units attribute \"%s\" is not listed in UDUnits2 SI system database\n",fl_bs_sng);
    return NCO_ERR; /* Failure */
  } /* endif */

  /* Create converter */
  ut_cnv=ut_get_converter(ut_sct_in,ut_sct_out); /* UDUnits converter */
  if(!ut_cnv){
    ut_rcd=ut_get_status(); /* [enm] UDUnits2 status */
    if(ut_rcd == UT_BAD_ARG) (void)fprintf(stderr,"WARNING: One of units, %s or %s, is NULL\n",fl_bs_sng,fl_unt_sng);
    if(ut_rcd == UT_NOT_SAME_SYSTEM) (void)fprintf(stderr,"WARNING: Units %s and %s belong to different unit systems\n",fl_bs_sng,fl_unt_sng);
    if(ut_rcd == UT_MEANINGLESS) (void)fprintf(stderr,"WARNING: Conversion between user-specified unit \"%s\" and file units \"%s\" is meaningless\n",fl_bs_sng,fl_unt_sng);
    return NCO_ERR; /* Failure */
  } /* endif */

  /* Convert */
  *og_val=cv_convert_double(ut_cnv,crr_val);
  
  if(nco_dbg_lvl_get() >= nco_dbg_var) fprintf(stderr, "%s: INFO %s() reports conversion between systems \"%s\" and \"%s\" is %f\n",nco_prg_nm_get(),fnc_nm,fl_unt_sng,fl_bs_sng,*og_val);

  ut_free(ut_sct_in);
  ut_free(ut_sct_out);
  cv_free(ut_cnv);
  ut_free_system(ut_sys); /* Free memory taken by UDUnits library */

  return NCO_NOERR;
}  /* end UDUnits2 nco_cln_clc_dff() */