1 /* This file is part of the Amalthea library. 2 * 3 * Copyright (C) 2021, 2024 Eugene 'Vindex' Stulin 4 * 5 * Distributed under the Boost Software License 1.0 or (at your option) 6 * the GNU Lesser General Public License 3.0 or later. 7 */ 8 9 module amalthea.time; 10 11 import core.stdc.time; 12 import core.sys.posix.signal : timespec; 13 import core.thread : Thread; 14 15 public import amalthea.libcore; 16 import amalthea.sys : SysException; 17 18 import 19 std.datetime, 20 std.datetime.systime, 21 std.string; 22 23 24 /******************************************************************************* 25 * The function returns number of seconds since 1970-01-01. 26 * Params: 27 * timeString = String with the format 'YYYY-MM-DD hh:mm:ss' 28 * or 'YYYY-MM-DDThh:mm:ss'. 29 * If the string is empty, the function returns current time. 30 * By default, empty. 31 */ 32 long unixTime(string timeString = "") { 33 if (timeString.empty) { 34 return core.stdc.time.time(null); 35 } 36 timeString = timeString.replace(" ", "T"); 37 return SysTime(DateTime.fromISOExtString(timeString)).toUnixTime(); 38 } 39 40 41 /******************************************************************************* 42 * Gets a time string from the std.datetime.systime.SysTime object. 43 * Returns: String with format "YYYY-MM-DD HH:MM:SS". 44 */ 45 string getTimeString(SysTime sysTime) { 46 return sysTime.toISOExtString().replace("T"," ").split('.')[0]; 47 } 48 49 50 /******************************************************************************* 51 * Gets a time string with the current time. 52 * Returns: String with format "YYYY-MM-DD HH:MM:SS". 53 */ 54 string getTimeString() { 55 return getTimeString(Clock.currTime); 56 } 57 58 59 /******************************************************************************* 60 * Gets a time string by UNIX time (number of seconds). 61 * Returns: String with format "YYYY-MM-DD HH:MM:SS". 62 */ 63 string getTimeString(long secondsByUnixTime) { 64 return getTimeString(SysTime.fromUnixTime(secondsByUnixTime)); 65 } 66 67 68 /******************************************************************************* 69 * Gets a time string by timestamp (only seconds from timestamp is used). 70 * Returns: String with format "YYYY-MM-DD HH:MM:SS". 71 */ 72 string getTimeString(timestamp_t t) { 73 return getTimeString(SysTime.fromUnixTime(t.tv_sec)); 74 } 75 76 77 /******************************************************************************* 78 * Gets a time string by timestamp content with nanoseconds. 79 * Returns: String with format "YYYY-MM-DD HH:MM:SS.NNNNNNNNN". 80 */ 81 string getTimeExtString(timestamp_t t) { 82 string part1 = getTimeString(SysTime.fromUnixTime(t.tv_sec)); 83 string nsecs = format!"%09d"(t.tv_nsec); 84 return part1 ~ "." ~ nsecs; 85 } 86 87 88 /******************************************************************************* 89 * Gets a string containing the current time with nanoseconds. 90 * Returns: String with format "YYYY-MM-DD HH:MM:SS.NNNNNNNNN". 91 */ 92 string getTimeExtString() { 93 return getTimeExtString(getCurrentTimestamp()); 94 } 95 96 97 /******************************************************************************* 98 * UNIX timestamp structure. 99 * Corresponds to C structure types 'statx_timestamp' and 'timespec'. 100 */ 101 extern(C) 102 struct timestamp_t { 103 /// Seconds since the Epoch (UNIX time). 104 long tv_sec; 105 /// Nanoseconds since tv_sec. 106 uint tv_nsec; 107 } 108 109 110 extern(C) private int clock_gettime(int __clock_id, timespec *__tp); 111 112 113 /******************************************************************************* 114 * Current time as timestamp_t. 115 */ 116 timestamp_t getCurrentTimestamp() { 117 timespec t; 118 enum CLOCK_REALTIME = 0; 119 int ret = clock_gettime(CLOCK_REALTIME, &t); 120 enforce(ret != 1, new SysException("clock_gettime")); 121 timestamp_t ts = { cast(long)t.tv_sec, cast(uint)t.tv_nsec }; 122 return ts; 123 } 124 125 126 /******************************************************************************* 127 * Transforms UNIX timestamp structure to std.datetime.systime.SysTime. 128 * SysTime stores hectonanoseconds, so some of the timestamp info is lost. 129 */ 130 SysTime convTimestampToSysTime(timestamp_t t) { 131 ulong hnsecs = t.tv_sec * 10_000_000 + t.tv_nsec / 100; 132 return SysTime(621_355_968_000_000_000L + hnsecs); 133 } 134 135 136 /******************************************************************************* 137 * Returns string with timezone offset (hours and minutes) like +0300 or -0700. 138 */ 139 string getTZOffsetAsString() { 140 Duration d = LocalTime().utcOffsetAt(Clock.currTime().stdTime); 141 int hours, minutes; 142 abs(d).split!("hours", "minutes")(hours, minutes); 143 auto offsetFmt = d < Duration.zero ? "-%02d%02d" : "+%02d%02d"; 144 return format(offsetFmt, hours, minutes); 145 } 146 147 148 /******************************************************************************* 149 * The function makes a delay, expressed in seconds. 150 */ 151 void sleep(double seconds) { 152 ulong microseconds = (seconds <= 0) ? 0 : to!ulong(seconds * (10^^6)); 153 Thread.sleep(dur!("usecs")(microseconds)); 154 } 155 156 157 /******************************************************************************* 158 * The function makes a delay, expressed in milliseconds. 159 */ 160 void msleep(ulong milliseconds) { 161 Thread.sleep(dur!("msecs")(milliseconds)); 162 } 163 164 165 /******************************************************************************* 166 * The function makes a delay, expressed in microseconds. 167 */ 168 void usleep(ulong microseconds) { 169 Thread.sleep(dur!("usecs")(microseconds)); 170 } 171