1UDUNITS(3) UNIDATA LIBRARY FUNCTIONS UDUNITS(3)
2
3
4
6 udunits, utInit, utScan, utCalendar, utInvCalendar, utConvert, utPrint,
7 utIsTime, utHasOrigin, utClear, utCopy, utScale, utDivide, utInvert,
8 utMultiply, utRaise, utTerm - Unidata units library
9
11 cc -Iunidata_inc ...
12
13 #include <udunits.h>
14
15 int utInit(
16 const char *path);
17
18 int utIsInit();
19
20 int utScan(
21 const char *spec,
22 utUnit *unit);
23
24 int utCalendar(
25 double value;
26 utUnit *unit,
27 int *year,
28 int *month,
29 int *day,
30 int *hour,
31 int *minute,
32 float *second);
33
34 int utInvCalendar(
35 int year,
36 int month,
37 int day,
38 int hour,
39 int minute,
40 double second,
41 utUnit *unit,
42 double *value);
43
44 int utConvert(
45 const utUnit *from,
46 const utUnit *to,
47 double *slope,
48 double *intercept);
49
50 int *utPrint(
51 const utUnit *unit,
52 char **s);
53
54 utUnit *utClear(
55 utUnit *unit);
56
57 int *utIsTime(
58 const utUnit *unit);
59
60 int *utHasOrigin(
61 const utUnit *unit);
62
63 utUnit *utCopy(
64 const utUnit *source,
65 utUnit *dest);
66
67 utUnit *utScale(
68 utUnit *source,
69 double factor,
70 utUnit *result);
71
72 utUnit *utDivide(
73 utUnit *numer,
74 utUnit *denom,
75 utUnit *result);
76
77 utUnit *utInvert(
78 utUnit *source,
79 utUnit *result);
80
81 utUnit *utMultiply(
82 utUnit *term1,
83 utUnit *term2,
84 utUnit *result);
85
86 utUnit *utRaise(
87 utUnit *source,
88 int power,
89 utUnit *result);
90
91 void utTerm();
92
94 The Unidata units library, udunits, supports conversion of unit speci‐
95 fications between formatted and binary forms, arithmetic manipulation
96 of unit specifications, and conversion of values between compatible
97 scales of measurement.
98
99 A unit is the amount by which a physical quantity is measured. For
100 example:
101
102
103
104 A unit can have an origin associated with it -- in which case the unit
105 and origin together define a scale. For example, the phrase "the tem‐
106 perature is 25 degrees Celsius" specifies a particular point on a mea‐
107 surement scale; whereas the phrase "the temperature difference is 25
108 degrees Celsius" specifies a unit with no origin and, hence, no associ‐
109 ated scale. If not remembered, this subtle distinction can cause prob‐
110 lems when handling units.
111
112 utInit() initializes the units package. If path is non-NULL and not
113 empty, then it specifies a units file containing initializing unit def‐
114 initions; otherwise, the environment variable UDUNITS_PATH is checked
115 and, if it exists and is not empty, then it is assumed to contain the
116 pathname of the units file; otherwise, a compile-time default pathname
117 is used.
118
119 The definitions in the units file are read into memory. This function
120 returns 0 on success, UT_ENOFILE if the units file doesn't exist,
121 UT_ESYNTAX if the units file contains a syntax error, UT_EUNKNOWN if
122 the units file contains an unknown specification, UT_EIO if an I/O
123 error occurred while accessing the units file, and UT_EALLOC if a mem‐
124 ory allocation failure occurred.
125
126 utIsInit() indicates whether or not the units package has been initial‐
127 ized.
128
129 This function returns 0 if the package hasn't been initialized and !0
130 if the package has been initialized.
131
132 utScan() converts the formatted unit specification spec into a binary
133 unit structure and stores the result in unit. The binary representa‐
134 tion is used for algebraic manipulation. This function returns 0 on
135 success, UT_ENOINIT if the package hasn't been initialized, UT_EINVALID
136 if the unit argument is a null pointer, UT_EUNKNOWN if the specifica‐
137 tion contains an unknown unit, and UT_ESYNTAX if the specification con‐
138 tains a syntax error.
139
140 utCalendar() converts the amount, value, of the temporal unit, unit,
141 into a UTC-referenced date and time (see, however, the section on HAN‐
142 DLING TIME). The reference unit shall be a time unit and have an ori‐
143 gin. This function returns 0 on success, UT_ENOINIT if the package
144 hasn't been initialized and UT_EINVALID if the unit structure is not a
145 temporal one.
146
147 utInvCalendar() converts a UTC-referenced date and time into the
148 amount, value, of the temporal unit, unit (see, however, the section on
149 HANDLING TIME). The reference unit shall be a time unit and have an
150 origin. This function returns 0 on success, UT_ENOINIT if the package
151 hasn't been initialized and UT_EINVALID if the unit structure is not a
152 temporal one.
153
154 utConvert() returns the coefficients of the Galilean transformation
155 (i.e. y = a*x + b) necessary to convert the from unit into the to unit.
156 The units must be compatible (i.e., their quotient must be dimension‐
157 less). On successful return, slope and intercept will contain the val‐
158 ues for the slope and intercept coefficients, respectively. This func‐
159 tion returns 0 on success, UT_ENOINIT if the package hasn't been ini‐
160 tialized, UT_EINVALID if one of the unit structures is invalid, and
161 UT_ECONVERT if the units are not convertible.
162
163 utPrint() converts the binary unit structure unit into a formatted unit
164 specification and stores the string into a static buffer. The argument
165 s is set to point to the static buffer. The string should not be modi‐
166 fied (it may, however, be copied) and will be overwritten by subsequent
167 calls to this function. This function returns 0 on success, UT_ENOINIT
168 if the package hasn't been initialized, and UT_EINVALID if the unit
169 structure is invalid. On error, the string argument is set to NULL.
170
171 utClear() clears a unit structure by setting it to the dimensionless
172 value 1.
173
174 utIsTime() returns true if the given unit structure refers to a time
175 unit and false otherwise. This function ignores whether or not the
176 unit has an origin.
177
178 utHasOrigin() returns true of the given unit structure has an origin
179 (i.e. defines a scale) and false otherwise.
180
181 utCopy() copies the unit structure source to the unit structure dest.
182 This function correctly handles the case where the same unit structure
183 is referenced by the source and destination units. The address of the
184 destination unit structure is returned.
185
186 utScale() scales the unit structure source by factor, storing the
187 result in the unit structure result. This function correctly handles
188 the case where the same unit structure is referenced by the source and
189 result units. The address of the result unit structure is returned.
190
191 utInvert() inverts the unit structure source, storing the result in
192 unit structure result. Multiplying a unit by its reciprocal yields the
193 dimensionless value 1. This function correctly handles the case where
194 the source and result unit refer to the same structure. If successful,
195 this function returns the address of the result unit structure; other‐
196 wise, it returns NULL.
197
198 utDivide() divides unit structure numer by unit structure denom and
199 stores the result in unit structure result. This function correctly
200 handles the case where the same unit structure is referenced by two or
201 more arguments. If successful, this function returns the address of
202 the result unit structure; otherwise, it returns NULL.
203
204 utMultiply() multiplies unit structure term1 by unit structure term2
205 and stores the result in unit structure result. This function cor‐
206 rectly handles the case where the same unit structure is referenced by
207 two or more arguments. If successful, this function returns the
208 address of the result unit structure; otherwise, it returns NULL.
209
210 utRaise() raises the unit structure source by the power power, storing
211 the result in the unit structure result. This function correctly han‐
212 dles the case where the same unit structure is referenced by the source
213 and result units. If successful, this function returns the address of
214 the result unit structure; otherwise, it returns NULL.
215
216 utTerm() terminates usage of this package. In particular, it frees all
217 allocated memory. It should be called when the library is no longer
218 needed.
219
221 The udunits(3) package uses a mixed Gregorian/Julian calendar system.
222 Dates prior to 1582-10-15 are assumed to use the Julian calendar, which
223 was introduced by Julius Caesar in 46 BCE and is based on a year that
224 is exactly 365.25 days long. Dates on and after 1582-10-15 are assumed
225 to use the Gregorian calendar, which was introduced on that date and is
226 based on a year that is exactly 365.2425 days long. (A year is actu‐
227 ally approximately 365.242198781 days long.) Seemingly strange behav‐
228 ior of the udunits(3) package can result if a user-given time interval
229 includes the changeover date. For example, utCalendar() and utInvCal‐
230 endar() can be used to show that 1582-10-15 *preceeded* 1582-10-14 by 9
231 days.
232
234 Convert two data sets to a common unit, subtract one from the other,
235 then save the result in a (different) output unit:
236
237 if (utInit("") != 0) {
238 /* handle initialization error */
239 } else {
240 char *UnitString1, *UnitString2, *OutputUnitString;
241 utUnit unit1, unit2, OutputUnit;
242 ...
243 if (utScan(UnitString1, &unit1) != 0 ||
244 utScan(UnitString2, &unit2) != 0 ||
245 utScan(OutputUnitString2, &OutputUnit) != 0) {
246 /*
247 * handle decode error
248 */
249 } else {
250 double InSlope, InIntercept;
251 double OutSlope, OutIntercept;
252 ...
253 if (utConvert(&unit2, &unit1, &InSlope,
254 &InIntercept) != 0 ||
255 utConvert(&unit1, &OutputUnit, &OutSlope,
256 &OutIntercept) != 0) {
257 /*
258 * handle data-incompatibility
259 */
260 } else {
261 /*
262 * process data using:
263 * OutputValue = OutSlope*(Data1Value -
264 * (InSlope*Data2Value + InIntercept))
265 * + OutIntercept
266 */
267 }
268 }
269 utTerm();
270 }
271
272 the above example could be made more efficient by testing the returned
273 conversion factors for nearness to 1 and 0 and using appropriately
274 streamlined processing expressions.
275
276
277 Compute a threshold value corresponding to an input data value plus a
278 user-specified delta (the units of the input data value and delta can
279 differ):
280
281 char *input_unit_string, *delta_unit_string;
282 float input_value;
283 utUnit input_unit, delta_unit;
284 ...
285 if (utScan(input_unit_string, &input_unit) != 0 ||
286 utScan(delta_unit_string, &delta_unit) != 0) {
287 /*
288 * handle decode error
289 */
290 } else {
291 double slope, intercept;
292 ...
293 if (utConvert(&delta_unit, &input_unit, &slope, &intercept) != 0) {
294 /*
295 * handle units incompatibility
296 */
297 } else {
298 float threshold = input_value + slope*delta_value
299 + intercept;
300 ...
301 }
302 }
303 utTerm();
304
305
306 Compute the number of time intervals from a start time to a reference
307 time:
308
309 #include <stdio.h>
310 #include <stdlib.h>
311 #include "udunits.h"
312
313 main()
314 {
315 if (utInit("/upc/cur/udunits/etc/udunits.dat") != 0) {
316 (void) fputs("utInit() error0, stderr);
317 } else {
318 utUnit timecenters_unit;
319
320 /*
321 * NB: The following "time centers" specification gives both
322 * the start time (January 1, 1990 at 00:00 UTC) and the
323 * sampling interval (2 minutes).
324 */
325 if (utScan("2 minutes since 1990-1-1", &timecenters_unit)
326 != 0) {
327 (void) fputs("utScan() error0, stderr);
328 } else {
329 /*
330 * The following reference time is 1 hour later than
331 * the above start time.
332 */
333 int ref_year = 1990;
334 int ref_month = 1;
335 int ref_day = 1;
336 int ref_hour = 1;
337 int ref_minute = 0;
338 float ref_second = 0;/* could be `double'
339 double ref_value;
340
341 (void) utInvCalendar(ref_year, ref_month, ref_day,
342 ref_hour, ref_minute, ref_second,
343 &timecenters_unit, &ref_value);
344 /*
345 * Exit successfully if the number of time intervals
346 * between the start and reference times is correct.
347 */
348 if (30 == ref_value)
349 exit(0);
350 }
351 }
352 abort();
353 }
354
355
357 The following are examples of formatted unit specifications that can be
358 interpreted by the utScan() function:
359
360 10 kilogram.meters/seconds2
361 10 kg-m/sec2
362 10 kg m/s^2
363 (PI radian)2
364 degF
365 100rpm
366 geopotential meters
367 33 feet water
368
369 A unit is specified as an arbitrary product of constants and unit names
370 raised to arbitrary integral powers. Division is indicated by a slash
371 `/'. Multiplication is indicated by whitespace, a period `.', or a
372 hyphen `-'. Exponentiation is indicated by an integer suffix or by the
373 exponentiation operators `^' and `**'. Parentheses may be used for
374 grouping and disambiguation.
375
376 Arbitrary Galilean transformations (i.e. y = ax + b) are supported. In
377 particular, temperature and time conversions are correctly handled.
378 The specification:
379
380 degF @ 32
381
382 indicates a Fahrenheit scale with the origin shifted to thirty-two
383 degrees Fahrenheit (i.e. to zero degrees Celsius). The Celsius scale
384 is equivalent to the following unit:
385
386 1.8 degR @ 273.15
387
388 Besides the character `@', the words `after', `from', `ref', and
389 `since' may also be used. Note that multiplication takes precedence
390 over origin-shift. In order of increasing precedence, the operations
391 are origin-shift, division, multiplication, and exponentiation.
392
393 Units of time are similarly handled. The specification:
394
395 seconds since 1992-10-8 15:15:42.5 -6:00
396
397 indicates seconds since October 8th, 1992 at 3 hours, 15 minutes and
398 42.5 seconds in the afternoon in the time zone which is six hours to
399 the west of Coordinated Universal Time (i.e. Mountain Daylight Time).
400 The time zone specification can also be written without a colon using
401 one or two-digits (indicating hours) or three or four digits (indicat‐
402 ing hours and minutes).
403
404 utScan() understands most conventional prefixes and abbreviations:
405
406
407
408 The function utPrint() always encodes a unit specification one way. To
409 reduce misunderstandings, it is recommended that this encoding style be
410 used as the default. In general, a unit is printed in terms of basic
411 units, factors, and exponents. Basic units are separated by spaces;
412 and any exponent directly appends its associated unit. The above exam‐
413 ples would be printed as follows:
414
415 10 kilogram meter second-2
416 9.8696044 radian2
417 0.555556 kelvin @ 255.372
418 10.471976 radian second-1
419 9.80665 meter2 second-2
420 98636.5 kilogram meter-1 second-2
421
422 Note that the Fahrenheit unit is encoded as a deviation, in fractional
423 kelvins, from an origin at 255.372 kelvin.
424
426 The units file is a formatted file containing unit definitions and is
427 used to initialize this package. It is the first place to look to dis‐
428 cover the set of valid names and symbols (of which there are many --
429 On October 9, 1992, it contained 446 entries).
430
431 The format for the units file is documented internally and the file may
432 be modified by the user as necessary. In particular, additional units
433 and constants may be easily added (including variant spellings of
434 existing units or constants).
435
437 UDUNITS_PATH If utInit() is called without a pathname argument, and
438 if this environment variable is non-empty, then its
439 value overrides the default pathname for the units file.
440
442 This package prints (hopefully) self-explanatory error-messages to
443 standard error.
444
446 udunits(1).
447
449 utScan() is case-sensitive. If this causes difficulties, you might try
450 making appropriate additional entries to the units file.
451
452 Some unit abbreviations in the default units file might seem counter-
453 intuitive. In particular, note the following:
454
455 For Use Not Which Instead Means
456
457 Celsius `Celsius' `C' coulomb
458 gram `gram' `g' <standard free fall>
459 gallon `gallon' `gal' <acceleration>
460 radian `radian' `rad' <absorbed dose>
461 Newton `newton' or `N' `nt' nit (unit of photometry)
462
464 NIST Special Publication 811, 1995 Edition: "Guide for the Use of the
465 International System of Units (SI)" by Barry N. Taylor. URL
466 <http://physics.nist.gov/Divisions/Div840/SI.html>.
467
468 ANSI/IEEE Std 260-1978: "IEEE Standard Letter Symbols for Units of Mea‐
469 surement".
470
471 ASTM Designation: E 380 - 85: "Standard for METRIC PRACTICE".
472
473 International Standard (ISO) 2955: "Information processing -- Represen‐
474 tation of SI and other units in systems with limited character sets",
475 Ref. No. ISO 2955-1983 (E).
476
477
478
479Printed: 119.6.22 $Date: 2003/08/29 18:29:55 $ UDUNITS(3)