Unidata / UDUNITS-2

API and utility for arithmetic manipulation of units of physical quantities
http://www.unidata.ucar.edu/software/udunits
Other
62 stars 36 forks source link

Lossy date parsing in corner case #123

Open pelson opened 2 weeks ago

pelson commented 2 weeks ago

Using a date specification such as seconds since 1234-6789, it seems the information after the 6 is totally discarded by the parser. I determine this by tracking down the unit equivalence in the CLI:

udunits2 -H 'min since 1234-6789' -W 'min since 1234-06-01 00:00:00'
    1 min since 1234-6789 = 1 (min since 1234-06-01 00:00:00)
    x/(min since 1234-06-01 00:00:00) = (x/(min since 1234-6789))

It seems to me that this is undesirable behaviour - either it should preserve the information, or raise.

Whilst the above is a toy example, I had a test example as below:

udunits2 -H 'min since 2020-0101' -W 'min since 2020-01-01 01:00:00'
    1 min since 2020-0101 = 1 (min since 2020-01-01 01:00:00)
    x/(min since 2020-01-01 01:00:00) = (x/(min since 2020-0101))

The implication of the above is more serious - note that not all information is discarded, and in fact the final 1 is interpreted as an hour specification. I would have expected 2020-0101 to represent 2020-01-01 (or raise an error)

pelson commented 2 weeks ago

I also found that timezone is being lost with the following:

udunits2 -H 'seconds from 1990-1-1 0:0:0 +2550' -W 'seconds from 1990-1-1 0:0:0'
    1 seconds from 1990-1-1 0:0:0 +2550 = 1 (seconds from 1990-1-1 0:0:0)
    x/(seconds from 1990-1-1 0:0:0) = (x/(seconds from 1990-1-1 0:0:0 +2550))

i.e. if the number is greater than 2359, it gets completely lost:

$ udunits2 -H 'seconds from 1990-1-1 0:0:0 +2359' -W 'seconds from 1990-1-1 0:0:0'
    1 seconds from 1990-1-1 0:0:0 +2359 = -86339 (seconds from 1990-1-1 0:0:0)
    x/(seconds from 1990-1-1 0:0:0) = (x/(seconds from 1990-1-1 0:0:0 +2359)) - 86340

$ udunits2 -H 'seconds from 1990-1-1 0:0:0 +2400' -W 'seconds from 1990-1-1 0:0:0'
    1 seconds from 1990-1-1 0:0:0 +2400 = 1 (seconds from 1990-1-1 0:0:0)
    x/(seconds from 1990-1-1 0:0:0) = (x/(seconds from 1990-1-1 0:0:0 +2400))