objectbox-dart
objectbox-dart copied to clipboard
UTC DateTime are getting converted to Local DateTime
Save any variable with @Property(type: PropertyType.date)
annotation with value as DateTime.now().toUtc()
Read the same variable DateTime comes back in local time zone and UTC flag is false
-
ObjectBox version: [e.g. 0.14.0] objectbox: ^1.2.0 objectbox_flutter_libs: ^1.2.0
-
Flutter/Dart SDK: [e.g. 2.0.0, or the output of
dart --version
orflutter --version
] Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter.git Framework • revision f4abaa0735 (9 weeks ago) • 2021-07-01 12:46:11 -0700 Engine • revision 241c87ad80 Tools • Dart 2.13.4 -
Null-safety enabled: [yes | no] yes
-
Reproducibility: [e.g. occurred once only | occasionally without visible pattern | always] always
-
Device/Emulator: [e.g. Galaxy S20] iPhone 8+ Simulator
Additionally, you can choose to provide more details, e.g. the output of:
Steps to reproduce
- Put any entity class having variable as date in UTC
- Read the same entity class
- DateTime comes back in local timezone
Expected behavior
Date time should be in UTC only
I'll start building an application that has many datetime fields. Should I store the milliseconds in utc and always do the conversion to datetime or can I trust that the utc flag will be fixed without changing any values in future releases?
I can confirm this bug. I was just running into it, and found this issue...
DateTime
is stored as milliseconds (Unix timestamp) without any time zone information. When reading an object a DateTime
property is restored with DateTime.fromMillisecondsSinceEpoch
. The reasoning behind this is that most code won't explicitly use UTC time, but use the device default. So when reading an object ObjectBox also restores using the default time zone.
Edit: one could add a converter (custom getter/setter) that uses DateTime.fromMillisecondsSinceEpoch(value, isUtc: true)
instead.
Example for the above:
@Transient()
DateTime? utcDate;
int? get dbUtcDate => utcDate?.millisecondsSinceEpoch;
set dbUtcDate(int? value) {
utcDate = value == null
? null
: DateTime.fromMillisecondsSinceEpoch(value, isUtc: true);
}
The main problem is, that the server I communicate, needs datetime with time zone information. If I get the datetime fields from the db, I get non utc datetime even if I store it in utc form.
And there is the DateTime.toIso8601String() dart function, which would convert the DateTime with timezone, if it would be utc (isUtc = true).
So the question is: how can we store (and read) DateTime with timezone in objectbox?
@ebadta81 I'm confused. You say you want to store using time in UTC (so time without time zone). Why does the above suggestion using a getter/setter then not work for you?
@ebadta81 I'm confused. You say you want to store using time in UTC (so time without time zone). Why does the above suggestion using a getter/setter then not work for you?
I use the dart json_serializable package, for automated json serialisation. This package use the DateTime.toIso8601String() dart function in the generated code.
I would like to use objectbox and json_serializable out of the box.
My server needs the datetime with timezone. I checked the toIso8601String() function, and it gives timezone string if the datetime is utc
if (isUtc) {
return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
} else {
return "$y-$m-${d}T$h:$min:$sec.$ms$us";
}
You are right, I can use a getter/setter in my classes, but I have to define it for every DateTime field in every class, and it has some overhead.
in summary, I would like to produce datetime fields with timezone information in my json structure, and send it to the server.
@ebadta81
I had the exact same requiment
I am storing values as local date time only and before sending to the server, I am doing a loop over the list (after reading from the database) to convert the time to UTC. I thought this would be a better option than getter and setter. I may be wrong though.
@ebadta81
I had the exact same requiment
I am storing values as local date time only and before sending to the server, I am doing a loop over the list (after reading from the database) to convert the time to UTC. I thought this would be a better option than getter and setter. I may be wrong though.
Hehe, I do exactly the same, in my code. :)
But this is only a workaround for the objectbox design problem.
So we are thinking about changing the read back milliseconds value to be converted using DateTime.fromMillisecondsSinceEpoch(value, isUtc: true)
. So DateTime
of a read Object would be in UTC.
This would make sense as a DateTime
is stored by using DateTime.millisecondsSinceEpoch
which obtains a "Unix epoch" timestamp, which is also UTC.
The problem is this does break existing code, no? E.g. to display the value in the UI with https://pub.dev/packages/intl it would then be necessary to call DateTime.toLocal()
first to get the same time zone as before.
@greenrobot-team Yes it will break the existing code, not only for display but also in case of query operations. But, I guess you can put it in migration note. So anybody switching to newer branch will also change their code.
Another option (non-breaking) would be to provide an annotation/option to switch to reading UTC time. For example like on the following fields:
@Property(type: PropertyType.date, isUtc: true)
int date;
@Property(isUtc: true)
DateTime date;
or
@UTC
DateTime date;
That is the correct way to do it.
Is this already available or a proposal ?
This proposal is available?
This proposal is available?
Not yet. We were asking for feedback on what is preferred.
Maybe the best choice would be the @Property(isUtc: true) Thanks
Maybe the best choice would be the @Property(isUtc: true) Thanks
I try to write a program with a lot of DateTime values and everything should be always in UTC.
So having some tool like @Property(isUtc: true)
soon, would be awesome!
This proposal is available?
Not yet. We were asking for feedback on what is preferred.
@Property(type: PropertyType.date, isUtc: true)
DateTime date;
would be the most consistent solution compared to, how DateTime values are handled.
@Utc
DateTime date;
would be the shortest one.
with moder IDE's and autocomplete, I would prefer the most consistent solution to already existing code.