Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Orekit Orekit
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 69
    • Issues 69
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 13
    • Merge requests 13
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Orekit
  • OrekitOrekit
  • Issues
  • #681
Closed
Open
Created May 12, 2020 by Evan Ward@evanward1Developer

AbsoluteDate.getComponents() loses precision, produces invalid times

AbsoluteDate.getComponents(...) carefully maintains full precision and passes two number to TimeComponents. Then the TimeComponents constructor adds those two numbers back together, losing some extra digits:

        second         = wholeSeconds + fractional;

This can cause second to be 60.0 (or 61.0 during a leap second), an invalid time. This also means that new AbsoluteDate(date.getComponents(scale), scale).equals(date) is sometimes usually false but occasionally true depending on cancellation in the least significant bits.

One possible solution is to use the same precision in AbsoluteDate and TimeComponents. This would mean using an int for whole seconds and a double for fractional seconds in TimeComponents. Even with this option there is no guarantee that there would be a unique DateTimeComponents for each AbsoluteDate.

Another possible solution is to always round down when computing the sum. This would increase the error from half an ULP to a whole ULP (~ 7 fs). This would fix the invalid time problem, but would not address converting an AbsoluteDate to components and back.

I'm leaning towards the second option.

Here is a failing test case:

    @Test
    public void testInvalidSecond() {
        // setup
        AbsoluteDate date = new AbsoluteDate(2017, 1, 1, utc)
                .shiftedBy(59)
                .shiftedBy(FastMath.nextDown(1.0));

        // action
        DateTimeComponents actual = date.getComponents(utc);

        // verify
        MatcherAssert.assertThat(actual.getTime().getSecond(),
                CoreMatchers.is(FastMath.nextDown(60.0)));
    }
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking