[CLAUDE] Api: fix lệch giờ +7h — serialize DateTime UTC-with-Z (anh Kiệt FDC)
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Has been cancelled

anh Kiệt báo "mới tạo phiếu mà báo cách 7h trước" — lỗi timezone: timestamps lưu UTC
(DateTime.UtcNow) nhưng EF đọc datetime2 = DateTimeKind.Unspecified → System.Text.Json default
serialize KHÔNG có 'Z' (vd "2026-06-23T08:20:00") → FE new Date(naive) hiểu là LOCAL → lệch +7h
(VN UTC+7).

Fix: UtcDateTimeJsonConverter (global qua AddControllers.AddJsonOptions) ép serialize UTC ISO-8601
CÓ 'Z' cho MỌI timestamp API → FE new Date("...Z") convert đúng về giờ local. Áp dụng cả DateTime?
(System.Text.Json tự dùng converter cho non-null của Nullable).

BE 2 file (converter mới + Program.cs đăng ký). Build slnx 0 err. KHÔNG migration. Bundle FE frozen.
Note: SignalR realtime push dùng serializer riêng — nếu giờ realtime còn lệch sẽ thêm AddJsonProtocol.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-23 15:31:08 +07:00
parent 1263c0dd77
commit 49ac0868db
2 changed files with 32 additions and 1 deletions

View File

@ -27,7 +27,11 @@ builder.Host.UseSerilog((ctx, cfg) => cfg
.Enrich.FromLogContext());
// ---------- Core services ----------
builder.Services.AddControllers();
// [S85 anh Kiệt — TZ FIX] Serialize DateTime UTC-with-Z. EF đọc datetime2 = Unspecified kind →
// default thiếu 'Z' → FE new Date(naive) hiểu là local → lệch +7h ("mới tạo báo 7h trước").
// UtcDateTimeJsonConverter ép 'Z' cho MỌI timestamp API → FE convert đúng về giờ local.
builder.Services.AddControllers().AddJsonOptions(o =>
o.JsonSerializerOptions.Converters.Add(new SolutionErp.Api.Serialization.UtcDateTimeJsonConverter()));
builder.Services.AddSignalR();
builder.Services.AddSingleton<IRealtimeNotifier, SignalRNotifier>();
builder.Services.AddHttpContextAccessor();

View File

@ -0,0 +1,27 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace SolutionErp.Api.Serialization;
// [S85 anh Kiet — TZ FIX] Timestamps luu UTC (DateTime.UtcNow) nhung EF doc tu SQL Server
// datetime2 = DateTimeKind.Unspecified -> System.Text.Json mac dinh serialize KHONG co 'Z'
// (vd "2026-06-23T08:20:00") -> FE new Date(naive) hieu la LOCAL -> lech +7h (VN UTC+7,
// "moi tao ma bao 7h truoc"). Converter nay ep serialize UTC ISO-8601 CO 'Z' -> FE new
// Date("...Z") convert dung ve local. System.Text.Json tu dung converter nay cho non-null
// value cua DateTime? (Nullable) nen khong can dang ky rieng cho DateTime?.
public sealed class UtcDateTimeJsonConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
=> reader.GetDateTime();
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
var utc = value.Kind switch
{
DateTimeKind.Utc => value,
DateTimeKind.Local => value.ToUniversalTime(),
_ => DateTime.SpecifyKind(value, DateTimeKind.Utc), // Unspecified (tu EF) = coi la UTC
};
writer.WriteStringValue(utc.ToString("O")); // ISO-8601 round-trip, co 'Z'
}
}