Last active
August 16, 2020 17:54
-
-
Save inhumantsar/3de42176c87b8845702b32f390865753 to your computer and use it in GitHub Desktop.
naturalDuration testing for humanize
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void main() { | |
print("# core values"); | |
var dayCounts = [ | |
-700, | |
-365, | |
-90, | |
-30, | |
-15, | |
-7, | |
-2, | |
-1, | |
-0.5, | |
0.5, | |
1, | |
2, | |
5, | |
7, | |
10, | |
15, | |
20, | |
25, | |
30, | |
40, | |
50, | |
70, | |
80, | |
100, | |
150, | |
200, | |
300, | |
400, | |
500, | |
700, | |
900, | |
1200 | |
]; | |
for (var count in dayCounts) { | |
var date = DateTime.now().add(Duration(hours: count * 24)); | |
print("$count days: " + naturalDuration(date)); | |
} | |
print(""); | |
print("# without Adposition"); | |
dayCounts = [ | |
-700, | |
-365, | |
-90, | |
-30, | |
-15, | |
-7, | |
-5, | |
-1, | |
-0.5, | |
0.5, | |
1, | |
5, | |
7, | |
15, | |
30, | |
90, | |
365, | |
700 | |
]; | |
for (var count in dayCounts) { | |
var date = DateTime.now().add(Duration(hours: count * 24)); | |
print("$count days: " + naturalDuration(date, applyAdposition: false)); | |
} | |
print(""); | |
print("# AP-style"); | |
dayCounts = [ | |
-5475, | |
-700, | |
-365, | |
-90, | |
-30, | |
-15, | |
-7, | |
-5, | |
-1, | |
-0.5, | |
0.5, | |
1, | |
5, | |
7, | |
15, | |
30, | |
90, | |
365, | |
700, | |
5475 | |
]; | |
for (var count in dayCounts) { | |
var date = DateTime.now().add(Duration(hours: count * 24)); | |
print("$count days: " + naturalDuration(date, applyAppNumber: true)); | |
} | |
print(""); | |
print("# AP-style without Adposition"); | |
dayCounts = [ | |
-5475, | |
-700, | |
-365, | |
-90, | |
-30, | |
-15, | |
-7, | |
-5, | |
-1, | |
-0.5, | |
0.5, | |
1, | |
5, | |
7, | |
15, | |
30, | |
90, | |
365, | |
700, | |
5475 | |
]; | |
for (var count in dayCounts) { | |
var date = DateTime.now().add(Duration(hours: count * 24)); | |
print("$count days: " + | |
naturalDuration(date, applyAppNumber: true, applyAdposition: false)); | |
} | |
} | |
String appNumber(int value) { | |
List values = [ | |
"one", | |
"two", | |
"three", | |
"four", | |
"five", | |
"six", | |
"seven", | |
"eight", | |
"nine" | |
]; | |
if (value < 0 || value > 10) { | |
return "$value"; | |
} else { | |
return values[value - 1]; | |
} | |
} | |
/// adds "in" or "ago" to a natural duration phrase. eg: "in 5 days", "2 months ago". | |
// this will be more useful when attempting internationalisation | |
String _applyAdposition(String value, bool inPast) { | |
var modifier = inPast ? "ago" : "in"; | |
var isSuffix = inPast ? true : false; | |
if (isSuffix) | |
return value + " " + modifier; | |
else | |
return modifier + " " + value; | |
} | |
/// Present date values as a string in natural duration units like weeks, months, | |
/// and years relative to the current date. | |
/// Examples: | |
/// * A date 14 days in the past would return "2 weeks ago". | |
/// * A date 40 days in the future would return "in 6 weeks". | |
/// * A date 700 days in the past would return "2 years ago". | |
/// Supports only English duration and unit names currently. | |
String naturalDuration(DateTime value, | |
{bool applyAdposition = true, bool applyAppNumber = false}) { | |
var duration = value.difference(DateTime.now()); | |
var inPast = duration.inMilliseconds < 0; | |
var days = duration.inDays.abs(); | |
// TODO: use naturalTime and naturalDay here | |
if (days < 1) return inPast ? "earlier today" : "today"; | |
if (days < 2) return inPast ? "yesterday" : "tomorrow"; | |
var weeks = (days / 7).round(); | |
var months = (days / 30).round(); | |
var years = (days / 365).round(); | |
var phrase; | |
// up to 10 days, but not 1 week exactly | |
if (days < 11 && days != 7) { | |
phrase = "${applyAppNumber ? appNumber(days) : days} days"; | |
} | |
// one week | |
else if (weeks == 1) { | |
phrase = "${applyAppNumber ? appNumber(weeks) : weeks} week"; | |
} | |
// multiple weeks but not 4 weeks (eg: 3 weeks, 6 weeks) | |
else if (weeks != 4 && weeks < 8) { | |
phrase = "${applyAppNumber ? appNumber(weeks) : weeks} weeks"; | |
} | |
// 1 month | |
else if (weeks == 4) { | |
phrase = "${applyAppNumber ? appNumber(months) : months} month"; | |
} | |
// multiple months | |
else if (months < 12) { | |
phrase = "${applyAppNumber ? appNumber(months) : months} months"; | |
} | |
// 1 year | |
else if (years == 1) { | |
phrase = "${applyAppNumber ? appNumber(years) : years} year"; | |
} | |
// multiple years | |
else if (years > 1) { | |
phrase = "${applyAppNumber ? appNumber(years) : years} years"; | |
} | |
// TODO: raise exception if term is still null | |
return applyAdposition ? _applyAdposition(phrase, inPast) : phrase; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment