humane-ruby
Getting human-readable file sizes with 1000-based math
(as the Mac Finder displays) and relative times worded the way Swift's
RelativeDateTimeFormatter does turned out to be a real challenge to get
both right and simple. The humane library exists so a Ruby application can share
consistent size and time formatting with a Swift application, instead of
reaching for a library whose output doesn't match Swift's or that's
complicated to drop in.
require "humane"
Humane::SizeFormatter.new.string(from_byte_count: 225_935) # "226 KB"
time_formatter = Humane::TimeFormatter.new
time_formatter.string(at: Time.now - 180, relative_to: Time.now) # "3 minutes ago"
Corresponding functions in Swift will have consistent output.
import Foundation
ByteCountFormatter.string(fromByteCount: Int64(225935), countStyle: .file) // "226 KB"
let formatter = RelativeDateTimeFormatter(); formatter.unitsStyle = .full
formatter.localizedString(for: time, relativeTo: now) // "3 minutes ago"
Install
gem install humane
or in a Gemfile:
gem "humane"
Beyond Foundation's defaults
Two options on Humane::TimeFormatter, both off by default so it matches
RelativeDateTimeFormatter exactly out of the box:
include_seconds(defaultfalse): below a minute, collapses to "less than a minute ago"/"in less than a minute" instead of an exact second count. Named after ActionView'sinclude_seconds, which defaults the same way.approximate(defaultfalse): prefixes "about"/"in about" on buckets of an hour or larger, the way ActionView'sdistance_of_time_in_wordsdoes past that same boundary -- for a render that can't refresh itself and shouldn't overstate its own precision.
Humane::TimeFormatter.new(approximate: true).string(at: t - 15 * 3600, relative_to: t)
# => "about 15 hours ago"
Scope
Finder's .file byte-count style, and a numeric (non-calendar-aware)
relative time style -- that's the whole surface area today.
allowed_units/alternate count_styles and a :named style
("yesterday", calendar-boundary-aware) aren't implemented -- contributions
welcome.