JamesNK/Newtonsoft.Json · error · ArgumentException

Can not convert {0} to DateTimeOffset.

Error message

Can not convert {0} to DateTimeOffset.

What it means

Thrown by the explicit (non-nullable) cast operator DateTimeOffset(JToken) at JToken.cs:588. It validates the token type against DateTimeTypes = {Date, String, Comment, Raw}. Only date-carrying or string JValues are accepted; numbers, booleans, null, and containers are rejected with this ArgumentException. (A string value is later parsed via DateTimeOffset.Parse, so only the type gate, not parse failures, produces this specific message.)

Source

Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:588

                return Convert.ToBoolean((int)integer);
            }
#endif

            return Convert.ToBoolean(v.Value, CultureInfo.InvariantCulture);
        }

#if HAVE_DATE_TIME_OFFSET
        /// <summary>
        /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static explicit operator DateTimeOffset(JToken value)
        {
            JValue? v = EnsureValue(value);
            if (v == null || !ValidateToken(v, DateTimeTypes, false))
            {
                throw new ArgumentException("Can not convert {0} to DateTimeOffset.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
            }

            if (v.Value is DateTimeOffset offset)
            {
                return offset;
            }

            if (v.Value is string s)
            {
                return DateTimeOffset.Parse(s, CultureInfo.InvariantCulture);
            }

            return new DateTimeOffset(Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture));
        }
#endif

        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="Boolean"/>.

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Use the nullable cast (DateTimeOffset?)token and null-coalesce, so a JSON null yields null rather than throwing.
  2. If the value is a numeric epoch, convert manually: DateTimeOffset.FromUnixTimeSeconds((long)token) — but first cast via long, not DateTimeOffset.
  3. Ensure the JSON value is an ISO-8601 string so its JTokenType is String (accepted by DateTimeTypes).
  4. Check token.Type is Date or String before the non-nullable cast.

Example fix

// before
DateTimeOffset dto = (DateTimeOffset)token["ts"]; // throws for numeric/null epoch

// after
DateTimeOffset dto = token["ts"].Type == JTokenType.Integer
    ? DateTimeOffset.FromUnixTimeSeconds((long)token["ts"])
    : (DateTimeOffset?)token["ts"] ?? DateTimeOffset.MinValue;
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the token is a date-or-string scalar before the non-nullable DateTimeOffset cast
static bool CanToDateTimeOffset(JToken? t) =>
    t is JValue v && (v.Type == JTokenType.Date || v.Type == JTokenType.String);

Type guard

static DateTimeOffset? SafeDateTimeOffset(JToken? t) => t switch {
    JValue v when v.Type is JTokenType.Date or JTokenType.String => (DateTimeOffset?)t,
    JValue v when v.Type is JTokenType.Null or JTokenType.Undefined => null,
    _ => null
};

Try / catch

try
{
    DateTimeOffset dto = (DateTimeOffset)token;
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not convert"))
{
    // token is numeric/null/object; handle epoch conversion or default
}

Prevention

When it happens

Trigger: Casting a JSON null to (DateTimeOffset)token; casting an Integer (e.g. a unix epoch) or Float JValue to DateTimeOffset; casting a Boolean, Guid, Uri, or a JObject/JArray to DateTimeOffset.

Common situations: API returns a numeric epoch timestamp but code assumes an ISO-8601 string; field became null after a schema/version change; a date field represented as an object (e.g. {"$date": ...}) instead of a string.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/e5b2887f1addf14b. Report an issue: GitHub.