Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Instant with limited database precision #468

Open
Burtan opened this issue Dec 28, 2024 · 3 comments
Open

Using Instant with limited database precision #468

Burtan opened this issue Dec 28, 2024 · 3 comments
Labels
waiting for clarification Additional information is needed from the user

Comments

@Burtan
Copy link

Burtan commented Dec 28, 2024

Hi,
I'm trying to use the Instant type with the widely used Google Cloud Datastore. Its corresponding type is Timestamp, which offers the same precision. Storing and retrieving Timestamps though limits precision to microseconds instead of nanoseconds. While I don't need nanoseconds precision I require the values stored and retrieved to be the same.
I wonder if this library provides a solution to this or if it is up to the user.

The best way is probably to limit the precision when receiving the Instant value. This would mean handling Clock precision and modifying the precision of all received values via APIs. However you probably would also have to limit the precision in all your client apps. This adds a lot of complexity.

Alternatively you should store Instant values as Strings if the native time value is of less precision.

What do you think?

@dkhalanskyjb
Copy link
Collaborator

dkhalanskyjb commented Jan 7, 2025

Hi!

While I don't need nanoseconds precision I require the values stored and retrieved to be the same.

Could you please explain where this requirement comes from? To me, this looks like a (tiny) waste of computations: if Google Cloud Datastore is already truncating the value for you, why do it in your code as well? Could you describe the business logic that mandates this?

If the only reason you need this is to simplify testing, this can be done differently:

val originalInstant = Clock.System.now()
val instantAfterRoundTrip: Instant = roundTripToCloudDatastore(originalInstant)
// assertEquals(originalInstant, instantAfterRoundTrip) // won't work due to precision loss
val difference = (instantAfterRoundTrip - originalInstant).absoluteValue
assertTrue(difference < 1.microseconds)

I wonder if this library provides a solution to this

Not at the moment. It's not clear yet why this would be needed. As a workaround, you could do this:

import kotlin.time.Duration.Companion.nanoseconds

fun Instant.truncatedToMicroseconds(): Instant =
    this - (nanosecondsOfSecond % 1000).nanoseconds

@Burtan
Copy link
Author

Burtan commented Jan 7, 2025

If you have the requirement to synchronize data, you need time values to be the same or to treat tiny differences as the same value. As you described, this requires manual adjustments each time you compare time values, which could be error prone. While the datastore values are truncated, incoming request from clients using Kotlin.Instant are not truncated by default.

@dkhalanskyjb
Copy link
Collaborator

If you have the requirement to synchronize data, you need time values to be the same or to treat tiny differences as the same value.

Could you provide some (pseudo)code that explains the problem? I've never worked on projects like the one you're describing, so it's difficult for me to imagine why your code needs to compare Instant values using ==. Where do Instant values come from? Why do they need to make a roundtrip? Why are they not allowed to lose precision during the roundtrip and have to lose the precision earlier than that? None of this is obvious to me.

@dkhalanskyjb dkhalanskyjb added the waiting for clarification Additional information is needed from the user label Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting for clarification Additional information is needed from the user
Projects
None yet
Development

No branches or pull requests

2 participants