/humanize

Java facility for adding a “human touch” to data.

Primary LanguageJavaApache License 2.0Apache-2.0

Humanize for Java Build Status Coverity Scan Build Status

Humanize is a Java facility for adding a “human touch” to data. It is thread-safe and supports per-thread internationalization.

The main modules are provided in two complementary variants:

humanize-slim

Lightweight distribution that only depends on Guava and standard Java APIs.

humanize-icu

Provides a concise facade for access to the International Components for Unicode (ICU) Java APIs. Includes the slim distribution.

Extensions

  • Unified Emoji — Easy Emoji handling for the JVM
  • Joda time — Joda time message format extensions
  • UCUM — Unified Units of Measurement
  • JSF — Java Server Faces converters
  • Taglib — JSP tag library

Getting Started

Maven Maven Badge

Current version:

<humanize.version>1.2.2</humanize.version>

Slim distribution:

<dependency>
  <groupId>com.github.mfornos</groupId>
  <artifactId>humanize-slim</artifactId>
  <version>${humanize.version}</version>
</dependency>

Full-fledged ICU distribution:

<dependency>
  <groupId>com.github.mfornos</groupId>
  <artifactId>humanize-icu</artifactId>
  <version>${humanize.version}</version>
</dependency>

Usage

Using Humanize is quite simple.

  1. Import the static methods of the Humanize class that you want to call.
  2. Invoke these methods.
import static humanize.Humanize.binaryPrefix;

class SomeClass {

  void doSomething() {

    String size = binaryPrefix(1325899906842624L); // 1.18 PB

  }

}

Principal Methods

Date&Time

Method Description Output Slim ICU
naturalDay For dates that are the current day or within one day, return ‘today’,‘tomorrow’ or ‘yesterday’, as appropriate. ‘today’, ‘tomorrow’, ‘yesterday’ or the date formatted
naturalTime Computes both past and future relative dates with optional precision. ‘2 days from now’, ‘3 decades ago’, ‘3 days 16 hours from now’, ‘3 minutes from now’, ‘3 days 15 hours 38 minutes ago’, ‘moments ago’, etc.
nanoTime Formats a number of nanoseconds as the proper ten power unit. ‘1.5µs’, ‘10.51ms’, ‘30ns’, etc. -
duration Formats a number of seconds as hours, minutes and seconds. ‘1 sec.’, ‘1:02:10’, etc.
smartDateFormat Guesses the best locale-dependent pattern to format the date/time fields that the skeleton specifies. skeleton ‘MMMd’ produces ‘11 Dec.’ -
prettyTimeFormat Returns a PrettyTime instance for the current thread. - -

Frequencies

Method Description Output Slim ICU
times Interprets numbers as occurrences. ‘never’, ‘once’, ‘5 times’, etc. -
paceFormat Matches a pace (value and interval) with a logical time frame. Very useful for slow paces. e.g. heartbeats, ingested calories, hyperglycemic crises. ‘Approximately 7 times per day.’ -

Numbers

Method Description Output Slim ICU
compactDecimal Abbreviates numbers with short and long styles according to CLDR. ‘2,4 Mio’, ‘100K’, ‘1M’, ‘2 millones’, ‘100 Tsd’, ‘100 Millionen’, etc. -
ordinal Converts a number to its ordinal as a string. ‘1st’, ‘2nd’, ‘3rd’, etc.
spellBigNumber Converts a big number to a friendly text representation. ‘2.3 thousand’, ‘1 million’, ‘–1.55 billion’, ‘3 decillion’, ‘2 googol’, etc. -
spellDigit For decimal digits, returns the number spelled out. ‘one’, ‘two’, ‘three’, etc. -
spellNumber Converts the given number to words. ‘twenty-three’, ‘two thousand eight hundred and forty’, ‘one million four hundred and twelve thousand six hundred and five’, etc. -

Units

Method Description Output Slim ICU
binaryPrefix Converts a given number to a string preceded by the corresponding binary International System of Units (SI) prefix. ‘2 bytes’, ‘1.5 KB’, ‘5 MB’, ‘1.18 PB’, etc. -
metricPrefix Converts a given number to a string preceded by the corresponding decimal multiplicative prefix. ‘100k’, ‘1M’, ‘3.5M’, etc. -
formatCurrency Smartly formats the given number as a monetary amount. ‘£34’, ‘£1,000’, ‘£12.50’, etc.
formatPluralCurrency Smartly formats the given number as a monetary amount in plural form. ‘34 British pounds sterling’, ‘1,500.55 British pounds sterling’, ‘1 euro’, etc. -
formatPercent Formats the given ratio as a percentage. ‘500%’, ‘56%’, etc.

Text

Method Description Output Slim ICU
pluralize Applies the proper format for a given plural state. - -
pluralizeFormat Constructs a message with pluralization logic by the means of ChoiceFormat. Refer to messageFormat for pluralization using CLDR Plural Rules. - -
camelize Makes a phrase camel case. Spaces, hyphens, underscores and dots will be removed. - -
capitalize Capitalizes a string, smartly. - -
decamelize Converts a camel case string into a human-readable name. - -
titleize Creates a nice looking title, smartly. - -
transliterate Full transliteration support. - -
simplify Sort of poor man’s transliteration, i.e. normalizes and strips diacritical marks. - -
unidecode Just enough transliteration, unicode to ascii. - -
slugify Transforms a text into a representation suitable to be used in an URL (unicode friendly). - -
mask Formats the given text with the mask specified. for ‘12345G’ with mask ‘__ __/’ produces ‘12 345/G’ -
wordWrap Truncate a string to the closest word boundary after a number of characters. - -
messageFormat Returns an ICU or extended MessageFormat instance for the current thread. -
replaceSupplementary Replaces characters outside the Basic Multilingual Plane with their name. ‘SMILING FACE WITH SMILING EYES’ for the corresponding Emoji char
oxford Converts a list of items to a human readable string with an optional limit. ‘Oranges, Pears, Bananas, and 2 others’ -

Documentation

Code Examples

Small set of code examples.

Date&Time

naturalTime(new Date());
// => "moments ago"

naturalTime(new Date(1000 * 60 * 60 * 24 * 1), new Date(0));
// => "1 day ago"

naturalTime(new Date(0), new Date(1000 * 60 * 12));
// => "12 minutes from now"

naturalTime(new Date(0), new Date(2629743830L * 3L));
// => "3 months from now"
// Fixed date for demonstration
Date moment = new Date(1000 * 60 * 60 * 24 * 3 + 1000 * 60 * 60 * 15 + 1000 * 60 * 38
                       + 1000 * 2);

naturalTime(new Date(0), moment, TimeMillis.HOUR)
// => "3 days 16 hours from now"

naturalTime(moment, new Date(0), TimeMillis.SECOND)
// => "3 days 15 hours 38 minutes ago"

Frequencies

paceFormat(1.75, TimeMillis.HOUR.millis());
// => "Approximately 2 times per hour."

paceFormat(0, TimeMillis.SECOND.millis());
// => "Never."

paceFormat(1, TimeMillis.WEEK.millis());
// => "Approximately one time per week."
times(0); // => "never"
times(1); // => "once"
times(2); // => "twice"
times(3); // => "3 times"

Text

Pluralize

pluralize("one", "{0}", "none", 1);  // => "one"
pluralize("one", "{0}", "none", 2);  // => "2"
pluralize("one", "{0}", "none", 0);  // => "none"
pluralize("one {1}.", "{0} {1}s.", "no {1}.", 1, "disk");  // => "one disk."
pluralize("one {1}.", "{0} {1}s.", "no {1}.", 2, "disk");  // => "2 disks."
pluralize("one {1}.", "{0} {1}s.", "no {1}.", 0, "disk");  // => "no disk."

Parameterized Pluralize

PluralizeParams p = PluralizeParams
                .begin("one {1}.")
                .many("{0} {1}s.")
                .none("no {1}.")
                .exts("disk");

pluralize(1, p); // => "one disk."
pluralize(2, p); // => "2 disks."
pluralize(0, p); // => "no disk."

Pluralize MessageFormat

MessageFormat msg = pluralizeFormat("There {0} on {1}.::are no files::is one file"
                                     + "::are {2} files");

msg.render(0, "disk");    // => "There are no files on disk."
msg.render(1, "disk");    // => "There is one file on disk."
msg.render(1000, "disk"); // => "There are 1,000 files on disk."
MessageFormat msg = pluralizeFormat("nothing::one thing::{0} things");

msg.render(-1); // => "nothing"
msg.render(0);  // => "nothing"
msg.render(1);  // => "one thing"
msg.render(2);  // => "2 things"
MessageFormat msg = pluralizeFormat("one thing::{0} things");

msg.render(-1); // => "-1 things"
msg.render(0);  // => "0 things"
msg.render(1);  // => "one thing"
msg.render(2);  // => "2 things"

Slugify

slugify("Cet été, j’en ai rien à coder");
// => "cet-ete-j-en-ai-rien-a-coder"

slugify("\nキャンパス//.Я_♥@борщ\n^abc");
// => "kiyanpasu-ia-borshch-abc"

Parse

Date & Time

parseISODateTime("2011-09-14T15:22:01Z");

parseISOTime("15:22:01Z");

parseSmartDate("1.2.12", "dd/MM/yy", "yyyy/MM/dd", "dd/MM/yyyy");

More Examples

Dependencies

Humanize-slim

  • guava 18.0
  • prettytime 3.2.5.Final
  • unidecode 0.0.7

Humanize-icu

  • humanize-slim ${humanize.version}
  • icu4j 54.1

Package size concerns

ICU

If you need customize the data included by default in the ICU distribution (all features and languages ~7.1MB), the ICU Data Library Customizer may be useful.

ProGuard

Using ProGuard with Guava.

Supported languages

humanize-slim naturalTime supports over 25 languages, see prettytime. Rest of methods have support for english and spanish.

humanize-icu all languages supported by the ICU APIs.

Custom languages

If you want to add support for other languages simply put a properties file named Humanize\_{your\_locale}.properties under the classpath i18n.

Extensible Message Formats

If you want to plug in your own formats then place a META-INF/services/humanize.spi.FormatProvider file inside your jar. This file must contain a list of the full qualified class names of your FormatProvider implementations, separated by carriage return. Also, you can register manually your format factories on the message formatter.

Built-in Humanize Extended Formats

Create a file META-INF/services/humanize.spi.FormatProvider with the following content:

humanize.text.HumanizeFormatProvider
humanize.text.MaskFormat

Now you can use it

Humanize.format("{0,humanize,ordinal} greetings", 1);
// => "1st greetings"

Cache configuration

By default the caches are configured to expire after 1 hour past the last access. If you want to change this behavior you need to provide a humanize.properties file, or specify the location of a properties file using the humanize.config system property, with a CacheBuilderSpec string configuration like this:

cache.builder.spec:expireAfterAccess=15m

The value must follow the CacheBuilderSpec syntax. The string syntax is a series of comma-separated keys or key-value pairs, each corresponding to a CacheBuilder method.

  • concurrencyLevel=[integer]: sets CacheBuilder.concurrencyLevel.
  • initialCapacity=[integer]: sets CacheBuilder.initialCapacity.
  • maximumSize=[long]: sets CacheBuilder.maximumSize.
  • maximumWeight=[long]: sets CacheBuilder.maximumWeight.
  • expireAfterAccess=[duration]: sets CacheBuilder.expireAfterAccess(long, java.util.concurrent.TimeUnit).
  • expireAfterWrite=[duration]: sets CacheBuilder.expireAfterWrite(long, java.util.concurrent.TimeUnit).
  • refreshAfterWrite=[duration]: sets CacheBuilder.refreshAfterWrite(long, java.util.concurrent.TimeUnit).
  • weakKeys: sets CacheBuilder.weakKeys().
  • softValues: sets CacheBuilder.softValues().
  • weakValues: sets CacheBuilder.weakValues().

Durations are represented by an integer, followed by one of “d”, “h”, “m”, or “s”, representing days, hours, minutes, or seconds respectively. (There is currently no syntax to request expiration in milliseconds, microseconds, or nanoseconds.)

Integrations

Handlebars Helper

Humanize is integrated in the awesome Handlebars.java project.


Have fun and stay fresh!

EOF