React by Patrik

UTC DateTime Handling Between React and ASP.NET Core

When working with frontend frameworks like React and backend APIs such as ASP.NET Core, ensuring consistent and accurate DateTime handling across timezones is essential — especially when dealing with user input via <input type="datetime-local"> and when storing timestamps like created, modified, and published in UTC in a database.

This Snippset explores a practical and professional strategy for:

  • Accepting and formatting user input in local time

  • Converting local times to UTC before sending to the server

  • Storing and retrieving UTC in ASP.NET Core

  • Formatting and displaying local time correctly on the frontend

All examples assume the use of modern JSON APIs with ISO 8601 strings ("2025-05-27T20:03:00Z") and an object-based form model in React.

datetime
timezone
utc
react
aspnetcore
...see more

To populate an <input type="datetime-local"> in React, you must convert your UTC string into a local time string formatted as "yyyy-MM-ddTHH:mm" — the only format the input accepts.

Implementation:

function toDatetimeLocalValue(dateInput) {
  const date = new Date(dateInput);
  const pad = (n) => n.toString().padStart(2, '0');

  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

Use this function when binding input values in forms to ensure users see time in their own timezone.

...see more

When a user selects a datetime in a <input type="datetime-local">, the returned value (e.g., "2025-05-27T22:03") is in local time. To maintain UTC consistency on the backend, this must be converted to UTC.

Implementation:

const handleChange = (e) => {
  const local = new Date(e.target.value); // local time
  const utc = local.toISOString();        // UTC string for API
  setPost({ ...post, created: utc });
};

This ensures accurate time data regardless of the user's timezone.

...see more

ASP.NET Core with System.Text.Json handles ISO 8601 UTC strings automatically when binding to DateTime properties. Ensure you're not converting to UTC again if the incoming data already ends with Z.

Best Practices:

 

[JsonPropertyName("created")]
public DateTime Created { get; set; } // Will be parsed as UTC if ends in "Z"

If needed, ensure correct serialization:

private readonly JsonSerializerOptions _jsonOptions = new()
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    Converters = { new UtcDateTimeConverter() }
};

Custom converter (if required):

public class UtcDateTimeConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        => DateTime.SpecifyKind(reader.GetDateTime(), DateTimeKind.Utc);

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
        => writer.WriteStringValue(value.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
}
...see more

To display datetimes in the user's local timezone while preserving backend UTC storage, you can use JavaScript's built-in timezone offset support:

const utcDate = "2025-05-27T20:03:00Z";
const localDisplay = new Date(utcDate).toLocaleString();
// → "5/27/2025, 10:03 PM" (depending on user's locale)

This gives users a familiar and correctly adjusted view of time. For a consistent format, Intl.DateTimeFormat can be used.

Comments