This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
Henry, > I have found it quite challenging to get to grips with the new udunits2 API > Attached is my project code. > > All the routine does is read the units attribute of a co-ordinate > variable into "fl_unt_sng" > > It then converts the value in "lmt_sng" to these units and places the > result into crr_val > > For example if > fl_unt_sng ="meters" lmt_sng="0.7 microns" => crr_val=7e-7 > fl_unt_sng="seconds" lmt_sng="10 minutes" -=> crr_val=600 > fl_unt_sng="days since 2008-02-01" lmt_sng="2008-01-29" crr_val=3 > > > Problems > > A) > How can I determine if the resulting udunits structure is a timestamp ? > e.g ut_sct_out=ut_parse(ut_sys, fl_unt_sng, UT_ASCII); One of the purposes of the UDUNITS package is to abstract what it means to be a unit so that you don't have to ask the question "Is this a timestamp unit?". Having said that, you could determine whether or not a unit is convertible with a known timestamp unit. For example ut_system unitSys = ...; ut_unit epochSeconds = ut_parse(unitSys, "seconds since 1970-01-01 00:00:00", UT_ASCII); ut_unit unknownUnit = ...; if (ut_are_convertible(unknownUnit, epochSeconds)) { ... } else { ... } > I tried reading the type eg "out_type=ut_sct_out->common.type" but I > got the compiler error "error: dereferencing pointer to incomplete > type", and anyway the enum UnitType is only local to unitcore.c.!! That's correct. To promote encapsulation, the internal details of the unit structure are not published. They were in the original UDUNITS package and that decision severely limited that package's extendibility. > Even if I know that the resultant type is a Timestamp Unit how do I > read the origin ? Similarly, if I have a Galilean Unit how do I read > the scale and offset ? You shouldn't have to know the origin of a timestamp unit or the scale and offset of a Galilean unit in order to use those units in a program. If you believe that you have to have these hidden details, then may I ask why? > B) > In order to parse a date in lmt_sng I had to prefix the date with "s@". > This fact was not mentioned in the manual. I only found this out by > looking at the code examples in testUnit.c That's correct. A date, by itself, isn't a time-offset unit (i.e., a timestamp unit) because it doesn't reference a unit of time (e.g., "second"). You can see this in the "Syntax" section of the documentation. > C) > In my initial code I tried parsing all of lmt_sng in one go (if it > wasn't a date) e.g ut_sct_in=ut_parse(ut_sys,"10 minutes",UT_ASCII) > This should work but doesn't. On parsing this string ut_sct_in has > the units type "seconds" and not "minutes". Actually, the internal structure of that unit will be closer to "600 seconds". During parsing, all units are related to the base units of the unit system, which, in the default case, would have the second as the base unit of time. Referencing all units to a base system allows for unit operations such as tests for equality, tests for convertibility, and conversion of numeric values. > It was only by looking at your code in prog/udunits.c that I saw > that you split off the value and the units into separate strings > > Regards Henry Regards, Steve Emmerson Ticket Details =================== Ticket ID: HAN-352788 Department: Support UDUNITS Priority: Normal Status: Closed