Hive: Retrieving DateTime from Hive storage precision is being lost.

Created on 20 Oct 2020  路  5Comments  路  Source: hivedb/hive

Question
When retrieving DateTime from storage the precision is lost, the precision is maintained when stored in memory it is only when retrieval from storage is triggered that the resulting date has now lost precision.

Code sample

var myBox = await Hive.openBox('myBox');
if(myBox.get('dateTest') == null)
{
var timeToStore = DateTime.parse('2020-10-19 18:11:29.497022');
await myBox.put('dateTest', timeToStore);
print('Storing date in HIVE');
}
print(await myBox.get('dateTest'));

// RESTART APP

This code will display the date correctly after it is first stored and being retrieved from memory, but after restarting the app the date retrieved from storage and then shown is

2020-10-19 18:11:29.497000

which has lost the precision compared with memory storage.

Version

  • Platform: iOS
  • Flutter version: stable, 1.22.2, on Mac OS X 10.15.6 19G2021, locale en-GB
  • Hive version: 1.4.4+1

    • Hive Flutter: 0.3.1

question

Most helpful comment

It's not currently possible to changing precision because this will invalidate all exists hivedb data. Instead we might add feature for overriding internal adapters so you could use custom DateTime adapter with high precision.

All 5 comments

Hive stores datetime in milliseconds precision.

Thank you for the reply.

As I understand it Hive in my example is storing the date value in memory after the first PUT and to a higher precision than milliseconds with Effectively no loss of precision to the date That I passed to PUT.

It is only after Hive retrieves the Date value from permanent storage that the precision becomes reduced to Milliseconds. (Or I assume technically when it was written to storage).

This is problematic because a date retrieved from memory will not compare correctly with dates retrieved from storage.

This discrepancy is not ideal and if Hive is to operate at milliseconds precision it would be best to reduce precision when stored and retrieved from memory also.

I can workaround this by reducing precision before first storage but it does seem consistency within Hive itself would be ideal.

@TheMisir I agree with @cimatt55 . I also face issues in comparison. Like, we need the precision in microseconds, not milliseconds.

I literally spent an hour on finding why my 2 objects were not compared properly, even if they contained the same data inside.

It's not currently possible to changing precision because this will invalidate all exists hivedb data. Instead we might add feature for overriding internal adapters so you could use custom DateTime adapter with high precision.

I just merged #484. I'll publish the update to pub.dev ASAP.

Here's how you can increase precision of datetime adapter:

/// A bit modified DateTimeWithTimezoneAdapter (https://github.com/hivedb/hive/blob/master/hive/lib/src/adapters/date_time_adapter.dart#L25-L42)
class PerciseDateTimeAdapter extends TypeAdapter<DateTime> {
  @override
  final typeId = 18;

  @override
  DateTime read(BinaryReader reader) {
    var micros = reader.readInt();
    var isUtc = reader.readBool();
    return DateTime.fromMicrosecondsSinceEpoch(micros, isUtc: isUtc);
  }

  @override
  void write(BinaryWriter writer, DateTime obj) {
    writer.writeInt(obj.microsecondsSinceEpoch);
    writer.writeBool(obj.isUtc);
  }
}

Hive.initFlutter();
Hive.registerAdapter(PerciseDateTimeAdapter(), override: true, internal: true);

I couldn't increase precision generally because this will invalidate all available data, Instead you can create & register custom adapters with newly added (not yet published) override and internal flags.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ProfileID picture ProfileID  路  4Comments

juandiago picture juandiago  路  4Comments

jamesdixon picture jamesdixon  路  3Comments

SergeShkurko picture SergeShkurko  路  4Comments

yaymalaga picture yaymalaga  路  4Comments