{"record":{"id":"6b377985bd561210","repo":"XINCGer/Unity3DTraining","slug":"invalid-timestamp-value-token-stringvalue","errorCode":null,"errorMessage":"Invalid Timestamp value: {token.StringValue}","messagePattern":"Invalid Timestamp value: (.+?)","errorType":"exception","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs","lineNumber":792,"sourceCode":"        {\n            if ((isPositiveInfinity && text != \"Infinity\") ||\n                (isNegativeInfinity && text != \"-Infinity\") ||\n                (isNaN && text != \"NaN\"))\n            {\n                throw new InvalidProtocolBufferException(\"Invalid numeric value: \" + text);\n            }\n        }\n\n        private static void MergeTimestamp(IMessage message, JsonToken token)\n        {\n            if (token.Type != JsonToken.TokenType.StringValue)\n            {\n                throw new InvalidProtocolBufferException(\"Expected string value for Timestamp\");\n            }\n            var match = TimestampRegex.Match(token.StringValue);\n            if (!match.Success)\n            {\n                throw new InvalidProtocolBufferException(\"Invalid Timestamp value: \" + token.StringValue);\n            }\n            var dateTime = match.Groups[\"datetime\"].Value;\n            var subseconds = match.Groups[\"subseconds\"].Value;\n            var offset = match.Groups[\"offset\"].Value;\n\n            try\n            {\n                DateTime parsed = DateTime.ParseExact(\n                    dateTime,\n                    \"yyyy-MM-dd'T'HH:mm:ss\",\n                    CultureInfo.InvariantCulture,\n                    DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);\n                // TODO: It would be nice not to have to create all these objects... easy to optimize later though.\n                Timestamp timestamp = Timestamp.FromDateTime(parsed);\n                int nanosToAdd = 0;\n                if (subseconds != \"\")\n                {\n                    // This should always work, as we've got 1-9 digits.","sourceCodeStart":774,"sourceCodeEnd":810,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/JsonParser.cs#L774-L810","documentation":"After confirming the token is a string, MergeTimestamp matches it against TimestampRegex, which enforces the RFC 3339 shape (calendar date, 'T' or 't' separator, time, optional fractional seconds, and 'Z'/offset). Strings that are close but not conformant — missing timezone, wrong separator, unparseable offsets — fail the regex and throw InvalidProtocolBufferException('Invalid Timestamp value: ' + value).","triggerScenarios":"JsonParser.Parse<T> with Timestamp fields given strings like '2024-01-15 10:30:00' (space instead of T with wrong format), '2024-01-15' (date only), '2024-01-15T10:30:00' (no offset/Z), or invalid offsets like '2024-01-15T10:30:00+0500'.","commonSituations":"DateTime.ToString() defaults that omit 'Z' or use space separators; SQL datetime strings pasted into JSON; offsets formatted without the required colon; date-only values used where full timestamps are required.","solutions":["Emit RFC 3339 UTC strings ending in 'Z', e.g. dateTime.ToUniversalTime().ToString(\"yyyy-MM-dd'T'HH:mm:ss.fff'Z'\") or the 'o' round-trip format on a UTC DateTime","Ensure any numeric offset includes a colon ('+05:00', not '+0500')","Include full date, time and offset — a bare date or naive local time is rejected","Normalize/pre-parse with DateTimeOffset.Parse + .ToString(\"o\") before embedding into JSON"],"exampleFix":"// before\nstring ts = DateTime.Now.ToString(\"yyyy-MM-dd HH:mm:ss\"); // 2024-01-15 10:30:00, no T/Z\n// after\nstring ts = DateTime.UtcNow.ToString(\"o\"); // 2024-01-15T10:30:00.0000000Z","handlingStrategy":"validation","validationCode":"static readonly System.Text.RegularExpressions.Regex Rfc3339 =\n    new System.Text.RegularExpressions.Regex(@\"^\\d{4}-\\d{2}-\\d{2}[Tt]\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?([Zz]|[+-]\\d{2}:\\d{2})$\");\nbool IsValidTimestampString(string s) => Rfc3339.IsMatch(s);","typeGuard":null,"tryCatchPattern":"try { return JsonParser.Default.Parse<T>(json); }\ncatch (InvalidProtocolBufferException ex) when (ex.Message.StartsWith(\"Invalid Timestamp value\")) {\n    logger.LogWarning(ex, \"Timestamp string does not match RFC 3339\");\n    return null;\n}","preventionTips":["Always emit UTC timestamps ending in 'Z' (DateTime.UtcNow.ToString(\"o\"))","Include colons in numeric offsets ('+05:00', not '+0500')","Reject date-only or naive local times at your API boundary","Unit-test timestamp serialization against the proto JSON conformance patterns"],"tags":["protobuf","json","timestamp","rfc3339","date-format"],"backgroundTag":"invalid-date-format","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"}