AbsoluteDate.toString() in Orekit 11 gives unpredictable result

from last sunday, I began to update my App’s orekit dependency version from 10.2 to 11.0.2,
I found that AbsoluteDate.toString() gives unpredictable result, after AbsoluteDate.shift(dt) operate. thie result is something like this:

AbsoluteDate absoluteDate = new AbsoluteDate("2022-01-12T00:00:00",TimeScalesFactory.getUTC());
            double step = 0.01;
            for(int i=0;i< 1000;i++){
                  AbsoluteDate shifted = absoluteDate.shiftedBy(step);
                  // System.out.printf("shifted date:%s\n",shifted.toString());
                  absoluteDate = shifted;
                  if(shifted.toString().length()>24){
                        TimeComponents timeComponents =   shifted.getComponents(TimeScalesFactory.getUTC()).getTime();
                        System.out.printf("shifted datetime:%s        time:%s\n",shifted.toString(),timeComponents.toStringWithoutUtcOffset());
                  }
            };

shifted datetime:2022-01-12T00:00:09.68000000000001Z time:00:00:09.68000000000001
shifted datetime:2022-01-12T00:00:09.69000000000001Z time:00:00:09.69000000000001
shifted datetime:2022-01-12T00:00:09.70000000000001Z time:00:00:09.70000000000001

if change step to (double)0.01f,results goes like this:
shifted datetime:2022-01-12T00:00:09.47999978810549Z time:00:00:09.47999978810549
shifted datetime:2022-01-12T00:00:09.48999978788197Z time:00:00:09.48999978788197
shifted datetime:2022-01-12T00:00:09.49999978765845Z time:00:00:09.49999978765845

I checked the code inside the AbsoluteDate.toString(),I found the reason:

    public String toStringWithoutUtcOffset() {
        // create formats here as they are not thread safe
        // Format for seconds to prevent rounding up to an invalid time. See #591
        final DecimalFormat secondsFormat =
                new DecimalFormat("00.000###########", US_SYMBOLS);
        return toStringWithoutUtcOffset(secondsFormat);
    }

the new DecimalFormat with 11 ‘#’ would causes this.

i also read the post
update-absolutedate-tostring for 11

the AbsoluteDate and toString are so import that this unperdictable result would make many application upgrade from 10 to 11 crash like my app.

I hope my reports could give some help.

If you need fixed rounding that truncates the accurate internal data, you’ll have to use
a custom formatting method. Your method should first call AbsoluteDate.getComponents(timeScale),
most probably with timescale set to UTC, and then format the date and time components as you wish.

Hi youngcle,

Orekit 11 also adds more flexible (and correct) date formatting. For example to select how many digits to emit one could use

TimeScale ts = ...;
AbsoluteDate date = ...;
int numDigits = ...;
date.getComponents(ts).toString(ts.minuteDuration(ts), numDigits);

Perhaps adding a convenience method to AbsoluteDate to do that would be a helpful feature.

If you need RFC3339 format you can also use AbsoluteDate.toStringRfc3339().

Regards,
Evan

This is a much cleaner solution than mine :+1:

1 Like

Added some more time formatting methods in Fix #880 #881 AbsoluteDate toString with and without UTC offset (!227) · Merge requests · Orekit / Orekit · GitLab