├── .gitignore ├── .gitmodules ├── .jshintignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── README.md ├── demo └── index.html ├── i18n ├── jquery.prettydate-cn.js ├── jquery.prettydate-cs-CZ.js ├── jquery.prettydate-da.js ├── jquery.prettydate-de.js ├── jquery.prettydate-es.js ├── jquery.prettydate-fr.js ├── jquery.prettydate-he.js ├── jquery.prettydate-id.js ├── jquery.prettydate-it.js ├── jquery.prettydate-ja.js ├── jquery.prettydate-kr.js ├── jquery.prettydate-lv.js ├── jquery.prettydate-nl.js ├── jquery.prettydate-pl.js ├── jquery.prettydate-pt-BR.js ├── jquery.prettydate-ro.js ├── jquery.prettydate-ru.js ├── jquery.prettydate-sv.js ├── jquery.prettydate-th.js ├── jquery.prettydate-tr.js ├── jquery.prettydate-uk.js ├── jquery.prettydate-zh-CN.js └── jquery.prettydate-zh-TW.js ├── jquery.prettydate.js ├── libs └── jquery.js ├── package.json ├── prettydate.jquery.json └── test ├── .jshintrc ├── index.html └── jquery.prettydate.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | build/dist 3 | docs 4 | .project 5 | *~ 6 | *.diff 7 | *.patch 8 | .DS_Store 9 | node_modules -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/jquery.qunit"] 2 | path = libs/jquery.qunit 3 | url = git://github.com/jquery/qunit.git 4 | -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | libs/ -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "camelcase": true, 3 | "curly": true, 4 | "eqeqeq": true, 5 | "immed": true, 6 | "latedef": true, 7 | "newcap": true, 8 | "noarg": true, 9 | "noempty": true, 10 | "nonew": true, 11 | "plusplus": true, 12 | "quotmark": "single", 13 | "undef": true, 14 | "unused": true, 15 | "strict": false, 16 | "trailing": true, 17 | 18 | "browser": true, 19 | "jquery": true, 20 | 21 | "nomen": true, 22 | "onevar": true 23 | } 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.10 4 | install: 5 | - npm install grunt-cli -g 6 | - npm install 7 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true*/ 2 | module.exports = function(grunt) { 3 | 4 | // Project configuration. 5 | grunt.initConfig({ 6 | qunit: { 7 | files: ['test/index.html'] 8 | }, 9 | jshint: { 10 | options: { 11 | jshintrc: '.jshintrc' 12 | }, 13 | files: [ 14 | 'jquery.prettydate.js', 15 | 'i18n/*.js' 16 | ], 17 | test: { 18 | options: { 19 | jshintrc: 'test/.jshintrc' 20 | }, 21 | files: { 22 | src: [ 23 | 'test/*.js' 24 | ] 25 | } 26 | }, 27 | grunt: { 28 | files: { 29 | src: [ 30 | 'Gruntfile.js' 31 | ] 32 | } 33 | } 34 | } 35 | }); 36 | 37 | grunt.loadNpmTasks('grunt-contrib-jshint'); 38 | grunt.loadNpmTasks('grunt-contrib-qunit'); 39 | 40 | grunt.registerTask('default', ['jshint', 'qunit']); 41 | 42 | }; 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [jQuery Prettydate Plugin](http://bassistance.de/jquery-plugins/jquery-plugin-prettydate/) 2 | ================================ 3 | 4 | [![Build Status](https://secure.travis-ci.org/jzaefferer/jquery-prettydate.png)](http://travis-ci.org/jzaefferer/jquery-prettydate) 5 | 6 | This plugin, originally written by John Resig, provides clientside date formatting in the style of Twitter’s timeline: “just now”, “5 minutes ago”, “yesterday”, “2 weeks ago”. This release extends John’s original release, providing support for internationalization and improving the API a bit: You can specify the source of the ISO-date, while not having to manually set up an interval to update the date formatting over time. 7 | 8 | See the link above for usage details. -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery prettyDate Demo 6 | 7 | 8 | 60 | 164 | 165 | 166 | 167 |

jQuery prettyDate Demo

168 |
169 | 170 |
171 |

Source code: github.com/jzaefferer/jquery-prettydate

172 |
173 | 174 | 175 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-cn.js: -------------------------------------------------------------------------------- 1 | /* Chinese */ 2 | $.extend($.prettyDate.messages, { 3 | now: '刚刚', 4 | minute: '1分钟前', 5 | minutes: $.prettyDate.template('{0}分钟前'), 6 | hour: '1小时前', 7 | hours: $.prettyDate.template('{0}小时前'), 8 | yesterday: '昨天', 9 | days: $.prettyDate.template('{0}天前'), 10 | week: '1星期前', 11 | weeks: $.prettyDate.template('{0}星期前') 12 | }); 13 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-cs-CZ.js: -------------------------------------------------------------------------------- 1 | /* Czech */ 2 | $.prettyDate.messages = { 3 | now: 'před chvílí', 4 | minute: 'před minutou', 5 | minutes: $.prettyDate.template('před {0} minutami'), 6 | hour: 'před hodinou', 7 | hours: $.prettyDate.template('před {0} hodinami'), 8 | yesterday: 'včera', 9 | days: $.prettyDate.template('před {0} dny'), 10 | weeks: $.prettyDate.template('před {0} týdny') 11 | }; 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-da.js: -------------------------------------------------------------------------------- 1 | /* Danish */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'lige nu', 4 | minute: 'et minut siden', 5 | minutes: $.prettyDate.template('{0} minutter siden'), 6 | hour: 'en time siden', 7 | hours: $.prettyDate.template('{0} timer siden'), 8 | yesterday: 'i går', 9 | days: $.prettyDate.template('{0} dage siden'), 10 | weeks: $.prettyDate.template('{0} uger siden') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-de.js: -------------------------------------------------------------------------------- 1 | /* German */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'gerade eben', 4 | minute: 'vor einer Minute', 5 | minutes: $.prettyDate.template('vor {0} Minuten'), 6 | hour: 'vor einer Stunde', 7 | hours: $.prettyDate.template('vor {0} Stunden'), 8 | yesterday: 'gestern', 9 | dayBeforeYesterday: 'vorgestern', 10 | days: $.prettyDate.template('vor {0} Tagen'), 11 | week: 'vor einer Woche', 12 | weeks: $.prettyDate.template('vor {0} Wochen'), 13 | month: 'vor einem Monat', 14 | months: $.prettyDate.template('vor {0} Monaten'), 15 | year: 'vor einem Jahr', 16 | years: $.prettyDate.template('vor {0} Jahren') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-es.js: -------------------------------------------------------------------------------- 1 | /* Spanish */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'recién', 4 | minute: 'hace un minuto', 5 | minutes: $.prettyDate.template('hace {0} minutos'), 6 | hour: 'hace una hora', 7 | hours: $.prettyDate.template('hace {0} horas'), 8 | yesterday: 'ayer', 9 | dayBeforeYesterday: 'anteayer', 10 | days: $.prettyDate.template('hace {0} días'), 11 | week: 'hace una semana', 12 | weeks: $.prettyDate.template('hace {0} semanas'), 13 | month: 'hace un mes', 14 | months: $.prettyDate.template('hace {0} meses'), 15 | year: 'hace un año', 16 | years: $.prettyDate.template('hace {0} años') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-fr.js: -------------------------------------------------------------------------------- 1 | /* French */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'à l\'instant', 4 | minute: 'il y a 1 minute', 5 | minutes: $.prettyDate.template(' il y a {0} minutes'), 6 | hour: ' il y a 1 heure', 7 | hours: $.prettyDate.template('il y a {0} heures'), 8 | yesterday: 'Hier', 9 | dayBeforeYesterday: 'Avant-hier', 10 | days: $.prettyDate.template('il y a {0} jours'), 11 | week: 'Il y a une semaine', 12 | weeks: $.prettyDate.template('il y a {0} semaines'), 13 | month: 'Il y a un mois', 14 | months: $.prettyDate.template('Il y a {0} mois'), 15 | year: 'Il y a un an', 16 | years: $.prettyDate.template('Il y a {0} ans') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-he.js: -------------------------------------------------------------------------------- 1 | /* Hebrew */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'ממש הרגע', 4 | minute: 'לפני דקה', 5 | minutes: $.prettyDate.template('לפני {0} דקות'), 6 | hour: 'לפני שעה', 7 | hours: $.prettyDate.template('לפני {0} שעות'), 8 | yesterday: 'אתמול', 9 | dayBeforeYesterday: 'לפני יומיים', 10 | days: $.prettyDate.template('לפני {0} ימים'), 11 | week: 'לפני שבוע', 12 | weeks: $.prettyDate.template('לפני {0} שבועות'), 13 | month: 'לפני חודש', 14 | months: $.prettyDate.template('לפני {0} חודשים'), 15 | year: 'לפני שנה', 16 | years: $.prettyDate.template('לפני {0} שנים') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-id.js: -------------------------------------------------------------------------------- 1 | /* Indonesian */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'sekarang', 4 | minute: '1 menit lalu', 5 | minutes: $.prettyDate.template('{0} Menit lalu'), 6 | hour: '1 jam lalu', 7 | hours: $.prettyDate.template('{0} Jam lalu'), 8 | yesterday: 'Kemarin', 9 | days: $.prettyDate.template('{0} Hari lalu'), 10 | weeks: $.prettyDate.template('{0} Minggu lalu') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-it.js: -------------------------------------------------------------------------------- 1 | /* Italian */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'adesso', 4 | minute: 'un minuto fa', 5 | minutes: $.prettyDate.template('{0} minuti fa'), 6 | hour: 'un\'ora fa', 7 | hours: $.prettyDate.template('{0} ore fa'), 8 | yesterday: 'ieri', 9 | dayBeforeYesterday: 'l\'altro ieri', 10 | days: $.prettyDate.template('{0} giorni fa'), 11 | week: 'una settimana fa', 12 | weeks: $.prettyDate.template('{0} settimane fa'), 13 | month: 'un mese fa', 14 | months: $.prettyDate.template('{0} mesi fa'), 15 | year: 'un anno fa', 16 | years: $.prettyDate.template('{0} anni fa') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-ja.js: -------------------------------------------------------------------------------- 1 | /* Japanese */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'たった今', 4 | minute: '1分前', 5 | minutes: $.prettyDate.template('{0}分前'), 6 | hour: $.prettyDate.template('1時間前'), 7 | hours: $.prettyDate.template('{0}時間前'), 8 | yesterday: '1日前', 9 | dayBeforeYesterday: '2日前', 10 | days: $.prettyDate.template('{0}日前'), 11 | week: '1週間前', 12 | weeks: $.prettyDate.template('{0}週間前'), 13 | month: '1ヶ月前', 14 | months: $.prettyDate.template('{0}ヶ月前'), 15 | year: '1年前', 16 | years: $.prettyDate.template('{0}年前') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-kr.js: -------------------------------------------------------------------------------- 1 | /* Korean */ 2 | $.extend($.prettyDate.messages, { 3 | now: '조금 전', 4 | minute: '약 1분 전', 5 | minutes: $.prettyDate.template('약 {0}분 전'), 6 | hour: '약 1시간 전', 7 | hours: $.prettyDate.template('약 {0}시간 전'), 8 | yesterday: '어제', 9 | dayBeforeYesterday: '그제', 10 | days: $.prettyDate.template('{0}일 전'), 11 | week: '지난주', 12 | weeks: $.prettyDate.template('약 {0}주 전'), 13 | month: '지난달', 14 | months: $.prettyDate.template('약 {0}개월 전'), 15 | year: '작년', 16 | years: $.prettyDate.template('약 {0}년 전') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-lv.js: -------------------------------------------------------------------------------- 1 | /* Latvian */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'tikko', 4 | minute: 'pirms minūtes', 5 | minutes: $.prettyDate.template('pirms {0} minūtēm'), 6 | hour: 'pirms stundas', 7 | hours: $.prettyDate.template('pirms {0} stundām'), 8 | yesterday: 'vakar', 9 | days: $.prettyDate.template('pirms {0} dienām'), 10 | weeks: $.prettyDate.template('pirms {0} nedēļām') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-nl.js: -------------------------------------------------------------------------------- 1 | /* Dutch */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'nu net', 4 | minute: 'een minuut geleden', 5 | minutes: $.prettyDate.template('{0} minuten geleden'), 6 | hour: '1 uur geleden', 7 | hours: $.prettyDate.template('{0} uur geleden'), 8 | yesterday: 'gisteren', 9 | days: $.prettyDate.template('{0} dagen geleden'), 10 | week: '1 week geleden', 11 | weeks: $.prettyDate.template('{0} weken geleden'), 12 | month: '1 maand geleden', 13 | months: $.prettyDate.template('{0} maanden geleden'), 14 | year: '1 jaar geleden', 15 | years: $.prettyDate.template('{0} jaren geleden') 16 | }); 17 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-pl.js: -------------------------------------------------------------------------------- 1 | /* Polish */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'przed chwilą', 4 | minute: 'minutę temu', 5 | minutes: $.prettyDate.template('{0} minut temu'), 6 | hour: 'godzinę temu', 7 | hours: $.prettyDate.template('{0} godzin temu'), 8 | yesterday: 'wczoraj', 9 | days: $.prettyDate.template('{0} dni temu'), 10 | weeks: $.prettyDate.template('{0} tygodni temu') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-pt-BR.js: -------------------------------------------------------------------------------- 1 | /* Portugês Brasil */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'agora', 4 | minute: 'há 1 minuto', 5 | minutes: $.prettyDate.template('há {0} minutos'), 6 | hour: 'há 1 hora', 7 | hours: $.prettyDate.template('há {0} horas'), 8 | yesterday: 'ontem', 9 | days: $.prettyDate.template('há {0} dias'), 10 | weeks: $.prettyDate.template('há {0} semanas') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-ro.js: -------------------------------------------------------------------------------- 1 | /* Romanian */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'acum', 4 | minute: 'acum un minut', 5 | minutes: $.prettyDate.template('acum {0} minute'), 6 | hour: 'acum o oră', 7 | hours: $.prettyDate.template('acum {0} ore'), 8 | yesterday: 'ieri', 9 | days: $.prettyDate.template('acum {0} zile'), 10 | week: 'acum o săptămână', 11 | weeks: $.prettyDate.template('acum {0} săptămâni'), 12 | month: 'acum o lună', 13 | months: $.prettyDate.template('acum {0} luni'), 14 | year: 'acum un an', 15 | years: $.prettyDate.template('acum {0} ani') 16 | }); -------------------------------------------------------------------------------- /i18n/jquery.prettydate-ru.js: -------------------------------------------------------------------------------- 1 | $.prettyDate.messages = (function() { 2 | 3 | var FuncSource = function(single, few, many) { 4 | this.single = single; 5 | this.few = few; 6 | this.many = many; 7 | }; 8 | 9 | FuncSource.prototype = { 10 | replace: function(regexp, amt) { 11 | return amt % 10 === 1 && amt % 100 !== 11 ? this.single.replace(regexp, amt) : (amt % 10 >= 2 && amt % 10 <= 4 && (amt % 100 < 10 || amt % 100 >= 20)? this.few.replace(regexp, amt): this.many.replace(regexp, amt)); 12 | } 13 | }; 14 | 15 | return { 16 | now: 'Только что', 17 | minute: 'Минуту назад', 18 | minutes: $.prettyDate.template(new FuncSource('{0} минуту назад', '{0} минуты назад', '{0} минут назад')), 19 | hour: 'Час назад', 20 | hours: $.prettyDate.template(new FuncSource('{0} час назад', '{0} часа назад', '{0} часов назад')), 21 | yesterday: 'Вчера', 22 | dayBeforeYesterday: 'Позавчера', 23 | days: $.prettyDate.template(new FuncSource('{0} день назад', '{0} дня назад', '{0} дней назад')), 24 | week: 'Неделю назад', 25 | weeks: $.prettyDate.template(new FuncSource('{0} неделю назад', '{0} недели назад', '{0} недель назад')), 26 | month: 'Месяц назад', 27 | months: $.prettyDate.template(new FuncSource('{0} месяц назад', '{0} месяца назад', '{0} месяцев назад')), 28 | year: 'Год назад', 29 | years: $.prettyDate.template(new FuncSource('{0} год назад', '{0} года назад', '{0} лет назад')) 30 | }; 31 | })(); -------------------------------------------------------------------------------- /i18n/jquery.prettydate-sv.js: -------------------------------------------------------------------------------- 1 | /* Swedish */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'just nu', 4 | minute: 'en minut sedan', 5 | minutes: $.prettyDate.template('{0} minuter sedan'), 6 | hour: 'en timme sedan', 7 | hours: $.prettyDate.template('{0} timmar sedan'), 8 | yesterday: 'igår', 9 | dayBeforeYesterday: 'Förrgår', 10 | days: $.prettyDate.template('{0} dagar sedan'), 11 | weeks: $.prettyDate.template('{0} veckor sedan'), 12 | month: '1 månad sedan', 13 | months: $.prettyDate.template('{0} månader sedan'), 14 | year: '1 år sedan', 15 | years: $.prettyDate.template('{0} år sedan') 16 | }); 17 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-th.js: -------------------------------------------------------------------------------- 1 | /* Thai */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'ปัจจุบัน', 4 | minute: 'นาที', 5 | minutes: $.prettyDate.template('{0} นาทีที่แล้ว'), 6 | hour: 'ชั่วโมง', 7 | hours: $.prettyDate.template('{0} ชั่วโมงที่แล้ว'), 8 | yesterday: 'เมื่อวาน', 9 | days: $.prettyDate.template('{0} วันที่แล้ว'), 10 | weeks: $.prettyDate.template('{0} สัปดาห์ที่แล้ว') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-tr.js: -------------------------------------------------------------------------------- 1 | /* Turkish */ 2 | $.extend($.prettyDate.messages, { 3 | now: 'Az önce', 4 | minute: '1 dakika önce', 5 | minutes: $.prettyDate.template('{0} dakika önce'), 6 | hour: '1 saat önce', 7 | hours: $.prettyDate.template('{0} saat önce'), 8 | yesterday: 'Dün', 9 | days: $.prettyDate.template('{0} gün önce'), 10 | weeks: $.prettyDate.template('{0} hafta önce') 11 | }); 12 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-uk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Ukrainian localization 3 | * Author: Menelion Elensúle 4 | * https://github.com/Oire/ 5 | */ 6 | 7 | $.prettyDate.messages = (function() { 8 | 9 | var FuncSource = function(single, few, many) { 10 | this.single = single; 11 | this.few = few; 12 | this.many = many; 13 | }; 14 | 15 | FuncSource.prototype = { 16 | replace: function(regexp, amt) { 17 | return amt % 10 === 1 && amt % 100 !== 11 ? this.single.replace(regexp, amt): (amt % 10 >= 2 && amt % 10 <= 4 && (amt % 100 < 10 || amt % 100 >= 20)? this.few.replace(regexp, amt): this.many.replace(regexp, amt)); 18 | } 19 | }; 20 | 21 | return { 22 | now: 'Щойно', 23 | minute: 'Хвилину тому', 24 | minutes: $.prettyDate.template(new FuncSource('{0} хвилину тому', '{0} хвилини тому', '{0} хвилин тому')), 25 | hour: 'Годину тому', 26 | hours: $.prettyDate.template(new FuncSource('{0} годину тому', '{0} години тому', '{0} годин тому')), 27 | yesterday: 'Вчора', 28 | dayBeforeYesterday: 'Позавчора', 29 | days: $.prettyDate.template(new FuncSource('{0} день тому', '{0} дні тому', '{0} днів тому')), 30 | week: 'Тиждень тому', 31 | weeks: $.prettyDate.template(new FuncSource('{0} тиждень тому', '{0} тижні тому', '{0} тижнів тому')), 32 | month: 'Місяць тому', 33 | months: $.prettyDate.template(new FuncSource('{0} місяць тому', '{0} місяці тому', '{0} місяців тому')), 34 | year: 'Рік тому', 35 | years: $.prettyDate.template(new FuncSource('{0} рік тому', '{0} роки тому', '{0} років тому')) 36 | }; 37 | })(); -------------------------------------------------------------------------------- /i18n/jquery.prettydate-zh-CN.js: -------------------------------------------------------------------------------- 1 | /* Simplified Chinese */ 2 | $.extend($.prettyDate.messages, { 3 | now: '刚刚', 4 | minute: '1分钟前', 5 | minutes: $.prettyDate.template('{0}分钟前'), 6 | hour: $.prettyDate.template('1小时前'), 7 | hours: $.prettyDate.template('{0}小时前'), 8 | yesterday: '昨天', 9 | dayBeforeYesterday: '前天', 10 | days: '{0}天前', 11 | week: '1周前', 12 | weeks: '{0}周前', 13 | month: '1个月前', 14 | months: '{0}个月前', 15 | year: '1年前', 16 | years: $.prettyDate.template('{0}年前') 17 | }); 18 | -------------------------------------------------------------------------------- /i18n/jquery.prettydate-zh-TW.js: -------------------------------------------------------------------------------- 1 | /* Traditional Chinese */ 2 | $.extend($.prettyDate.messages, { 3 | now: '剛剛', 4 | minute: '1分鐘前', 5 | minutes: $.prettyDate.template('{0}分鐘前'), 6 | hour: '1小時前', 7 | hours: $.prettyDate.template('{0}小時前'), 8 | yesterday: '昨天', 9 | dayBeforeYesterday: '兩天前', 10 | days: $.prettyDate.template('{0}天前'), 11 | week: '1星期前', 12 | weeks: $.prettyDate.template('{0}星期前'), 13 | month: '1個月前', 14 | months: $.prettyDate.template('{0}個月前'), 15 | year: '1年前', 16 | years: $.prettyDate.template('{0}年前') 17 | }); 18 | -------------------------------------------------------------------------------- /jquery.prettydate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery prettyDate v1.2.0pre 3 | * 4 | * @author John Resig (ejohn.org) 5 | * @author Jörn Zaefferer 6 | * @author Timo Tijhof 7 | * 8 | * Based on http://ejohn.org/blog/javascript-pretty-date 9 | * Documentation: http://bassistance.de/jquery-plugins/jquery-plugin-prettydate/ 10 | * 11 | * Copyright 2013 Jörn Zaefferer 12 | * Released under the MIT license: 13 | * http://www.opensource.org/licenses/mit-license.php 14 | */ 15 | 16 | (function ($) { 17 | 'use strict'; 18 | 19 | var slice = Array.prototype.slice, 20 | rES5ts = /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/, 21 | // Indexes in a rES5ts match list that are required for Date.UTC, 22 | // Use in a loop to replace undefined with 0 (otherwise Date.UTC would give NaN) 23 | dateUrcReqIndx = [1, 4, 5, 6, 7, 10, 11]; 24 | 25 | $.prettyDate = { 26 | 27 | /** 28 | * Replace numerial placeholders ({0}, {1}, ..) with the value 29 | * at that index in the array or variadic list of arugments. 30 | * When called with only a source, a function is returned that calls itself 31 | * again, that time with the arguments passed to apply the template. 32 | * 33 | * @param {string} source Text containing {#} placeholders where 34 | * '#' is a number referring to an index in `params`. 35 | * @param {string|Array} [params...] List of replacement values or a 36 | * varadic argument list starting where this argument is the first one. 37 | */ 38 | template: function (source, params) { 39 | if (arguments.length === 1) { 40 | return function () { 41 | var args = slice.call(arguments); 42 | args.unshift(source); 43 | return $.prettyDate.template.apply(this, args); 44 | }; 45 | } 46 | // Detect different call patterns: 47 | // * template(source, [1, 2, 3]) 48 | // * template(source, 1, 2, 3) 49 | if (!$.isArray(params)) { 50 | params = slice.call(arguments, 1); 51 | } 52 | $.each(params, function (i, n) { 53 | source = source.replace(new RegExp('\\{' + i + '\\}', 'g'), n); 54 | }); 55 | return source; 56 | }, 57 | 58 | /** 59 | * Offset from which the relative date will be generated. 60 | * @return {Date} 61 | */ 62 | now: function () { 63 | return new Date(); 64 | }, 65 | 66 | /** 67 | * Implementation of the ES5 Date.parse specification (ES5 §15.9.4.2, 68 | * which is a subset of ISO 8601), see http://es5.github.com/#x15.9.1.15. 69 | 70 | * Since Date.parse already existed in old browsers and there would be 71 | * many forms to be tested for, don't use feature-detection but just 72 | * implement it straight up. 73 | * 74 | * Based on https://github.com/csnover/js-iso8601 75 | * 76 | * @example 77 | * '2012' 78 | * '2012-01-07' 79 | * '2012-01-07T23:30:59Z' 80 | * '2012-01-07T23:30:59+01:00' 81 | * '2012-01-07T23:30:59.001+01:00' 82 | * @param {string} timestamp 83 | * @return {number} Unix epoch or NaN. 84 | */ 85 | parse: function (timestamp) { 86 | var i, k, minutesOffset, 87 | m = rES5ts.exec(timestamp); 88 | if (!m) { 89 | return NaN; 90 | } 91 | for (i = 0; (k = dateUrcReqIndx[i]); i += 1) { 92 | m[k] = +m[k] || 0; 93 | } 94 | // Undefined days and months are allowed 95 | m[2] = +m[2] || 1; 96 | m[3] = +m[3] || 1; 97 | 98 | if (m[8] !== 'Z' && m[9] !== undefined) { 99 | minutesOffset = m[10] * 60 + m[11]; 100 | 101 | if (m[9] === '+') { 102 | minutesOffset = 0 - minutesOffset; 103 | } 104 | } else { 105 | minutesOffset = 0; 106 | } 107 | 108 | return Date.UTC( 109 | // Year 110 | m[1], 111 | // Month 112 | m[2] - 1, 113 | // Day 114 | m[3], 115 | // Hour 116 | m[4], 117 | // Minutes 118 | // Date.UTC allows values higher than 59 here, 119 | // it increments hours, days etc. if needed. 120 | m[5] + minutesOffset, 121 | // Seconds 122 | m[6], 123 | // Milliseconds 124 | m[7] 125 | ); 126 | }, 127 | 128 | /** 129 | * Takes an ISO time and returns a string representing how 130 | * long ago the date represents. 131 | * @param {string} targetTs Timestamp in ISO 8601 format. 132 | * @return {string} 133 | */ 134 | format: function (target) { 135 | var messages, 136 | targetTime = $.prettyDate.parse(target), 137 | nowTime = $.prettyDate.now().getTime(), 138 | diff = (nowTime - targetTime) / 1000, 139 | dayDiff = Math.floor(diff / 86400); 140 | 141 | if (isNaN(dayDiff) || dayDiff < 0) { 142 | return; 143 | } 144 | 145 | messages = $.prettyDate.messages; 146 | return dayDiff === 0 && ( 147 | diff < 60 && messages.now || 148 | diff < 120 && messages.minute || 149 | diff < 3600 && messages.minutes(Math.floor(diff / 60)) || 150 | diff < 7200 && messages.hour || 151 | diff < 86400 && messages.hours(Math.floor(diff / 3600))) || 152 | dayDiff === 1 && messages.yesterday || 153 | dayDiff === 2 && (messages.dayBeforeYesterday || messages.days(dayDiff)) || 154 | dayDiff < 7 && messages.days(dayDiff) || 155 | dayDiff < 8 && messages.week || 156 | dayDiff < 14 && messages.days(dayDiff) || 157 | dayDiff < 30 && messages.weeks(Math.ceil(dayDiff / 7)) || 158 | dayDiff < 32 && messages.month || 159 | dayDiff < 363 && messages.months(Math.ceil(dayDiff / 31)) || 160 | dayDiff <= 380 && messages.year || 161 | dayDiff > 380 && messages.years(Math.ceil(dayDiff / 365)); 162 | } 163 | 164 | }; 165 | 166 | $.prettyDate.messages = { 167 | now: 'just now', 168 | minute: '1 minute ago', 169 | minutes: $.prettyDate.template('{0} minutes ago'), 170 | hour: '1 hour ago', 171 | hours: $.prettyDate.template('{0} hours ago'), 172 | yesterday: 'Yesterday', 173 | dayBeforeYesterday: 'Two days ago', 174 | days: $.prettyDate.template('{0} days ago'), 175 | week: '1 week ago', 176 | weeks: $.prettyDate.template('{0} weeks ago'), 177 | month: '1 month ago', 178 | months: $.prettyDate.template('{0} months ago'), 179 | year: '1 year ago', 180 | years: $.prettyDate.template('{0} years ago') 181 | }; 182 | 183 | /** 184 | * @context {jQuery} 185 | * @param {Object} options 186 | * - {number|false} interval Time in milliseconds between updates, 187 | * or set to false to disable auto updating interval. 188 | * - {string} attribute Name of attribute where the timestamp should 189 | * be accessed from. 190 | * - {Function} value Overrides 'attribute', a custom function to get the 191 | * timestamp. 'this' context is set to the HTMLElement. 192 | */ 193 | $.fn.prettyDate = function (options) { 194 | options = $.extend({ 195 | interval: 10000, 196 | attribute: 'title', 197 | value: function () { 198 | return $(this).attr(options.attribute); 199 | } 200 | }, options); 201 | var elements = this; 202 | function format() { 203 | elements.each(function () { 204 | var date = $.prettyDate.format(options.value.apply(this)); 205 | if (date && $(this).text() !== date) { 206 | $(this).text(date); 207 | } 208 | }); 209 | } 210 | format(); 211 | if (options.interval) { 212 | setInterval(format, options.interval); 213 | } 214 | return this; 215 | }; 216 | 217 | }(jQuery)); 218 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettydate", 3 | "title": "jQuery Prettydate", 4 | "description": "Format relative dates as 'six minutes ago' and the like.", 5 | "version": "0.0.0", 6 | "homepage": "https://github.com/jzaefferer/jquery-prettydate", 7 | "author": { 8 | "name": "Jörn Zaefferer", 9 | "email": "joern.zaefferer@gmail.com", 10 | "url": "http://bassistance.de" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/jzaefferer/jquery-prettydate.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/jzaefferer/jquery-prettydate/issues" 18 | }, 19 | "licenses": [ 20 | { 21 | "type": "MIT", 22 | "url": "http://www.opensource.org/licenses/MIT" 23 | } 24 | ], 25 | "scripts": { 26 | "test": "grunt jshint qunit" 27 | }, 28 | "devDependencies": { 29 | "grunt": "~0.4.1", 30 | "grunt-contrib-qunit": "~0.2.1", 31 | "grunt-contrib-jshint": "~0.4.3" 32 | }, 33 | "keywords": [ 34 | "dates", 35 | "prettydate", 36 | "relativetime" 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /prettydate.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "prettydate", 3 | "title": "jQuery Prettydate", 4 | "description": "Format relative dates as 'six minutes ago' and the like.", 5 | "keywords": [ 6 | "dates", 7 | "prettydate", 8 | "relativetime" 9 | ], 10 | "version": "1.2.0pre", 11 | "author": { 12 | "name": "Jörn Zaefferer", 13 | "email": "joern.zaefferer@gmail.com", 14 | "url": "http://bassistance.de" 15 | }, 16 | "licenses": [ 17 | { 18 | "type": "MIT", 19 | "url": "http://www.opensource.org/licenses/MIT" 20 | } 21 | ], 22 | "bugs": "https://github.com/jzaefferer/jquery-prettydate/issues", 23 | "homepage": "https://github.com/jzaefferer/jquery-prettydate", 24 | "docs": "http://bassistance.de/jquery-plugins/jquery-plugin-prettydate/", 25 | "download": "http://bassistance.de/jquery-plugins/jquery-plugin-prettydate/", 26 | "dependencies": { 27 | "jquery": ">=1.8" 28 | } 29 | } -------------------------------------------------------------------------------- /test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "QUnit", 4 | "module", 5 | "test", 6 | "start", 7 | "stop", 8 | "expect", 9 | "ok", 10 | "equal", 11 | "deepEqual", 12 | "strictEqual" 13 | ], 14 | 15 | "camelcase": true, 16 | "curly": true, 17 | "eqeqeq": true, 18 | "immed": true, 19 | "latedef": true, 20 | "newcap": true, 21 | "noarg": true, 22 | "noempty": true, 23 | "nonew": true, 24 | "plusplus": true, 25 | "quotmark": "single", 26 | "undef": true, 27 | "unused": true, 28 | "strict": false, 29 | "trailing": true, 30 | 31 | "browser": true, 32 | "jquery": true, 33 | 34 | "nomen": true, 35 | "onevar": true, 36 | "white": true 37 | } 38 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jQuery prettyDate Test 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 | fallback 16 | fallback 17 | fallback 18 | fallback 19 | fallback 20 | fallback 21 | fallback 22 | fallback 23 | fallback 24 | fallback 25 | fallback 26 | fallback 27 | fallback 28 | fallback 29 |
30 |
31 | fallback 32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /test/jquery.prettydate.test.js: -------------------------------------------------------------------------------- 1 | (function ($, QUnit) { 2 | 3 | QUnit.module('prettyDate', { 4 | setup: function () { 5 | this.orgNow = $.prettyDate.now; 6 | this.orgMessages = $.prettyDate.messages; 7 | $.prettyDate.messages = $.extend(true, {}, this.orgMessages); 8 | }, 9 | teardown: function () { 10 | // Restore 11 | $.prettyDate.now = this.orgNow; 12 | $.prettyDate.messages = this.orgMessages; 13 | } 14 | }); 15 | 16 | // Fixed "now" to make unit testing easier 17 | $.prettyDate.now = function () { 18 | // 2008-01-28 22:25:00.000 UTC 19 | return new Date(1201559100000); 20 | }; 21 | var $main = $('#main a'), 22 | $alt = $('#alternate a'); 23 | 24 | 25 | QUnit.test('Plain', 2, function (assert) { 26 | var expected = [ 27 | 'fallback', 28 | 'just now', 29 | '1 minute ago', 30 | '4 minutes ago', 31 | '2 hours ago', 32 | 'Yesterday', 33 | 'Two days ago', 34 | '4 days ago', 35 | '1 week ago', 36 | '2 weeks ago', 37 | '1 month ago', 38 | '2 months ago', 39 | '1 year ago', 40 | '2 years ago' 41 | ]; 42 | assert.deepEqual( 43 | $.map($main.toArray(), function (el) { 44 | return $.prettyDate.format(el.title) || 'fallback'; 45 | }), 46 | expected, 47 | 'jQuery.prettyDate' 48 | ); 49 | assert.deepEqual( 50 | $.map($main.prettyDate().toArray(), function (el) { 51 | return $(el).text(); 52 | }), 53 | expected, 54 | '.prettyDate()' 55 | ); 56 | }); 57 | 58 | QUnit.test('Local timezone has influence as expected', function (assert) { 59 | $.prettyDate.now = function () { 60 | var fixed = new Date(1201559100000), 61 | local = new Date(); 62 | // Corrupt "now" with local computer timezone 63 | fixed.setTime(fixed.getTime() - (local.getTimezoneOffset() * 60 * 1000)); 64 | return fixed; 65 | }; 66 | var hourOffset = Math.floor(new Date().getTimezoneOffset() / 60); 67 | assert.deepEqual( 68 | $.map($main.eq(4).prettyDate().toArray(), function (el) { 69 | return $(el).text(); 70 | }), 71 | [(2 - hourOffset) + ' hours ago'] 72 | ); 73 | }); 74 | 75 | QUnit.test('messages', function (assert) { 76 | $.prettyDate.messages.hours = $.prettyDate.template('text {0} text'); 77 | $main.eq(4).prettyDate(); 78 | assert.equal($main.eq(4).text(), 'text 2 text'); 79 | }); 80 | 81 | QUnit.test('option "attribute"', function (assert) { 82 | assert.deepEqual( 83 | $.map($alt.prettyDate({ attribute: 'data-mytimestamp' }).toArray(), function (el) { 84 | return $(el).text(); 85 | }), 86 | ['2 hours ago'] 87 | ); 88 | }); 89 | 90 | }(jQuery, QUnit)); 91 | --------------------------------------------------------------------------------