Rails 3 - time_ago_in_words says "ABOUT 2 hours ago" - ruby-on-rails

Code:
<%="#{time_ago_in_words(comment.created_at)} ago "%>
What i'd like is for it not to have "ABOUT" in front of the 2 hours ago, which shows up for hours but not for minutes...
Is there another function or a way to remove it without finding and replacing?

You can change this via your I18n locale file. In config/locales/en.yml...
"en":
datetime:
distance_in_words:
about_x_hours:
# The defaults are "about 1 hour" and "about %{count} hours"
one: "1 hour"
other: "%{count} hours"
See the default locale file in actionpack for a complete reference.

I had the same issue, I ended up doing this, mostly because I'm still up in the air about whether or not to remove the about globally -
<p class="entry_created_at"><%= time_ago_in_words(plate.created_at).gsub('about','') + ' ago' %></p>

You can use my dotiw gem/plugin for that. It adds a couple of additional options and has greater precision than the one Rails offers.
distance_of_time_in_words(time1, time2, :only => [:days, :hours, :minutes])

Related

Rails: Is there a built translation for "ago"?

Rails translate time ago with time_ago_in_words and documentation is this.
time_ago_in_words(3.minutes.from_now) # => 3 minutes
However, in our app, we use "ago": 3 minutes ago
So, what is the best way to translate when "ago" appears before the time_ago, such as in French:
Il y a 3 minutes
Is this built into Rails?
Using Rails 4.2.10 and rails-i18n gem which provides the distance in time, but not the "ago".
You could use custom scopes:
https://github.com/rails/rails/blob/fc5dd0b85189811062c85520fd70de8389b55aeb/actionview/lib/action_view/helpers/date_helper.rb#L75
time_ago_in_words(3.minutes.ago, scope: 'datetime.distance_in_words_ago') # => 3 minutes ago
and you need to add this to your locale (en.yml)
en:
datetime:
distance_in_words_ago:
x_days:
one: 1 day ago
other: "%{count} days ago"
x_minutes:
one: 1 minute ago
other: "%{count} minutes ago"
x_months:
one: 1 month ago
other: "%{count} months ago"
x_years:
one: 1 year ago
other: "%{count} years ago"
x_seconds:
one: 1 second ago
other: "%{count} seconds ago"
https://github.com/rails/rails/blob/fc5dd0b85189811062c85520fd70de8389b55aeb/actionview/lib/action_view/helpers/date_helper.rb#L78
I think you just need to pass the time as a variable to the translation.
Then in the language ymls, you can have the rest of the string where it needs to be.
Suppose that #product.purchased_time_ago returns the time_ago_in_words().
# app/views/products/show.html.erb
<%= t('time_ago', time: #product.purchased_time_ago) %>
# config/locales/en.yml
en:
time_ago: "%{time} ago"
# config/locales/fr.yml
fr:
time_ago: "Il y a %{time}"
This is direct taken from the docs.

Locale change to time_ago_in_words not changing

I am trying to change the default time_ago_in_words function to use 1min instead for 1minute for example.
I came across the following but it doesn't seem to change anything. Inside en.yml
en:
datetime:
distance_in_words:
x_minutes:
one: "1 min"
other: "%{count} min"
any clues?

Ruby/Rails time helper method

I am looking for a helper class/method/gem that's out there that will help me format a time helper. The output I'm looking after passing in an instance of Time.now is something like the following:
"1 minute ago"
"2 minutes ago"
"1 hour ago"
"2 hours ago"
"1 day ago"
"2 days ago"
"over a year ago"
I started writing something like this but it's going to be long and painful and I feel like something like this has to exist. The only catch is I need it to use my own wording, so something with a formatter is required..
def time_ago_to_str(timestamp)
minutes = (((Time.now.to_i - timestamp).abs)/60).round
return nil if minutes < 0
Rails.logger.debug("minutes #{minutes}")
return "#{minutes} minute ago" if minutes == 1
return "#{minutes} minutes ago" if minutes < 60
# crap load more return statements to follow?
end
Such a helper already exists and is built-in to Rails:
http://apidock.com/rails/ActionView/Helpers/DateHelper/time_ago_in_words
time_ago_in_words(5.days.ago)
=> "5 days"
EDIT:
If you'd like to customize the wording you can create a custom I18n locale, for example, I created one called time_ago in config/locales/time_ago.yml:
time_ago:
datetime:
distance_in_words:
half_a_minute: "half a minute"
less_than_x_seconds:
one: "less than 1 second"
other: "less than %{count} seconds"
x_seconds:
one: "1 second"
other: "%{count} seconds"
less_than_x_minutes:
one: "less than a minute"
other: "less than %{count} minutes"
x_minutes:
one: "1 min"
other: "%{count} mins"
about_x_hours:
one: "about 1 hour"
other: "about %{count} hours"
x_days:
one: "1 day"
other: "%{count} days"
about_x_months:
one: "about 1 month"
other: "about %{count} months"
x_months:
one: "1 month"
other: "%{count} months"
about_x_years:
one: "about 1 year"
other: "about %{count} years"
over_x_years:
one: "over 1 year"
other: "over %{count} years"
almost_x_years:
one: "almost 1 year"
other: "almost %{count} years"
Now, you can use the locale with distance_of_time_in_words:
# distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})
distance_of_time_in_words(5.minutes.ago, Time.now, true, {:locale => "time_ago"})
=> "5 mins"
You could of course add this to config/locales/en.yml and completely override them application wide, which would you allow you to call time_ago_in_words as mentioned above!

Ruby (with Rails) convert a string of time into seconds?

So, I've got a string of time... something along the lines of
'4 hours'
'48 hours'
'3 days'
'15 minutes'
I would like to convert those all into seconds. For '4 hours', this works fine
Time.parse('4 hours').to_i - Time.parse('0 hours').to_i
=> 14400 # 4 hours in seconds, yay
However, this doesn't work for 48 hours (outside of range error). It also does not work for 3 days (no information error), etc.
Is there a simple way to convert these strings into seconds?
What you're asking Ruby to do with Time.parse is determine a time of day. That's not what you are wanting. All of the libraries I can think of are similar in this aspect: they are interested in absolute times, not lengths of time.
To convert your strings into time formats that we can work with, I recommend using Chronic (gem install chronic). To convert to seconds, we can do everything relative to the current time, then subtract that time to get the absolute number of seconds, as desired.
def seconds_in(time)
now = Time.now
Chronic.parse("#{time} from now", :now => now) - now
end
seconds_in '48 hours' # => 172,800.0
seconds_in '15 minutes' # => 900.0
seconds_in 'a lifetime' # NoMethodError, not 42 ;)
A couple quick notes:
The from now is is why Chronic is needed — it handles natural language input.
We're specifying now to be safe from a case where Time.now changes from the time that Chronic does it's magic and the time we subtract it from the result. It might not occur ever, but better safe than sorry here I think.
'48 hours'.match(/^(\d+) (minutes|hours|days)$/) ? $1.to_i.send($2) : 'Unknown'
=> 172800 seconds
4.hours => 14400 seconds
4.hours.to_i 14400
4.hours - 0.hours => 14400 seconds
def string_to_seconds string
string.split(' ')[0].to_i.send(string.split(' ')[1]).to_i
end
This helper method will only work if the time is in the format of number[space]hour(s)/minute(s)/second(s)
Chronic will work, but Chronic Duration is a better fit.
It can parse a string and give you seconds.
require "chronic_duration"
ChronicDuration::parse('15 minutes')
# or
ChronicDuration::parse('4 hours')
http://everydayrails.com/2010/08/11/ruby-date-time-parsing-chronic.html
I'm sure you would get some good work out of chronic gem.
Also, here is some good to know info about dates/times in ruby
>> strings = ['4 hours', '48 hours', '3 days', '15 minutes', '2 months', '5 years', '2 decades']
=> ["4 hours", "48 hours", "3 days", "15 minutes", "2 months", "5 years", "2 decades"]
>> ints = strings.collect{|s| eval "#{s.gsub(/\s+/,".")}.to_i" rescue "Error"}
=> [14400, 172800, 259200, 900, 5184000, 157788000, "Error"]

Rails time_ago_in_words producing bad output

I thought this might be due to moving to activesupport 2.3.5 but now I believe something else must have happened.
Model has a valid rfc822 style date:
>> s.lastVisitDate
=> "Thu, 06 Jan 2011 22:24:10 -0800"
But in my view:
<%=h time_ago_in_words(#site.lastVisitDate) -%>
renders: *about {{count}} hours ago*
instead of: *about 2 hours ago* which was working just fine earlier.
Wondering if anyone else has seen this behavior. I've reviewed my version history for the model and view and nothing has changed recently so I believe I must have messed up something on the config side of things.
I found that I was missing the appropriate values in a locale file.
So in my case I added the following to /config/locales/en.yml
I am not sure why this was previously working or what specific gem or config change triggered this issue but having the proper definition here make actionpack happy.
# Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words()
datetime:
distance_in_words:
half_a_minute: "half a minute"
less_than_x_seconds:
one: "less than 1 second"
other: "less than %{count} seconds"
x_seconds:
one: "1 second"
other: "%{count} seconds"
less_than_x_minutes:
one: "less than a minute"
other: "less than %{count} minutes"
x_minutes:
one: "1 minute"
other: "%{count} minutes"
about_x_hours:
one: "about 1 hour"
other: "about %{count} hours"
x_days:
one: "1 day"
other: "%{count} days"
about_x_months:
one: "about 1 month"
other: "about %{count} months"
x_months:
one: "1 month"
other: "%{count} months"
about_x_years:
one: "about 1 year"
other: "about %{count} years"
over_x_years:
one: "over 1 year"
other: "over %{count} years"
almost_x_years:
one: "almost 1 year"
other: "almost %{count} years"
prompts:
year: "Year"
month: "Month"
day: "Day"
hour: "Hour"
minute: "Minute"
second: "Seconds"

Resources