1 /// Provides a wrapper around a `mg_local_time`. Uses `std.datetime.systime.SysTime` internally. 2 module memgraph.local_time; 3 4 import memgraph.mgclient, memgraph.detail, memgraph.value, memgraph.enums; 5 import st = std.datetime.systime; 6 import sd = std.datetime.date; 7 import ct = core.time; 8 9 /// Represents a local time. 10 /// Time is defined with nanoseconds since midnight. 11 struct LocalTime { 12 /// Create a shallow copy of `other` LocalTime. 13 this(inout ref LocalTime other) { 14 this(other.ptr); 15 } 16 17 /// Create a local time from a Value. 18 this(inout ref Value value) { 19 assert(value.type == Type.LocalTime); 20 this(mg_value_local_time(value.ptr)); 21 } 22 23 /// Compares this local time with `other`. 24 /// Return: true if same, false otherwise. 25 @nogc auto opEquals(const ref LocalTime other) const { 26 return Detail.areLocalTimesEqual(ptr_, other.ptr_); 27 } 28 29 /// Return a printable string representation of this local time. 30 string toString() const { 31 import std.format; 32 return format!("%02d:%02d:%02d.%09d")(localTime_.hour, localTime_.minute, localTime_.second, 33 localTime_.fracSecs.total!"nsecs"); 34 } 35 36 /// Return the hash code for this local time. 37 size_t toHash() const nothrow @safe { 38 return cast(ulong)ptr_; 39 } 40 41 /// Returns nanoseconds since midnight. 42 @nogc auto nanoseconds() const { return nanoSeconds_; } 43 44 package: 45 /// Create a LocalTime using the given `mg_local_time` pointer. 46 this(inout mg_local_time *ptr) { 47 assert(ptr != null); 48 ptr_ = ptr; 49 nanoSeconds_ = mg_local_time_nanoseconds(ptr); 50 immutable auto now = st.Clock.currTime(); 51 localTime_ = st.SysTime(sd.DateTime(now.year, now.month, now.day, 0, 0, 0)); 52 localTime_ += ct.nsecs(nanoSeconds_); 53 } 54 55 /// Returns the internal `mg_local_time` pointer. 56 @nogc auto ptr() inout { 57 return ptr_; 58 } 59 60 private: 61 const mg_local_time *ptr_; 62 st.SysTime localTime_; 63 long nanoSeconds_; 64 alias localTime_ this; 65 } // struct LocalTime 66 67 unittest { 68 import testutils : connectContainer; 69 import std.conv : to; 70 71 auto client = connectContainer(); 72 assert(client); 73 74 auto result = client.execute(`return localtime('12:34:56.100');`); 75 assert(result, client.error); 76 foreach (r; result) { 77 assert(r.length == 1); 78 assert(r[0].type() == Type.LocalTime); 79 const t = to!LocalTime(r[0]); 80 assert(t.toString == "12:34:56.100000000", t.toString); 81 assert(t.nanoseconds == 45_296_100_000_000); 82 } 83 } 84 85 unittest { 86 import std.conv : to; 87 88 auto tm = mg_local_time_make(45_296_100_000_000); 89 assert(tm != null); 90 91 auto t = LocalTime(tm); 92 assert(t.nanoseconds == 45_296_100_000_000); 93 94 const t1 = t; 95 assert(t1 == t); 96 97 assert(to!string(t) == "12:34:56.100000000"); 98 assert(t.toString == "12:34:56.100000000"); 99 100 st.SysTime st = t; 101 import std.format; 102 assert(format!("%02d:%02d:%02d.%09d")(st.hour, st.minute, st.second, 103 st.fracSecs.total!"nsecs") == t.toString); 104 105 auto t2 = LocalTime(t.ptr); 106 assert(t2 == t); 107 108 const t3 = LocalTime(t2); 109 assert(t3 == t); 110 111 const t5 = LocalTime(t3); 112 assert(t5 == t3); 113 114 auto v = Value(mg_value_make_local_time(tm)); 115 assert(to!string(v) == "12:34:56.100000000", to!string(v)); 116 117 assert(cast(ulong)t.ptr == t.toHash); 118 }