Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

356 lines (309 sloc) 13.451 kb
<h1>Convert elapsed timestamps, like, "in 3 minutes!"</h1>
<p>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!"</p>
<p>See also: <a target="_blank" href="http://adamyeager.com/code/prettytime-net/">PrettyTime.NET</a>, <a target="_blank" href="http://grails.org/plugin/pretty-time">PrettyTime Grails Plug-in</a></p>
<p style="margin-bottom: 10px;">
<table class="featured" border="0" width="100%">
<tbody>
<tr>
<td width="50%">
<h3 style="font-size: 140%; margin-bottom: 5px;">Downloads: ↓ (LGPL3)</h3>
<p style="padding-left: 30px;"><strong>1.0.6:</strong> <a href="http://ocpsoft.com/repository/org/ocpsoft/ocpsoft-pretty-time/1.0.6/ocpsoft-pretty-time-1.0.6.jar">jar</a>, <a href="http://ocpsoft.com/repository/org/ocpsoft/ocpsoft-pretty-time/1.0.6/ocpsoft-pretty-time-1.0.6-sources.jar">src</a>, <a target="_blank" href="http://ocpsoft.com/api/ocpsoft-pretty-time/1.0.6/">api</a></p>
<p style="padding-left: 30px;"><a href="http://ocpsoft.com/repository/org/ocpsoft/ocpsoft-pretty-time/">All Downloads / Maven Repo</a></p>
<h4 style="padding-left: 30px; margin-top: 10px; margin-bottom: 5px;">Dependencies:</h4>
<p style="padding-left: 30px;">Java 5.0 and up</p>
<h4 style="margin-top: 10px;"><strong>New features:</strong></h4>
<a href="#i18n">i18n support</a>, thread-safety, Java 1.5 support </td>
<td style="text-align: justify; text-justify: newspaper">Please <a href="http://code.google.com/p/prettytime/issues/entry" target="_blank">open an issue</a> if you have any suggestions, or any difficulties.
<br/>
View the <a href="#docs">documentation</a>.</td>
</tr></tbody></table>
<h4>From <a href="http://twitter.com/ocpsoft">@ocpsoft</a> and <a href="http://twitter.com/lincolnthree">@lincolnthree</a></h4>
<br/>
<h1>Features:</h1>
<ol>
<li>Generate human-readable timestamps like, "right now", "2 days ago", or "3 months from now"</li>
<li>Simple single interface - easy to learn.</li>
<li>Entirely customizable. Provide your own TimeUnit and TimeFormat objects for complete control.</li>
<li>Provided integration for the JSF web-application framework (if you would like to include another, <a href="http://ocpsoft.com/services/contact/">contact us</a>)</li>
</ol>
<a name="docs"></a>
<h2>Documentation:</h2>
Using PrettyTime is simple.
<!--more-->
<ol>
<li><a href="#basic">Basic use in a Java App</a><br /></li>
<li><a href="#i18n">i18n support (contributed by Thomas Weitzel)</a><br /></li>
<li><a href="#customunit">Creating a custom TimeUnit</a><br /></li>
<li><a href="#jsf">Using PrettyTimeConverter in JSF</a><br/></li>
<li><a href="#examples">Examples using JUnit</a></li>
</ol>
<h3 style="margin-bottom: 15px;"><a href="#configuration"><strong>0. Extract necessary JAR files into your /WEB-INF/lib directory</strong></a></h3>
This step is pretty straight-forward, right?
<h4>or include a maven dependency in your pom.xml (optional)</h4>
<pre lang="xml">
<dependency>
<groupId>org.ocpsoft</groupId>
<artifactId>ocpsoft-pretty-time</artifactId>
<version>1.0.6</version>
</dependency>
</pre>
<h3><a name="basic"></a><a href="#docs"><strong>Basic use in a Java App:</strong></a></h3>
<p>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.</p>
<pre lang="java">import java.util.Date;
import org.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”
}
}</pre>
<h4>See below for more <a href="#examples">examples</a> using JUnit.</h4>
<p/><br/>
<h3><a name="i18n"></a><a href="#docs"><strong>i18n support (contributed by Thomas Weitzel):</strong></a></h3>
<p>PrettyTime now supports internationalization via resource bundles. Simply place an appropriate Resources_**.properties bundle on the classpath: <b>org.ocpsoft.pretty.time.i18n</b>, then set the desired Locale into your PrettyTime object.</p>
<h4>Locales with built-in support:</h4>
<ul>
<li>English - DEFAULT</li>
<li>Dutch - NL: <span class="faded">Bram Van Dam</span></li>
<li>French - FR: <span class="faded">Eric Palpacuer</span></li>
<li>German - DE: <span class="faded">Thomas Weitzel</span></li>
<li>Chinese - ZH_CN: <span class="faded"">陈正华</span></li>
<li>Portugese - PT: <span class="faded">Gustavo Ehrhardt</span></li>
<li>Spanish - ES: <span class="faded">Bruno Resano</span></li>
<li>Slovakian - SL: <span class="faded">Uros Majeric</span></li>
<li>Bulgarian - BG: <span class="faded">Марио Георгиев</span></li>
<li>Italian - IT: <span class="faded">Mirco Attocchi</span></li>
</ul>
<p>If you create a new Locale resource bundle for PrettyTime, please <a href="mailto:admin@ocpsoft.com">submit it back to the project here!</a> </p>
<pre lang="java">import java.util.Date;
import java.util.Locale;
import org.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()));
}
}</pre>
<h4>Resource bundle example: (find full examples packaged inside pretty-time.jar)</h4>
<pre lang="java">package org.ocpsoft.pretty.time.i18n;
import java.util.ListResourceBundle;
public class Resources_de extends ListResourceBundle
{
private static final Object[][] CONTENTS = new Object[][] {
{ "CenturyPattern", "%n %u" },
{ "CenturyFuturePrefix", "In " },
{ "CenturyFutureSuffix", "" },
{ "CenturyPastPrefix", "Vor " },
{ "CenturyPastSuffix", "" },
{ "CenturyName", "Jahrhundert" },
{ "CenturyPluralName", "Jahrhunderten" }
//...
};
}
@Override
protected Object[][] getContents()
{
return CONTENTS;
}
}
</pre>
<p/><br/>
<h3><a name="customunit"></a><a href="#docs"><strong>Creating a custom TimeUnit:</strong></a></h3>
<p>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</p>
<pre lang="java">package org.ocpsoft.pretty.time.units;
import org.ocpsoft.pretty.time.BasicTimeFormat;
import org.ocpsoft.pretty.time.TimeFormat;
import org.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 */
}
</pre>
<p>TimeFormat is also simple -- and is the core of the Formatting platform.</p>
<pre lang="java">package org.ocpsoft.pretty.time;
public interface TimeFormat
{
/**
* Given a populated Duration object. Apply formatting and output the
* result.
*/
public abstract String format(final Duration duration);
}
</pre>
<p>See BasicTimeFormat for an implementation example using regular expressions</p>
<br/>
<h3><a name="jsf"></a><a href="#docs"><strong>Using PrettyTimeConverter in JSF:</strong></a></h3>
<p>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.</p>
<pre lang="xml">
<h:outputText value="#{exampleBean.futureDate}">
<f:converter converterId="org.ocpsoft.PrettyTimeConverter"/>
</h:outputText>
</pre>
<p>In this example, futureDate must be a valid java.util.Date object.</p>
<br/>
<h3><a name="examples"></a><a href="#docs"><strong>Examples using JUnit:</strong></a></h3>
<p>See below for creating custom time units and formats:</p>
<pre lang="java">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)));
}
}
</pre>
<br/>
Jump to Line
Something went wrong with that request. Please try again.