1 /** Contains functions for converting an exact date to a fuzzy human readable form. 2 */ 3 module fuzzydate; 4 5 import std.datetime : Clock, SysTime, UTC; 6 7 /** Converts a certain date/time to a fuzzy string. 8 9 Params: 10 time = The point in time to convert to a fuzzy string 11 now = Optional time value to customize the reference time, i.e. the present 12 dst = Output range to write the result into 13 14 Returns: 15 The non-range based overloads will return the fuzzy representation as a `string` 16 */ 17 string toFuzzyDate(SysTime time) 18 { 19 return toFuzzyDate(time, Clock.currTime(UTC())); 20 } 21 22 /// ditto 23 string toFuzzyDate(SysTime time, SysTime now) 24 { 25 import std.array : appender; 26 auto app = appender!string(); 27 app.toFuzzyDate(time, now); 28 return app.data; 29 } 30 31 /// ditto 32 void toFuzzyDate(R)(ref R dst, SysTime time) 33 { 34 toFuzzyDate(dst, time, Clock.currTime(UTC())); 35 } 36 37 /// ditto 38 void toFuzzyDate(R)(ref R dst, SysTime time, SysTime now) 39 { 40 import core.time : dur; 41 import std.format : formattedWrite; 42 43 auto tm = now - time; 44 if (tm < dur!"seconds"(0)) dst.put("still going to happen"); 45 else if (tm < dur!"seconds"(10)) dst.put("just now"); 46 else if (tm < dur!"minutes"(1)) dst.put("less than a minute ago"); 47 else if (tm < dur!"minutes"(2)) dst.put("a minute ago"); 48 else if (tm < dur!"hours"(1)) dst.formattedWrite("%s minutes ago", tm.total!"minutes"()); 49 else if (tm < dur!"hours"(2)) dst.put("an hour ago"); 50 else if (tm < dur!"days"(1)) dst.formattedWrite("%s hours ago", tm.total!"hours"()); 51 else if (tm < dur!"days"(2)) dst.put("a day ago"); 52 else if (tm < dur!"weeks"(5)) dst.formattedWrite("%s days ago", tm.total!"days"()); 53 else if (tm < dur!"weeks"(52)) { 54 auto m1 = time.month; 55 auto m2 = now.month; 56 auto months = (now.year - time.year) * 12 + m2 - m1; 57 if (months == 1) dst.put("a month ago"); 58 else dst.formattedWrite("%s months ago", months); 59 } else if (now.year - time.year <= 1) dst.put("a year ago"); 60 else dst.formattedWrite("%s years ago", now.year - time.year); 61 } 62 63 /// 64 unittest { 65 SysTime tm(string timestr) { return SysTime.fromISOExtString(timestr); } 66 assert(toFuzzyDate(tm("2015-11-12T19:59:59Z"), tm("2015-11-12T20:00:00Z")) == "just now"); 67 assert(toFuzzyDate(tm("2015-11-12T19:58:55Z"), tm("2015-11-12T20:00:00Z")) == "a minute ago"); 68 assert(toFuzzyDate(tm("2015-11-02T12:00:00Z"), tm("2015-11-12T20:00:00Z")) == "10 days ago"); 69 assert(toFuzzyDate(tm("2014-06-06T12:00:00Z"), tm("2015-11-12T20:00:00Z")) == "a year ago"); 70 }