Many online social products, and more continue to, avoid a formal timestamp format…
2009-10-10 23:14:17 and Thu, October 29, 2004 12:14:19 PM
… opting for more user friendly, “warm and fuzzy,” human-readable styles…
9 days ago and 5 years ago.
As a result, and also in my quest to always help provide my clients free, cheap and easy to use tools, I have been on the lookout for a jQuery plugin that would provide the ability to easily…![]()
- convert timestamps to ‘cuter’ language-styled forms (e.g. yesterday, 2 hours ago, last year, in the future!),
- customize the time scales and output formatting, and
- update automatically and/or manually the displayed CuteTime(s).
While there are other similar tools out there in JavaScript, PHP, and, I am sure, many other languages, none adequately met my goals. Therefore, I created the jQuery CuteTime plugin.
Usage
CuteTime is a customizable jQuery plugin (jQuery.cuteTime) that automatically converts timestamps to formats much cuter. It also has the ability to manually and/or automatically update timestamps on a controlled interval.
- If used via Selector, CuteTime replaces the text of the provided object with a cuteTime.
- If used as a function, CuteTime returns a string containing a cuteTime version of the provided timestamp.
// METHOD
$('.timestamp').cuteTime();
$('.timestamp').cuteTime({ /* OPTIONS * / });
cutetime_object = $('.timestamp').cuteTime();
cutetime_object.update_cuteness();
// FUNCTION
$.cuteTime('2009/10/12 22:11:19');
$.cuteTime({ /* OPTIONS * / }, '2009-11-24T19:20:30+01:00');
As a Function
If used as a function, CuteTime returns a string containing a cuteTime version of the provided timestamp.
$(document).ready(function () {
// timestamp MUST be a valid Date().parse 'able' format
$('.predetermined').text(
$.cuteTime('2009/10/12 22:11:19')
);
$('.predetermined2').text(
$.cuteTime(settings, '2009-11-24T13:15:30Z')
);
});
<html> <body> <div class='predetermined'></div> <div class='predetermined2'></div> </body> </html>
As a Method
If used via Selector, CuteTime replaces the text of the provided object with a cuteTime.
$(document).ready(function () {
$('.timestamp').cuteTime();
});
<html> <body> <div class="timestamp"> 2009/10/12 22:11:19 </div> <div class="timestamp"> 2008/11/01 07:11:00 </div> <div class="timestamp"> 2018/11/01 07:11:00 </div> <div class="timestamp"></div> <div class="timestamp" cutetime="1980/10/12 22:11:19"> 2009/10/12 22:11:19 </div> <div class="timestamp" cutetime="asd"> 10/12/2009 22:11:19 </div> <div class="timestamp" cutetime="asd"> aoisd </div> <div class="timestamp" cutetime="asd"></div> </body> </html>
When initialized, the cuteTime() call either updates or assigns the 'cutetime' attribute to the provided objects. Method implementation supports chaining, returning the jQuery object.
e.g. <div class='timestamp' cutetime='2009 10 12 22:11:19'>2009 10 12 22:11:19</div>
If the cutetime attribute already exists within the provided object, then the text within the object is ignored in the cutification process. If the cutetime attribute does not exist or an invalid one is provided, then a valid cutetime attribute is assigned to the object.
If the cutetime attribute is missing, then it is calculated from the text of the provided object.
If neither cutetime attribute nor valid object text exist, then the timestamp is assumed to be 'now'.
When using CuteTime in the form...
<br />
$(document).ready(function () {
remember_the_cuteness = $('.timestamp').cuteTime();
});
... the following methods can be used ...
// stops all automatic updates of refresh-enabled timestamps remember_the_cuteness.stop_cuteness(); // (re)starts the automatic updating of timestamps // REMINDER: make sure refresh is set to > 0 remember_the_cuteness.start_cuteness(); // updates timestamps of the provided objects remember_the_cuteness.update_cuteness();
Settings
By default, automatic updating is disabled and the following CuteTimes can be displayed...
the future!
just now
a few seconds ago
a minute ago
x minutes ago
an hour ago
x hours ago
yesterday
x days ago
last month
x months ago
last year
x years ago
To change these settings, they can either be accessed directly...
$.fn.cuteTime.settings.refresh = 10000;
... or at the time of initialization ...
my_cutetime = $('.timestamp_move').cuteTime({ refresh: 60000*10 });
The default settings data structure is...
$.fn.cuteTime.settings = {
refresh: -1, // time in milliseconds before next refresh of page data; -1 == no refresh
time_ranges: [
{bound: Number.NEGATIVE_INFINITY, // IMPORANT: bounds MUST be in ascending order, from negative infinity to positive infinity
cuteness: 'the future!', unit_size: 0},
{bound: 0,
cuteness: 'just now', unit_size: 0},
{bound: 20 * 1000,
cuteness: 'a few seconds ago', unit_size: 0},
{bound: 60 * 1000,
cuteness: 'a minute ago', unit_size: 0},
{bound: 60 * 1000 * 2,
cuteness: ' minutes ago', unit_size: 60 * 1000},
{bound: 60 * 1000 * 60,
cuteness: 'an hour ago', unit_size: 0},
{bound: 60 * 1000 * 60 * 2,
cuteness: ' hours ago', unit_size: 60 * 1000 * 60},
{bound: 60 * 1000 * 60 * 24,
cuteness: 'yesterday', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 2,
cuteness: ' days ago', unit_size: 60 * 1000 * 60 * 24},
{bound: 60 * 1000 * 60 * 24 * 30,
cuteness: 'last month', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 2,
cuteness: ' months ago', unit_size: 60 * 1000 * 60 * 24 * 30},
{bound: 60 * 1000 * 60 * 24 * 30 * 12,
cuteness: 'last year', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
cuteness: ' years ago', unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
{bound: Number.POSITIVE_INFINITY,
cuteness: 'a blinkle ago', unit_size: 0}
]
};
All modifications to the settings are non-constructive. This means that you need to specify all the non-default settings you wish to have applied on each cuteTime.update_cuteness() or cuteTime() call.
The parameters are defined (and all can be overridden) thus...
- refresh
- time in milliseconds before next refresh of page data;
- a value of -1 disables refreshing
- time_ranges
- the array of bound_structures that delineate the cute descriptions associated with time_ranges
- time_range's boundary structures consist of the following variables...
- time_range[x].bound
- the value is an integer representing the time difference between the provided timestamp and now
- the lower inclusive bound, or starting point, for using the 'cuteness' string that describes the current timestamp
- the exclusive upper bound is defined by the next boundary structure definition in the time_ranges array [current boundary + 1]
- time_range[x].cuteness
- string to use in place of the current timestamp (e.g. 'yesterday')
- time_range[x].unit_size
- the integer divisor in milliseconds to apply to the calculated time difference
- if unit_size > 0 then a number value is prepended to the cuteness string as calculated by time_difference / unit_size (e.g. 4 hours ago)
- if unit_size = 0, then no number is prepended to the cuteness string (e.g. an hour ago)
%CT% and International Support
Originally, CuteTime was developed with a less than universal syntactic centricity. Basically, CuteTime originally could hanle the cuteness of presenting...
"a few seconds ago"
"last month"
...as well as prepend values resulting in...
" hours ago" becoming "4 hours ago"
" seconds ago" becoming "18 seconds ago".
Now, in addition to supporting the prepending of the computed CuteTime,
- the calculation can be inserted within the cuteness string, and
- both formatted HTML styling and proper character accenting can be applied...
...resulting in the additional support for...
"il y a %CT% minutes" becoming "il y a 4 minutes"
"l\'année dernière" becoming "l'année dernière"
"<span style='color: red; font-weight: bold'>in the future<span>" becoming "in the future"
Date & Time
Formatting of timestamps is the bane of many a developer. Especially onerous is the handling of "standard" time formatting by the front-end developer. The JavaScript Date Object() supports the IETF standard, defined in RFC 822 Section 5, at least in FireFox, with most backend systems providing and storing (or at least converting to) dates in ISO8601 form.
Now, when converting a normal time into a CuteTime it can be either formatted in a manner compatible with the JavaScript Date() Object ...
Thu Oct 15 2009 22:11:19 GMT-0400 (Eastern Daylight Time)
Oct 15 2009 22:11:19
... or ISO8601 ...
2009-11-24T19:20:30+01:00
2009-11
2009-11-24T13:15:30Z
If you are counting on leveraging the JavaScript Date() Object handling of your timestamp, make sure you use timestamps that are fully recognized by the JavaScript Date object’s Parse method in all the browser versions you want to support. Otherwise, prepare for a headache.
Get It
You can download CuteTime, dual licensed under GPL and MIT, from...
jQuery Repository
http://plugins.jquery.com/project/CuteTime
Git
Public Clone URL: git://github.com/theproductguy/CuteTime.git
GitHub: http://github.com/theproductguy/CuteTime
Zip
jQuery.cuteTime-source-bundle_1.1.1_20100201.zip
Demo
http://theproductguy.com/cutetime/cutetime.demo.html
Release Notes
Version 1.0 - 2009/10/17
Initial Release.Version 1.0.5 - 2009/11/10
[UPDATED] updated cutetime attribute to be HTML 5 custom attribute compatible and more flexible in the future; using data-timestamp and global constant TS_ATTR
[UPDATED] test/demo HTML files to work with new TS_ATTR
[UPDATE] minified version of javascript compiled with Google's Closure Tools (new)
[FIXED] setting behavior is not as desired THEREFORE updated settings (temporarily) to be DESTRUCTIVE between updates
[FEATURE] added translations.txt to act as repository for all language translations for the CuteTime cuteness translationsVersion 1.0.6 - 2009.11.19
[FEATURE] added Spansish time translation to the translations.txt file (courtesy of Alex Hernandez)Version 1.1 - 2009.11.26
[FEATURE] implemented case-sensitive variable %CT% that can be used anywhere within the cuteness strings; if not specified, and number insertion is called for, then prepends number to provided string; if no number is called for, then the %CT% is removed from the final string
[FEATURE] added support for foreign language characters and HTML within the cuteness strings
[FEATURE] accepts timestamps in format compatible with either/both JavaScript Date() Object as well as ISO8601
[UPDATED] test/demo files to also demo foreign language and %CT%
[UPDATED] test/demo files to also demo ISO8601
[FEATURE] settings can be submitted as parameter to CuteTime function call
[FEATURE] added French time translation to the translations.txt file (courtesy of Bruno Morency)
[FIXED] documentation to indicate that Number.NEGATIVE_INFINITY and Number.POSTIVE_INFINITY should be used within the boundsVersion 1.1.1 - 2010.02.01
[FEATURE] added Russian time translation to the translations.txt file (courtesy of Jansen Price)
If you find this useful, or have any questions, ideas, or issues, leave a comment.
Enjoy!
Jeremy Horn
The Product Guy
$(document).ready(function () {
// timestamp MUST be a valid Date().parse 'able' format
$.cuteTime('2009/10/12 22:11:19');
});


October 26, 2009 at 9:45 am
[...] CuteTime [...]
October 27, 2009 at 1:37 pm
I have one initial comment about this plugin, and its the usage of the custom element attribute “cutetime”. This attribute is invalid HTML, and without a custom DTD its also invalid XHTML. To be HTML5 valid you would have to use a data-attribute, such as “data-cutetime”.
What is it you want to do with the orginal timestamp, since you expose it as a element attrbute? You could use jQuery.data to store the orginal timestamp in the internal jQuery data-object. It would be way faster, because you minimize the DOM-access. But this way the timestamp would not be exposed in the DOM, and therefore not accessible from ouside of the jQuery context.
If you do want to expose the orginal timestamp into the DOM, and therefore into the semantics of the markup, then I think you should consider using the HTML5 data-attributes, and in that case I would rename the attribute to “date” or “timestamp”, since its information that describes the date-context in a generic way.
Just my cents..
-Kenneth Auchenberg
October 27, 2009 at 3:57 pm
Thanks. Good advice. You will definitely find some of these suggestions in the next update. Please keep the feedback and feature suggestions coming.
October 29, 2009 at 6:20 pm
Thanks to Vincent Rolfs we have an example of how to use CuteTime in a multilingual setting. Vincent’s German example follows…
$(‘.timestamp’).cuteTime({
time_ranges: [
{bound: NEG_INF,
cuteness: 'in der Zukunft!', unit_size: 0},
{bound: 0,
cuteness: 'gerade jetzt', unit_size: 0},
{bound: 20 * 1000,
cuteness: 'vor ein paar Sekunden', unit_size: 0},
{bound: 60 * 1000,
cuteness: 'vor einer Minute', unit_size: 0},
{bound: 60 * 1000 * 2,
cuteness: ' Minuten her', unit_size: 60 * 1000},
{bound: 60 * 1000 * 60,
cuteness: 'vor einer Stunde', unit_size: 0},
{bound: 60 * 1000 * 60 * 2,
cuteness: ' Stunden her', unit_size: 60 * 1000 * 60},
{bound: 60 * 1000 * 60 * 24,
cuteness: 'Gestern', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 2,
cuteness: ' Tage her', unit_size: 60 * 1000 * 60 * 24},
{bound: 60 * 1000 * 60 * 24 * 30,
cuteness: 'letzen Monat', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 2,
cuteness: ' Monate her', unit_size: 60 * 1000 * 60 * 24 * 30},
{bound: 60 * 1000 * 60 * 24 * 30 * 12,
cuteness: 'letztes Jahr', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
cuteness: ' Jahre her', unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
{bound: POS_INF,
cuteness: 'vor langer Zeit', unit_size: 0}
]
});
November 12, 2009 at 4:01 pm
Hey, nice work, this my translation to Spanish .
thanks.
SETTINGS = {
time_ranges: [
{bound: NEG_INF,
cuteness: 'el futuro!', unit_size: 0},
{bound: 0,
cuteness: 'en este momento', unit_size: 0},
{bound: 20 * 1000,
cuteness: 'hace unos segundos', unit_size: 0},
{bound: 60 * 1000,
cuteness: 'hace un minuto', unit_size: 0},
{bound: 60 * 1000 * 2,
cuteness: ' minutos, unit_size: 60 * 1000},
{bound: 60 * 1000 * 60,
cuteness: 'hace una hora atrás', unit_size: 0},
{bound: 60 * 1000 * 60 * 2,
cuteness: ' horas', unit_size: 60 * 1000 * 60},
{bound: 60 * 1000 * 60 * 24,
cuteness: 'ayer', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 2,
cuteness: ' días', unit_size: 60 * 1000 * 60 * 24},
{bound: 60 * 1000 * 60 * 24 * 30,
cuteness: 'en el último mes', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 2,
cuteness: ' meses atrás', unit_size: 60 * 1000 * 60 * 24 * 30},
{bound: 60 * 1000 * 60 * 24 * 30 * 12,
cuteness: 'el año pasado', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
cuteness: ' años', unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
{bound: POS_INF,
cuteness: 'hace rato', unit_size: 0}
]
};
November 19, 2009 at 2:38 pm
Awesome! Alex, you rock! I will be including this translation in the next update.
I wonder which language will be submitted next….
November 14, 2009 at 9:12 am
[...] CuteTime is a customizable jQuery plugin that automatically converts timestamps to formats much cuter (i.e., yesterday, 2 hours ago, last year, in the future, etc). Also has the ability to dynamically re-update and/or automatically update timestamps on a controlled interval. [...]
November 22, 2009 at 8:17 am
How can i use unix time with this ?
November 22, 2009 at 10:34 pm
Can you be more specific? Can you provide me with an example of the date/time format?
November 23, 2009 at 4:43 am
This php example for UnixTime & ISO8601
<?php
echo 'Unix Time: '.date('U') .'’;
echo ‘ISO8601 Date: ‘.date(‘c’);
?>
the result right now
Unix Time: 1258965499
ISO8601 Date: 2009-11-23T08:38:19+00:00
http://en.wikipedia.org/wiki/Unix_time
November 24, 2009 at 1:52 pm
One such OK workaround can be to reformat the string to be JavaScript Date() compatible when passing the value to the client-side.
HOWEVER, I am, right now, working on a better solution. The next major release (v1.1) will support both JavaScript Date() and ISO 8601 compatible timestamp formats.
November 26, 2009 at 3:18 pm
Hi, thanks for this great plugin!
I started a translation in french, but there is a little difficulty :
X hours ago => il y a X heures
There is a way to place the X inside the sentence ?
November 26, 2009 at 4:00 pm
Hi again, I finally find a way
this is my french traduction :
{bound: NEG_INF, // IMPORANT: bounds MUST be in ascending order, from negative infinity to positive infinity
cuteness: ‘le future!’, unit_size: 0},
{bound: 0,
cuteness: “a l’instant”, unit_size: 0},
{bound: 20 * 1000,
cuteness: ‘il y a quelques secondes’, unit_size: 0},
{bound: 60 * 1000,
cuteness: ‘il y a 1 minute’, unit_size: 0},
{bound: 60 * 1000 * 2,
cuteness: ‘il y a X minutes’, unit_size: 60 * 1000},
{bound: 60 * 1000 * 60,
cuteness: ‘il y a 1 heure’, unit_size: 0},
{bound: 60 * 1000 * 60 * 2,
cuteness: ‘il y a X heures’, unit_size: 60 * 1000 * 60},
{bound: 60 * 1000 * 60 * 24,
cuteness: ‘hier’, unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 2,
cuteness: ‘il y a X jours’, unit_size: 60 * 1000 * 60 * 24},
{bound: 60 * 1000 * 60 * 24 * 30,
cuteness: ‘il y a 1 mois’, unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 2,
cuteness: ‘il y a X mois’, unit_size: 60 * 1000 * 60 * 24 * 30},
{bound: 60 * 1000 * 60 * 24 * 30 * 12,
cuteness: “il y a 1 an”, unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
cuteness: ‘il y a X ans’, unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
{bound: POS_INF,
cuteness: ‘a blinkle ago’, unit_size: 0}
then, replace :
cute_time = calculated_time + timespan['cuteness'];
by :
var reg=new RegExp(“(X)”, “g”);
cute_time = timespan['cuteness'].replace(reg,calculated_time);
November 27, 2009 at 6:01 am
[...] In: JQuery plugins 27 Nov 2009 Go to Source [...]
November 30, 2009 at 10:21 am
[...] CuteTime [...]
November 30, 2009 at 10:58 pm
hi, this is great! i want to use this for events, so would need it to output future dates. ie: this event is in 3 days 7h 12m 23sec
is this a possible feature to tweak into this great plugin?
thanks!
November 30, 2009 at 11:33 pm
Sam – You sure can define future cutetime language and time ranges. You can define the ranges to be in the past or the future via the settings as desired. However, the plugin will only display 1 unit of granularity. In your example you could say something is going to happen “in about 3 days” or “in 72 hours”.
December 1, 2009 at 2:42 am
Social comments and analytics for this post…
This post was mentioned on Twitter by macroman66: Excelente plugin de #jquery para convertir fechas tipo timestamp a fecha coloquiales. Util para foros o chats http://icio.us/30la5b...
December 8, 2009 at 6:49 pm
[...] This post was Twitted by FGRibreau [...]
December 21, 2009 at 2:33 am
[...] CuteTime [...]
December 27, 2009 at 1:05 pm
CuteTime is great!! xD, but… I’m making a website and i’m using DatePicker and i saw that when i had using CuteTime this wasn’t working and same with DatePicker..
Only works the wich was declared first.
Somebody can help me with a crack or some settings thanks.
December 27, 2009 at 1:29 pm
If you can send me a sample of the code you are having trouble with that I can run locally, I would be happy to take a look.
December 28, 2009 at 12:05 am
Ok, I have sended to you an email.
thanks for response
January 23, 2010 at 3:53 pm
[...] Shared CuteTime « The Product Guy. [...]
January 30, 2010 at 4:02 am
Hi,
Looks like a great plugin, we would just like to suggest one update to your above settings code. Shouldnt the last bound be positive infinity? Currently you have both first and last bound as “Number.NEGATIVE_INFINITY”
January 30, 2010 at 8:24 am
You are correct. Thanks. Fixed.
February 1, 2010 at 1:27 pm
[...] For more details about the latest CuteTime improvements and their implementation, visit http://tpgblog.com/CuteTime [...]
February 2, 2010 at 12:48 pm
Hi. Thank you for a great plugin.
Here’s my translation to Portuguese (Portugal)
var portuguese = {
time_ranges: [
{bound: Number.NEGATIVE_INFINITY,
cuteness: 'o futuro!', unit_size: 0},
{bound: 0,
cuteness: 'agora mesmo', unit_size: 0},
{bound: 20 * 1000,
cuteness: 'há uns segundos', unit_size: 0},
{bound: 60 * 1000,
cuteness: 'há um minuto', unit_size: 0},
{bound: 60 * 1000 * 2,
cuteness: 'há %CT% minutos', unit_size: 60 * 1000},
{bound: 60 * 1000 * 60,
cuteness: 'acerca de há uma hora atrás', unit_size: 0},
{bound: 60 * 1000 * 60 * 2,
cuteness: 'há %CT% horas atrás', unit_size: 60 * 1000 * 60},
{bound: 60 * 1000 * 60 * 24,
cuteness: 'ontem', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 2,
cuteness: 'há %CT% dias', unit_size: 60 * 1000 * 60 * 24},
{bound: 60 * 1000 * 60 * 24 * 30,
cuteness: 'no mês passado', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 2,
cuteness: 'há %CT% meses atrás', unit_size: 60 * 1000 * 60 * 24 * 30},
{bound: 60 * 1000 * 60 * 24 * 30 * 12,
cuteness: 'no ano passado', unit_size: 0},
{bound: 60 * 1000 * 60 * 24 * 30 * 12 * 2,
cuteness: 'há %CT% anos', unit_size: 60 * 1000 * 60 * 24 * 30 * 12},
{bound: Number.POSITIVE_INFINITY,
cuteness: 'há bué tempo', unit_size: 0}
]
};
February 2, 2010 at 4:07 pm
This is great! Thank you very much.
February 3, 2010 at 8:50 am
Thank you for this interesting plugin.
But there seems to be a problem with calculation of spans greater than 24 hours.
Let’s say it is 2010-01-03 12:00:00 for example and I want to get the cute time for 2010-01-01 18:00:00 it will return “yesterday” – that is not correct.
Tested this with IE8 and FF 3.6
February 3, 2010 at 11:07 am
Thank you. The calculation is correct. In my examples I have defined yesterday to be between 24 and 48 hours ago — you example falls right within that window. The great thing about CuteTime is that it allows for the customization of times, units and timespans to suit your needs. Thereby allowing you to remove the “yesterday” label or even redefine it. Hope this helps clarify.