JamesNK/Newtonsoft.Json · error · ArgumentException

Can not convert {0} to DateTime.

Error message

Can not convert {0} to DateTime.

What it means

Thrown by the explicit nullable cast operator DateTime?(JToken?) at JToken.cs:671. With nullable:true, JSON null/undefined tokens pass and return null. The ArgumentException is raised only when the token is not a JValue (container) or its type is outside DateTimeTypes = {Date, String, Comment, Raw} — i.e. Integer, Float, Boolean, Guid, Uri, Bytes, Object, Array.

Source

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

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

        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="DateTime"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static explicit operator DateTime?(JToken? value)
        {
            if (value == null)
            {
                return null;
            }

            JValue? v = EnsureValue(value);
            if (v == null || !ValidateToken(v, DateTimeTypes, true))
            {
                throw new ArgumentException("Can not convert {0} to DateTime.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
            }

#if HAVE_DATE_TIME_OFFSET
            if (v.Value is DateTimeOffset offset)
            {
                return offset.DateTime;
            }
#endif

            return (v.Value != null) ? (DateTime?)Convert.ToDateTime(v.Value, CultureInfo.InvariantCulture) : null;
        }

#if HAVE_DATE_TIME_OFFSET
        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="DateTimeOffset"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Check token.Type is Date or String before casting.
  2. If the value is an epoch/tick integer, convert explicitly (e.g. DateTimeOffset.FromUnixTimeSeconds((long)token).DateTime) rather than the DateTime cast.
  3. Use token.Value<DateTime?>() which yields default for non-convertible tokens.
  4. Deserialize into a typed POCO with a nullable DateTime property.

Example fix

// before
DateTime? dt = (DateTime?)token["created"]; // throws when created is an epoch int

// after
DateTime? dt = token["created"].Type == JTokenType.Integer
    ? DateTimeOffset.FromUnixTimeSeconds((long)token["created"]).LocalDateTime
    : (DateTime?)token["created"];
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the token is a date-or-string scalar (nullable cast tolerates JSON null)
static bool CanToNullableDateTime(JToken? t) =>
    t is not JValue v || v.Type is JTokenType.Date or JTokenType.String
        or JTokenType.Null or JTokenType.Undefined;

Type guard

static DateTime? SafeDateTime(JToken? t) => t switch {
    JValue v when v.Type is JTokenType.Date or JTokenType.String => (DateTime?)t,
    JValue v when v.Type is JTokenType.Null or JTokenType.Undefined => null,
    _ => null // integer epoch, bool, container, etc.
};

Try / catch

try
{
    DateTime? dt = (DateTime?)token;
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not convert"))
{
    // token is numeric/bool/container; handle epoch or default
}

Prevention

When it happens

Trigger: Casting an Integer/Float/Boolean JValue to (DateTime?)token; casting a JObject/JArray or a Guid/Uri to DateTime?. A JSON null is accepted and returns null.

Common situations: An API returns dates as numeric ticks/epoch but code expects a Date or ISO string; a field that became a boolean flag is read as a date; a container where a scalar date was expected.

Related errors


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