From c61ff564729fbab84a9246d472a82cc298b7a4ef Mon Sep 17 00:00:00 2001 From: Mykhailo Temnokhud Date: Wed, 14 Jan 2026 10:07:12 +0100 Subject: [PATCH] feat: add option to serialize DateTime values as UTC --- drift/lib/src/runtime/data_class.dart | 25 +++++++++++++------ .../drift3/lib/src/database/data_class.dart | 18 ++++++++++--- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/drift/lib/src/runtime/data_class.dart b/drift/lib/src/runtime/data_class.dart index 106ec3db1..e59703738 100644 --- a/drift/lib/src/runtime/data_class.dart +++ b/drift/lib/src/runtime/data_class.dart @@ -207,8 +207,10 @@ abstract class ValueSerializer { /// timestamp ([DateTime.millisecondsSinceEpoch]) or a string /// ([DateTime.toIso8601String]). /// In either case, date time values can be _deserialized_ from both formats. - const factory ValueSerializer.defaults( - {bool serializeDateTimeValuesAsString}) = _DefaultValueSerializer; + const factory ValueSerializer.defaults({ + bool serializeDateTimeAsUtc, + bool serializeDateTimeValuesAsString, + }) = _DefaultValueSerializer; /// Converts the [value] to something that can be passed to /// [JsonCodec.encode]. @@ -220,9 +222,13 @@ abstract class ValueSerializer { } class _DefaultValueSerializer extends ValueSerializer { + final bool serializeDateTimeAsUtc; final bool serializeDateTimeValuesAsString; - const _DefaultValueSerializer({this.serializeDateTimeValuesAsString = false}); + const _DefaultValueSerializer({ + this.serializeDateTimeAsUtc = false, + this.serializeDateTimeValuesAsString = false, + }); @override T fromJson(dynamic json) { @@ -234,7 +240,11 @@ class _DefaultValueSerializer extends ValueSerializer { if (typeList is List) { if (json is int) { - return DateTime.fromMillisecondsSinceEpoch(json) as T; + return DateTime.fromMillisecondsSinceEpoch( + json, + isUtc: serializeDateTimeAsUtc, + ) + as T; } else { return DateTime.parse(json.toString()) as T; } @@ -246,7 +256,7 @@ class _DefaultValueSerializer extends ValueSerializer { // blobs are encoded as a regular json array, so we manually convert that to // a Uint8List - if (typeList is List && json is! Uint8List) { + if (json is! Uint8List) { final asList = (json as List).cast(); return Uint8List.fromList(asList) as T; } @@ -257,9 +267,10 @@ class _DefaultValueSerializer extends ValueSerializer { @override dynamic toJson(T value) { if (value is DateTime) { + final dateTime = (serializeDateTimeAsUtc ? value.toUtc() : value); return serializeDateTimeValuesAsString - ? value.toIso8601String() - : value.millisecondsSinceEpoch; + ? dateTime.toIso8601String() + : dateTime.millisecondsSinceEpoch; } return value; diff --git a/future/drift3/lib/src/database/data_class.dart b/future/drift3/lib/src/database/data_class.dart index 01498a319..cc7d48fb8 100644 --- a/future/drift3/lib/src/database/data_class.dart +++ b/future/drift3/lib/src/database/data_class.dart @@ -202,6 +202,7 @@ abstract class ValueSerializer { /// ([DateTime.toIso8601String]). /// In either case, date time values can be _deserialized_ from both formats. const factory ValueSerializer.defaults({ + bool serializeDateTimeAsUtc, bool serializeDateTimeValuesAsString, }) = _DefaultValueSerializer; @@ -215,9 +216,13 @@ abstract class ValueSerializer { } class _DefaultValueSerializer extends ValueSerializer { + final bool serializeDateTimeAsUtc; final bool serializeDateTimeValuesAsString; - const _DefaultValueSerializer({this.serializeDateTimeValuesAsString = false}); + const _DefaultValueSerializer({ + this.serializeDateTimeAsUtc = false, + this.serializeDateTimeValuesAsString = false, + }); @override T fromJson(dynamic json) { @@ -229,7 +234,11 @@ class _DefaultValueSerializer extends ValueSerializer { if (typeList is List) { if (json is int) { - return DateTime.fromMillisecondsSinceEpoch(json) as T; + return DateTime.fromMillisecondsSinceEpoch( + json, + isUtc: serializeDateTimeAsUtc, + ) + as T; } else { return DateTime.parse(json.toString()) as T; } @@ -252,9 +261,10 @@ class _DefaultValueSerializer extends ValueSerializer { @override dynamic toJson(T value) { if (value is DateTime) { + final dateTime = (serializeDateTimeAsUtc ? value.toUtc() : value); return serializeDateTimeValuesAsString - ? value.toIso8601String() - : value.millisecondsSinceEpoch; + ? dateTime.toIso8601String() + : dateTime.millisecondsSinceEpoch; } return value;