1 /// Provides a wrapper around a `mg_date_time`. 2 module memgraph.date_time; 3 4 import memgraph.mgclient, memgraph.detail, memgraph.value, memgraph.enums; 5 6 /// Represents date and time with its time zone. 7 /// 8 /// Date is defined with seconds since the adjusted Unix epoch. 9 /// Time is defined with nanoseconds since midnight. 10 /// Time zone is defined with minutes from UTC. 11 struct DateTime { 12 13 /// Create a deep copy of `other` date time. 14 this(inout ref DateTime other) { 15 this(mg_date_time_copy(other.ptr)); 16 } 17 18 /// Create a date time from a Value. 19 this(inout ref Value value) { 20 assert(value.type == Type.DateTime); 21 this(mg_date_time_copy(mg_value_date_time(value.ptr))); 22 } 23 24 /// Assigns a date time to another. The target of the assignment gets detached from 25 /// whatever date time it was attached to, and attaches itself to the new date time. 26 ref DateTime opAssign(DateTime rhs) @safe return { 27 import std.algorithm.mutation : swap; 28 swap(this, rhs); 29 return this; 30 } 31 32 /// Return a printable string representation of this date time. 33 const (string) toString() const { 34 import std.conv : to; 35 return to!string(seconds) ~ " " ~ to!string(nanoseconds) ~ " " ~ to!string(tz_offset_minutes); 36 } 37 38 /// Compares this date time with `other`. 39 /// Return: true if same, false otherwise. 40 bool opEquals(const ref DateTime other) const { 41 return Detail.areDateTimesEqual(ptr_, other.ptr); 42 } 43 44 /// Returns seconds since Unix epoch. 45 const (long) seconds() const { return mg_date_time_seconds(ptr_); } 46 47 /// Returns nanoseconds since midnight. 48 const (long) nanoseconds() const { return mg_date_time_nanoseconds(ptr_); } 49 50 /// Returns time zone offset in minutes from UTC. 51 const (long) tz_offset_minutes() const { return mg_date_time_tz_offset_minutes(ptr_); } 52 53 this(this) { 54 if (ptr_) 55 ptr_ = mg_date_time_copy(ptr_); 56 } 57 58 @safe @nogc ~this() { 59 if (ptr_) 60 mg_date_time_destroy(ptr_); 61 } 62 63 package: 64 /// Create a DateTime using the given `mg_date_time`. 65 this(mg_date_time *ptr) @trusted { 66 assert(ptr != null); 67 ptr_ = ptr; 68 } 69 70 /// Create a DateTime from a copy of the given `mg_date_time`. 71 this(const mg_date_time *ptr) { 72 assert(ptr != null); 73 this(mg_date_time_copy(ptr)); 74 } 75 76 const (mg_date_time *) ptr() const { return ptr_; } 77 78 private: 79 mg_date_time *ptr_; 80 } 81 82 unittest { 83 import std.conv : to; 84 import memgraph.enums; 85 86 auto tm = mg_date_time_alloc(&mg_system_allocator); 87 assert(tm != null); 88 tm.seconds = 23; 89 tm.nanoseconds = 42; 90 tm.tz_offset_minutes = 60; 91 92 auto t = DateTime(tm); 93 assert(t.seconds == 23); 94 assert(t.nanoseconds == 42); 95 assert(t.tz_offset_minutes == 60); 96 97 const t1 = t; 98 assert(t1 == t); 99 100 assert(to!string(t) == "23 42 60"); 101 102 auto t2 = DateTime(mg_date_time_copy(t.ptr)); 103 assert(t2 == t); 104 105 const t3 = DateTime(t2); 106 assert(t3 == t); 107 108 const v = Value(t); 109 const t4 = DateTime(v); 110 assert(t4 == t); 111 assert(v == t); 112 assert(to!string(v) == to!string(t)); 113 114 t2 = t; 115 assert(t2 == t); 116 117 const v1 = Value(t2); 118 assert(v1.type == Type.DateTime); 119 const v2 = Value(t2); 120 assert(v2.type == Type.DateTime); 121 122 assert(v1 == v2); 123 124 const t5 = DateTime(t3); 125 assert(t5 == t3); 126 }