1 /** 2 * Duration functions. 3 * 4 * License: 5 * This Source Code Form is subject to the terms of 6 * the Mozilla Public License, v. 2.0. If a copy of 7 * the MPL was not distributed with this file, You 8 * can obtain one at http://mozilla.org/MPL/2.0/. 9 * 10 * Authors: 11 * Vladimir Panteleev <ae@cy.md> 12 */ 13 14 module ae.utils.time.fpdur; 15 16 import core.time; 17 18 /// A variant of core.time.dur which accepts floating-point values. 19 /// Useful for parsing command-line arguments. 20 /// Beware of rounding / floating-point errors! Do not use where precision matters. 21 template dur(string units) 22 if (units == "weeks" || 23 units == "days" || 24 units == "hours" || 25 units == "minutes" || 26 units == "seconds" || 27 units == "msecs" || 28 units == "usecs" || 29 units == "hnsecs" || 30 units == "nsecs") 31 { 32 Duration dur(T)(T length) @safe pure nothrow @nogc 33 if (is(T : real) && !is(T : ulong)) 34 { 35 auto hnsecs = length * convert!(units, "hnsecs")(1); 36 // https://issues.dlang.org/show_bug.cgi?id=15900 37 static import core.time; 38 return core.time.hnsecs(cast(long)hnsecs); 39 } 40 } 41 42 alias weeks = dur!"weeks"; /// Ditto 43 alias days = dur!"days"; /// Ditto 44 alias hours = dur!"hours"; /// Ditto 45 alias minutes = dur!"minutes"; /// Ditto 46 alias seconds = dur!"seconds"; /// Ditto 47 alias msecs = dur!"msecs"; /// Ditto 48 alias usecs = dur!"usecs"; /// Ditto 49 alias hnsecs = dur!"hnsecs"; /// Ditto 50 alias nsecs = dur!"nsecs"; /// Ditto 51 52 /// 53 unittest 54 { 55 import core.time : msecs; 56 static assert(1.5.seconds == 1500.msecs); 57 } 58 59 /// Multiply a duration by a floating-point number. 60 Duration durScale(F)(Duration d, F f) 61 if (is(F : real)) 62 { 63 return hnsecs(d.total!"hnsecs" * f); 64 } 65 66 /// 67 unittest 68 { 69 import core.time : seconds, msecs; 70 assert(durScale(1.seconds, 1.5) == 1500.msecs); 71 } 72 73 /// Like d.total!units, but returns fractional parts as well. 74 T fracTotal(string units, T = real)(Duration d) 75 { 76 return T(d.total!"hnsecs") / convert!(units, "hnsecs")(1); 77 } 78 79 /// 80 unittest 81 { 82 import core.time : seconds, msecs; 83 assert(1500.msecs.fracTotal!"seconds" == 1.5); 84 }