PrettyTime
Convert elapsed timestamps, like, “in 3 minutes!”
PrettyTime is an OpenSource time formatting library. Completely customizable, PrettyTime creates human readable, relative timestamps like those seen on Digg, Twitter, and Facebook. It’s simple, get started “right now!”
See also: PrettyTime.NET, PrettyTime Grails Plug-in
Downloads: ↓ (LGPL3)Dependencies:Java 6.0 and up (use 1.0.3 for 5.0 support) New features:i18n support (contributed by Thomas Weitzel, thank you!) | Please open an issue if you have any suggestions, or any difficulties. View the documentation. |
From @ocpsoft and @lincolnthree
Features:
- Generate human-readable timestamps like, “right now”, “2 days ago”, or “3 months from now”
- Simple single interface – easy to learn.
- Entirely customizable. Provide your own TimeUnit and TimeFormat objects for complete control.
- Provided integration for the JSF web-application framework (if you would like to include another, contact us)
Documentation:
Using PrettyTime is simple.
- Basic use in a Java App
- i18n support (contributed by Thomas Weitzel)
- Creating a custom TimeUnit
- Using PrettyTimeConverter in JSF
- Examples using JUnit
0. Extract necessary JAR files into your /WEB-INF/lib directory
This step is pretty straight-forward, right?
or include a maven dependency in your pom.xml (optional)
<dependency> <groupId>com.ocpsoft</groupId> <artifactId>ocpsoft-pretty-time</artifactId> <version>1.0.5</version> </dependency>
Basic use in a Java App:
PrettyTime, by default, uses the current time as the point of reference (reference time) for calculating the elapsed, or remaining time to the Date argument.
import java.util.Date; import com.ocpsoft.pretty.time.PrettyTime; public class BasicJavaApp { public static void main(String[] args) { PrettyTime p = new PrettyTime(); System.out.println(p.format(new Date())); //prints: “right now” } }
See below for more examples using JUnit.
i18n support (contributed by Thomas Weitzel):
PrettyTime now supports internationalization via resource bundles. Simply place an appropriate resources_**.xml bundle on the classpath: com.ocpsoft.pretty.time, then set the desired locale into your PrettyTime object.
Locales with built-in support:
- Dutch – NL: Bram Van Dam
- English – DEFAULT
- French – FR: Eric Palpacuer
- German – DE: Thomas Weitzel
- Chinese – ZH_CN: 陈正华
- Portugese – PT: Gustavo Ehrhardt
- Spanish – ES: Bruno Resano
If you create a new Locale resource bundle for PrettyTime, please submit it back to the project here!
import java.util.Date; import java.util.Locale; import com.ocpsoft.pretty.time.PrettyTime; public class Basic_i18n { public static void main(final String[] args) { PrettyTime p = new PrettyTime(new Locale("de")); System.out.println(p.format(new Date())); } }
Resource bundle example: (find full examples packaged inside pretty-time.jar)
<properties> <!-- Century --> <entry key="CenturyPattern">%n %u</entry> <entry key="CenturyFuturePrefix">In </entry> <entry key="CenturyFutureSuffix"></entry> <entry key="CenturyPastPrefix">Vor </entry> <entry key="CenturyPastSuffix"></entry> <entry key="CenturyName">Jahrhundert</entry> <entry key="CenturyPluralName">Jahrhunderten</entry> <!-- Day --> <entry key="DayPattern">%n %u</entry> <entry key="DayFuturePrefix">In </entry> <entry key="DayFutureSuffix"></entry> <!-- And so on... --> </properties>
Creating a custom TimeUnit:
TimeUnits are the units of measure in PrettyTime. They can be as long or as short as desired, and can be formatted into any necessary pattern. All that needs to be done is to implement the TimeUnit interface, and provide a default TimeFormat
package com.ocpsoft.pretty.time.units; import com.ocpsoft.pretty.time.BasicTimeFormat; import com.ocpsoft.pretty.time.TimeFormat; import com.ocpsoft.pretty.time.TimeUnit; public class Month implements TimeUnit { private static final TimeFormat defaultFormat = new BasicTimeFormat().setPattern("%n %u").setPastSuffix(" ago") .setFutureSuffix(" from now"); private TimeFormat format = defaultFormat; private long maxQuantity = 0; private final long millisPerUnit = 2629743830L; private String name = "month"; private String pluralName = "months"; /* getters and setters */ }
TimeFormat is also simple — and is the core of the Formatting platform.
package com.ocpsoft.pretty.time; public interface TimeFormat { /** * Given a populated Duration object. Apply formatting and output the * result. */ public abstract String format(final Duration duration); }
See BasicTimeFormat for an implementation example using regular expressions
Using PrettyTimeConverter in JSF:
PrettyTime includes a JSF Converter for easy output formatting. No additional configuration is required to use this object, since PrettyTime includes its own META-INF/faces-config.xml — Just include the PrettyTime jar file on your classpath.
<h:outputText value="#{exampleBean.futureDate}"> <f:converter converterId="com.ocpsoft.PrettyTimeConverter"/> </h:outputText>
In this example, futureDate must be a valid java.util.Date object.
Examples using JUnit:
See below for creating custom time units and formats:
import static org.junit.Assert.assertEquals; import java.util.Date; import org.junit.Test; public class PrettyTimeTest { @Test public void testRightNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("right now", t.format(new Date(6000))); } @Test public void testMinutesFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("12 minutes from now", t.format(new Date(1000 * 60 * 12))); } @Test public void testCustomFormat() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); t.setUnits(new TimeUnit() { public TimeFormat getFormat() { return new BasicTimeFormat().setPattern("%n %u").setRoundingTolerance(20).setFutureSuffix("... RUN!") .setFuturePrefix("self destruct in: ").setPastPrefix("self destruct was: ").setPastSuffix( " ago..."); } public long getMaxQuantity() { return 0; } public long getMillisPerUnit() { return 5000; } public String getName() { return "tick"; } public String getPluralName() { return "ticks"; } }); assertEquals("self destruct in: 5 ticks... RUN!", t.format(new Date(25000))); t.setReference(new Date(25000)); assertEquals("self destruct was: 5 ticks ago...", t.format(new Date(0))); } @Test public void testHoursFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("3 hours from now", t.format(new Date(1000 * 60 * 60 * 3))); } @Test public void testDaysFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("3 days from now", t.format(new Date(1000 * 60 * 60 * 24 * 3))); } @Test public void testWeeksFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("3 weeks from now", t.format(new Date(1000 * 60 * 60 * 24 * 7 * 3))); } @Test public void testMonthsFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("3 months from now", t.format(new Date(2629743830L * 3L))); } @Test public void testYearsFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("3 years from now", t.format(new Date(2629743830L * 12L * 3L))); } @Test public void testDecadesFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("30 years from now", t.format(new Date(315569259747L * 3L))); } @Test public void testCenturiesFromNow() throws Exception { PrettyTime t = new PrettyTime(new Date(0)); assertEquals("300 years from now", t.format(new Date(3155692597470L * 3L))); } /* * Past */ @Test public void testMomentsAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(6000)); assertEquals("moments ago", t.format(new Date(0))); } @Test public void testMinutesAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(1000 * 60 * 12)); assertEquals("12 minutes ago", t.format(new Date(0))); } @Test public void testHoursAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(1000 * 60 * 60 * 3)); assertEquals("3 hours ago", t.format(new Date(0))); } @Test public void testDaysAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(1000 * 60 * 60 * 24 * 3)); assertEquals("3 days ago", t.format(new Date(0))); } @Test public void testWeeksAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(1000 * 60 * 60 * 24 * 7 * 3)); assertEquals("3 weeks ago", t.format(new Date(0))); } @Test public void testMonthsAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(2629743830L * 3L)); assertEquals("3 months ago", t.format(new Date(0))); } @Test public void testYearsAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(2629743830L * 12L * 3L)); assertEquals("3 years ago", t.format(new Date(0))); } @Test public void testDecadesAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(315569259747L * 3L)); assertEquals("30 years ago", t.format(new Date(0))); } @Test public void testCenturiesAgo() throws Exception { PrettyTime t = new PrettyTime(new Date(3155692597470L * 3L)); assertEquals("300 years ago", t.format(new Date(0))); } }
