Skip to content

Commit 6332029

Browse files
committed
Implement and test realtime timestamp functions
1 parent 2e68d65 commit 6332029

File tree

4 files changed

+742
-5
lines changed

4 files changed

+742
-5
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/model/Values.kt

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,11 +750,32 @@ internal object Values {
750750

751751
@JvmStatic
752752
fun timestamp(seconds: Long, nanos: Int): Timestamp {
753+
validateRange(seconds, nanos)
754+
753755
// Firestore backend truncates precision down to microseconds. To ensure offline mode works
754756
// the same with regards to truncation, perform the truncation immediately without waiting for
755757
// the backend to do that.
756758
val truncatedNanoseconds: Int = nanos / 1000 * 1000
757-
758759
return Timestamp.newBuilder().setSeconds(seconds).setNanos(truncatedNanoseconds).build()
759760
}
761+
762+
/**
763+
* Ensures that the date and time are within what we consider valid ranges.
764+
*
765+
* More specifically, the nanoseconds need to be less than 1 billion- otherwise it would trip over
766+
* into seconds, and need to be greater than zero.
767+
*
768+
* The seconds need to be after the date `1/1/1` and before the date `1/1/10000`.
769+
*
770+
* @throws IllegalArgumentException if the date and time are considered invalid
771+
*/
772+
private fun validateRange(seconds: Long, nanoseconds: Int) {
773+
require(nanoseconds in 0 until 1_000_000_000) {
774+
"Timestamp nanoseconds out of range: $nanoseconds"
775+
}
776+
777+
require(seconds in -62_135_596_800 until 253_402_300_800) {
778+
"Timestamp seconds out of range: $seconds"
779+
}
780+
}
760781
}

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/EvaluateResult.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ internal sealed class EvaluateResult(val value: Value?) {
2626
fun timestamp(timestamp: Timestamp): EvaluateResult =
2727
EvaluateResultValue(encodeValue(timestamp))
2828
fun timestamp(seconds: Long, nanos: Int): EvaluateResult =
29-
if (seconds !in -62_135_596_800 until 253_402_300_800) EvaluateResultError
30-
else timestamp(Values.timestamp(seconds, nanos))
29+
try {
30+
timestamp(Values.timestamp(seconds, nanos))
31+
} catch (e: IllegalArgumentException) {
32+
EvaluateResultError
33+
}
3134
}
3235
}
3336

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/evaluation.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,14 +568,14 @@ internal val evaluateTimestampToUnixSeconds = unaryFunction { t: Timestamp ->
568568
internal val evaluateUnixMicrosToTimestamp = unaryFunction { micros: Long ->
569569
EvaluateResult.timestamp(
570570
Math.floorDiv(micros, L_MICROS_PER_SECOND),
571-
Math.floorMod(micros, I_MICROS_PER_SECOND)
571+
Math.floorMod(micros, I_MICROS_PER_SECOND) * 1000
572572
)
573573
}
574574

575575
internal val evaluateUnixMillisToTimestamp = unaryFunction { millis: Long ->
576576
EvaluateResult.timestamp(
577577
Math.floorDiv(millis, L_MILLIS_PER_SECOND),
578-
Math.floorMod(millis, I_MILLIS_PER_SECOND)
578+
Math.floorMod(millis, I_MILLIS_PER_SECOND) * 1000_000
579579
)
580580
}
581581

0 commit comments

Comments
 (0)