Utils: Add support for short "x ago" forms (#3825)

This commit is contained in:
Samantaz Fox 2023-05-31 22:28:47 +02:00
commit 21f0b90354
No known key found for this signature in database
GPG Key ID: F42821059186176E
2 changed files with 60 additions and 11 deletions

View File

@ -0,0 +1,46 @@
require "../spec_helper"
Spectator.describe "Utils" do
describe "decode_date" do
it "parses short dates (en-US)" do
expect(decode_date("1s ago")).to be_close(Time.utc - 1.second, 500.milliseconds)
expect(decode_date("2min ago")).to be_close(Time.utc - 2.minutes, 500.milliseconds)
expect(decode_date("3h ago")).to be_close(Time.utc - 3.hours, 500.milliseconds)
expect(decode_date("4d ago")).to be_close(Time.utc - 4.days, 500.milliseconds)
expect(decode_date("5w ago")).to be_close(Time.utc - 5.weeks, 500.milliseconds)
expect(decode_date("6mo ago")).to be_close(Time.utc - 6.months, 500.milliseconds)
expect(decode_date("7y ago")).to be_close(Time.utc - 7.years, 500.milliseconds)
end
it "parses short dates (en-GB)" do
expect(decode_date("55s ago")).to be_close(Time.utc - 55.seconds, 500.milliseconds)
expect(decode_date("44min ago")).to be_close(Time.utc - 44.minutes, 500.milliseconds)
expect(decode_date("22hr ago")).to be_close(Time.utc - 22.hours, 500.milliseconds)
expect(decode_date("1day ago")).to be_close(Time.utc - 1.day, 500.milliseconds)
expect(decode_date("2days ago")).to be_close(Time.utc - 2.days, 500.milliseconds)
expect(decode_date("3wk ago")).to be_close(Time.utc - 3.weeks, 500.milliseconds)
expect(decode_date("11mo ago")).to be_close(Time.utc - 11.months, 500.milliseconds)
expect(decode_date("11yr ago")).to be_close(Time.utc - 11.years, 500.milliseconds)
end
it "parses long forms (singular)" do
expect(decode_date("1 second ago")).to be_close(Time.utc - 1.second, 500.milliseconds)
expect(decode_date("1 minute ago")).to be_close(Time.utc - 1.minute, 500.milliseconds)
expect(decode_date("1 hour ago")).to be_close(Time.utc - 1.hour, 500.milliseconds)
expect(decode_date("1 day ago")).to be_close(Time.utc - 1.day, 500.milliseconds)
expect(decode_date("1 week ago")).to be_close(Time.utc - 1.week, 500.milliseconds)
expect(decode_date("1 month ago")).to be_close(Time.utc - 1.month, 500.milliseconds)
expect(decode_date("1 year ago")).to be_close(Time.utc - 1.year, 500.milliseconds)
end
it "parses long forms (plural)" do
expect(decode_date("5 seconds ago")).to be_close(Time.utc - 5.seconds, 500.milliseconds)
expect(decode_date("17 minutes ago")).to be_close(Time.utc - 17.minutes, 500.milliseconds)
expect(decode_date("23 hours ago")).to be_close(Time.utc - 23.hours, 500.milliseconds)
expect(decode_date("3 days ago")).to be_close(Time.utc - 3.days, 500.milliseconds)
expect(decode_date("2 weeks ago")).to be_close(Time.utc - 2.weeks, 500.milliseconds)
expect(decode_date("9 months ago")).to be_close(Time.utc - 9.months, 500.milliseconds)
expect(decode_date("8 years ago")).to be_close(Time.utc - 8.years, 500.milliseconds)
end
end
end

View File

@ -111,24 +111,27 @@ def decode_date(string : String)
else nil # Continue else nil # Continue
end end
# String matches format "20 hours ago", "4 months ago"... # String matches format "20 hours ago", "4 months ago", "20s ago", "15min ago"...
date = string.split(" ")[-3, 3] match = string.match(/(?<count>\d+) ?(?<span>[smhdwy]\w*) ago/)
delta = date[0].to_i
case date[1] raise "Could not parse #{string}" if match.nil?
when .includes? "second"
delta = match["count"].to_i
case match["span"]
when .starts_with? "s" # second(s)
delta = delta.seconds delta = delta.seconds
when .includes? "minute" when .starts_with? "mi" # minute(s)
delta = delta.minutes delta = delta.minutes
when .includes? "hour" when .starts_with? "h" # hour(s)
delta = delta.hours delta = delta.hours
when .includes? "day" when .starts_with? "d" # day(s)
delta = delta.days delta = delta.days
when .includes? "week" when .starts_with? "w" # week(s)
delta = delta.weeks delta = delta.weeks
when .includes? "month" when .starts_with? "mo" # month(s)
delta = delta.months delta = delta.months
when .includes? "year" when .starts_with? "y" # year(s)
delta = delta.years delta = delta.years
else else
raise "Could not parse #{string}" raise "Could not parse #{string}"