{"record":{"id":"14efbf41d3f0db09","repo":"XINCGer/Unity3DTraining","slug":"timestamp-contains-invalid-values-seconds-second","errorCode":null,"errorMessage":"Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}","messagePattern":"Timestamp contains invalid values: Seconds=(.+?); Nanos=(.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/WellKnownTypes/TimestampPartial.cs","lineNumber":120,"sourceCode":"        }\n\n        /// <summary>\n        /// Converts this timestamp into a <see cref=\"DateTime\"/>.\n        /// </summary>\n        /// <remarks>\n        /// The resulting <c>DateTime</c> will always have a <c>Kind</c> of <c>Utc</c>.\n        /// If the timestamp is not a precise number of ticks, it will be truncated towards the start\n        /// of time. For example, a timestamp with a <see cref=\"Nanos\"/> value of 99 will result in a\n        /// <see cref=\"DateTime\"/> value precisely on a second.\n        /// </remarks>\n        /// <returns>This timestamp as a <c>DateTime</c>.</returns>\n        /// <exception cref=\"InvalidOperationException\">The timestamp contains invalid values; either it is\n        /// incorrectly normalized or is outside the valid range.</exception>\n        public DateTime ToDateTime()\n        {\n            if (!IsNormalized(Seconds, Nanos))\n            {\n                throw new InvalidOperationException(@\"Timestamp contains invalid values: Seconds={Seconds}; Nanos={Nanos}\");\n            }\n            return UnixEpoch.AddSeconds(Seconds).AddTicks(Nanos / Duration.NanosecondsPerTick);\n        }\n\n        /// <summary>\n        /// Converts this timestamp into a <see cref=\"DateTimeOffset\"/>.\n        /// </summary>\n        /// <remarks>\n        /// The resulting <c>DateTimeOffset</c> will always have an <c>Offset</c> of zero.\n        /// If the timestamp is not a precise number of ticks, it will be truncated towards the start\n        /// of time. For example, a timestamp with a <see cref=\"Nanos\"/> value of 99 will result in a\n        /// <see cref=\"DateTimeOffset\"/> value precisely on a second.\n        /// </remarks>\n        /// <returns>This timestamp as a <c>DateTimeOffset</c>.</returns>\n        /// <exception cref=\"InvalidOperationException\">The timestamp contains invalid values; either it is\n        /// incorrectly normalized or is outside the valid range.</exception>\n        public DateTimeOffset ToDateTimeOffset()\n        {","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/WellKnownTypes/TimestampPartial.cs#L102-L138","documentation":"Timestamp.ToDateTime requires the timestamp to be normalized (Nanos in [0, 999999999]) and within the valid DateTime range (0001-01-01 to 9999-12-31 after conversion from Unix epoch). IsNormalized checks both; when it fails the method throws InvalidOperationException describing the offending Seconds/Nanos. Converting an out-of-range or non-normalized timestamp to a DateTime is impossible without overflow.","triggerScenarios":"Calling ToDateTime() (directly or via ToDateTimeOffset) on a Timestamp with negative Nanos, Nanos >= 1e9, or Seconds outside the range that maps into DateTime's min/max (roughly seconds -62135596800..253402300799).","commonSituations":"Timestamps decoded from untrusted or buggy producers (e.g. nanos populated with milliseconds * 1e6 overflow); sentinel values like Seconds=0/Nanos=-1; very large Seconds from int64 overflow upstream; timestamps pre-1AD or post-9999AD.","solutions":["Check Timestamp.IsNormalized-equivalent before converting: validate Nanos >= 0 && Nanos < 1_000_000_000 and Seconds within DateTime-representable range","Fix the producer so it normalizes (borrow from Seconds when Nanos is negative)","If you need range beyond DateTime, use ToDateTimeOffset on a DateTimeOffset-capable path or keep the raw Seconds/Nanos","Clamp or reject out-of-range timestamps at deserialization boundaries"],"exampleFix":"// before\nvar ts = new Timestamp { Seconds = -7_000_000_000L, Nanos = -5 };\nvar dt = ts.ToDateTime(); // throws\n// after\nif (ts.Nanos < 0 || ts.Nanos > 999_999_999)\n{\n    // repair or reject\n    ts = new Timestamp { Seconds = ts.Seconds - 1, Nanos = ts.Nanos + 1_000_000_000 };\n}\nvar dt2 = ts.ToDateTime();","handlingStrategy":"validation","validationCode":"static bool IsConvertibleTimestamp(Timestamp t) => t.Nanos >= 0 && t.Nanos < 1_000_000_000 && t.Seconds >= -62135596800L && t.Seconds <= 253402300799L;","typeGuard":"static bool IsSafeTimestamp(Timestamp t) => t != null && t.Nanos >= 0 && t.Nanos < 1_000_000_000;","tryCatchPattern":"try { return ts.ToDateTime(); } catch (InvalidOperationException ex) { log.Warn(ex, \"Invalid timestamp {Seconds}/{Nanos}\", ts.Seconds, ts.Nanos); return DateTime.MinValue; }","preventionTips":["Check the exception message's Seconds/Nanos to find the faulty producer","Reject or clamp timestamps at the ingestion boundary","Prefer DateTimeOffset arithmetic for extreme ranges"],"tags":["protobuf","c-sharp","timestamp","datetime"],"backgroundTag":"value-out-of-range","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}