time_in_words
All code stolen from lucky framework time_helpers, but added the Chinese support.
Only EN and ZH_CN supported for now, PR is welcome.
The locale name will follow name in this file.
Documentation
Installation
-
Add the dependency to your
shard.yml:dependencies: time_in_words: github: crystal_china/time_in_words -
Run
shards install
Breaking Changes
The from method's past_time: keyword argument has been renamed to time:
because it supports both past and future times. Update existing calls:
# Before
TimeHelper.from(past_time: posted_at)
# After
TimeHelper.from(time: posted_at)
Usage
require "time_in_words"
alias TimeHelper = TimeInWords::Helpers(TimeInWords::I18n::ZH_CN)
TimeHelper.from(time: Time.local - 13.months) # => "大约一年前"
from_time = Time.local
TimeHelper.distance(from: from_time, to: from_time + 50.minutes) # => "大约一个小时"
TimeHelper.distance(from: from_time, to: from_time + 35.minutes) # => "35 分钟"
span = 4.minutes
TimeHelper.distance(span: span) # => "四分钟"
TimeHelper.distance(span: Time::Span.zero) # => "零秒"
TimeHelper.from(time: Time.utc) # => "刚刚"
Check the time_in_words_en_spec.cr for usage about English time words.
In both languages, distance returns only the duration, regardless of the order
of its dates or the sign of its span. from adds ago / 前 for past times and
in / 后 for future times; the Chinese result for the current moment is 刚刚.
Both methods describe elapsed duration rather than calendar date differences. Day-level descriptions use Rails-style minute rounding: 60 hours becomes 3 days, regardless of the input time zones. Month descriptions use complete elapsed days and start at 30 days. English uses "about 2 months" from 45 days up to, but not including, 60 days. Chinese keeps "大约一个半月" from 38 days up to, but not including, 52 days. Second and year descriptions keep their existing rules.
now = Time.utc(2026, 10, 20, 14)
posted_at = now - 60.hours
TimeHelper.from(time: posted_at, now: now) # => "三天前"
now is optional and defaults to the current time. Pass it when you need a fixed
reference time, such as in tests or when rendering several timestamps together.
Year descriptions follow Rails' approximate / over / almost thresholds. Date
pairs account for leap days; a bare Time::Span uses fixed 365-day years because
it has no calendar dates.
alias EnglishTimeHelper = TimeInWords::Helpers(TimeInWords::I18n::EN)
EnglishTimeHelper.from(time: Time.utc - 2.hours) # => "about 2 hours ago"
EnglishTimeHelper.distance(span: 2.hours) # => "about 2 hours"
Development
TODO Write development instructions here
Contributing
- Fork it (https://github.com/zw963/time_in_words/fork)
- Run
maketo ensure spec passed. - Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Run
makeagain to ensure spec passed. - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Billy.Zheng - creator and maintainer