1st attempt to support i18n in dates and times

This commit is contained in:
Kuba Brecka 2013-03-07 20:05:18 +01:00
parent 052887c296
commit 2e76e337a6
7 changed files with 54 additions and 158 deletions

View File

@ -24,6 +24,8 @@
//= require ./discourse/helpers/i18n_helpers
//= require ./discourse
//= require ./locales/date_locales.js
// Stuff we need to load first
//= require_tree ./discourse/mixins
//= require ./discourse/views/view

View File

@ -1,5 +1,3 @@
/*global humaneDate:true */
/**
Breaks up a long string
@ -162,7 +160,7 @@ Handlebars.registerHelper('avatar', function(user, options) {
Handlebars.registerHelper('unboundDate', function(property, options) {
var dt;
dt = new Date(Ember.Handlebars.get(this, property, options));
return dt.format("{d} {Mon}, {yyyy} {hh}:{mm}");
return dt.format("long");
});
/**
@ -176,9 +174,9 @@ Handlebars.registerHelper('editDate', function(property, options) {
dt = Date.create(Ember.Handlebars.get(this, property, options));
yesterday = new Date() - (60 * 60 * 24 * 1000);
if (yesterday > dt.getTime()) {
return dt.format("{d} {Mon}, {yyyy} {hh}:{mm}");
return dt.format("long");
} else {
return humaneDate(dt);
return dt.relative();
}
});
@ -215,7 +213,7 @@ Handlebars.registerHelper('number', function(property, options) {
@for Handlebars
**/
Handlebars.registerHelper('date', function(property, options) {
var displayDate, dt, fiveDaysAgo, fullReadable, humanized, leaveAgo, val;
var displayDate, dt, fiveDaysAgo, oneMinuteAgo, fullReadable, humanized, leaveAgo, val;
if (property.hash) {
if (property.hash.leaveAgo) {
leaveAgo = property.hash.leaveAgo === "true";
@ -229,23 +227,26 @@ Handlebars.registerHelper('date', function(property, options) {
return new Handlebars.SafeString("—");
}
dt = new Date(val);
fullReadable = dt.format("{d} {Mon}, {yyyy} {hh}:{mm}");
fullReadable = dt.format("long");
displayDate = "";
fiveDaysAgo = (new Date()) - 432000000;
if (fiveDaysAgo > (dt.getTime())) {
oneMinuteAgo = (new Date()) - 60000;
if (oneMinuteAgo <= dt.getTime() && dt.getTime() <= (new Date())) {
displayDate = Em.String.i18n("now");
} else if (fiveDaysAgo > (dt.getTime())) {
if ((new Date()).getFullYear() !== dt.getFullYear()) {
displayDate = dt.format("{d} {Mon} '{yy}");
displayDate = dt.format("short");
} else {
displayDate = dt.format("{d} {Mon}");
displayDate = dt.format("short_no_year");
}
} else {
humanized = humaneDate(dt);
humanized = dt.relative();
if (!humanized) {
return "";
}
displayDate = humanized;
if (!leaveAgo) {
displayDate = displayDate.replace(' ago', '');
displayDate = (dt.millisecondsAgo()).duration();
}
}
return new Handlebars.SafeString("<span class='date' title='" + fullReadable + "'>" + displayDate + "</span>");

View File

@ -1,134 +0,0 @@
/*
* Javascript Humane Dates
* Copyright (c) 2008 Dean Landolt (deanlandolt.com)
* Re-write by Zach Leatherman (zachleat.com)
*
* Adopted from the John Resig's pretty.js
* at http://ejohn.org/blog/javascript-pretty-date
* and henrah's proposed modification
* at http://ejohn.org/blog/javascript-pretty-date/#comment-297458
*
* Licensed under the MIT license.
*/
function humaneDate(date, compareTo){
if(!date) {
return;
}
var lang = {
ago: 'ago',
from: '',
now: 'just now',
minute: 'minute',
minutes: 'minutes',
hour: 'hour',
hours: 'hours',
day: 'day',
days: 'days',
week: 'week',
weeks: 'weeks',
month: 'month',
months: 'months',
year: 'year',
years: 'years'
},
formats = [
[60, lang.now],
[3600, lang.minute, lang.minutes, 60], // 60 minutes, 1 minute
[86400, lang.hour, lang.hours, 3600], // 24 hours, 1 hour
[604800, lang.day, lang.days, 86400], // 7 days, 1 day
[2628000, lang.week, lang.weeks, 604800], // ~1 month, 1 week
[31536000, lang.month, lang.months, 2628000], // 1 year, ~1 month
[Infinity, lang.year, lang.years, 31536000] // Infinity, 1 year
],
isString = typeof date == 'string',
date = isString ?
new Date(('' + date).replace(/-/g,"/").replace(/[TZ]/g," ")) :
date,
compareTo = compareTo || new Date,
seconds = (compareTo - date +
(compareTo.getTimezoneOffset() -
// if we received a GMT time from a string, doesn't include time zone bias
// if we got a date object, the time zone is built in, we need to remove it.
(isString ? 0 : date.getTimezoneOffset())
) * 60000
) / 1000,
token;
if(seconds < 0) {
seconds = Math.abs(seconds);
token = lang.from ? ' ' + lang.from : '';
} else {
token = lang.ago ? ' ' + lang.ago : '';
}
/*
* 0 seconds && < 60 seconds Now
* 60 seconds 1 Minute
* > 60 seconds && < 60 minutes X Minutes
* 60 minutes 1 Hour
* > 60 minutes && < 24 hours X Hours
* 24 hours 1 Day
* > 24 hours && < 7 days X Days
* 7 days 1 Week
* > 7 days && < ~ 1 Month X Weeks
* ~ 1 Month 1 Month
* > ~ 1 Month && < 1 Year X Months
* 1 Year 1 Year
* > 1 Year X Years
*
* Single units are +10%. 1 Year shows first at 1 Year + 10%
*/
function normalize(val, single)
{
var margin = 0.1;
if(val >= single && val <= single * (1+margin)) {
return single;
}
return val;
}
for(var i = 0, format = formats[0]; formats[i]; format = formats[++i]) {
if(seconds < format[0]) {
if(i === 0) {
// Now
return format[1];
}
var val = Math.ceil(normalize(seconds, format[3]) / (format[3]));
return val +
' ' +
(val != 1 ? format[2] : format[1]) +
(i > 0 ? token : '');
}
}
};
if(typeof jQuery != 'undefined') {
jQuery.fn.humaneDates = function(options)
{
var settings = jQuery.extend({
'lowercase': false
}, options);
return this.each(function()
{
var $t = jQuery(this),
date = $t.attr('datetime') || $t.attr('title');
date = humaneDate(date);
if(date && settings['lowercase']) {
date = date.toLowerCase();
}
if(date && $t.html() != date) {
// don't modify the dom if we don't have to
$t.html(date);
}
});
};
}

View File

@ -0,0 +1,36 @@
// fix EN locale
Date.getLocale('en').short_no_year = '{d} {Mon}';
// create CS locale
Date.addLocale('cs', {
'plural': true,
'capitalizeUnit': false,
'months': 'ledna,února,března,dubna,května,června,července,srpna,září,října,listopadu,prosince',
'weekdays': 'neděle,pondělí,úterý,středa,čtvrtek,pátek,sobota',
'units': 'milisekund:a|y||ou|ami,sekund:a|y||ou|ami,minut:a|y||ou|ami,hodin:a|y||ou|ami,den|dny|dnů|dnem|dny,týden|týdny|týdnů|týdnem|týdny,měsíc:|e|ů|em|emi,rok|roky|let|rokem|lety',
'short': '{d}. {month} {yyyy}',
'short_no_year': '{d}. {month}',
'long': '{d}. {month} {yyyy} {H}:{mm}',
'full': '{weekday} {d}. {month} {yyyy} {H}:{mm}:{ss}',
'relative': function(num, unit, ms, format) {
var numberWithUnit, last = num.toString().slice(-1);
var mult;
if (format === 'past' || format === 'future') {
if (num === 1) mult = 3;
else mult = 4;
} else {
if (num === 1) mult = 0;
else if (num >= 2 && num <= 4) mult = 1;
else mult = 2;
}
numberWithUnit = num + ' ' + this.units[(mult * 8) + unit];
switch(format) {
case 'duration': return numberWithUnit;
case 'past': return 'před ' + numberWithUnit;
case 'future': return 'za ' + numberWithUnit;
}
}
});
// set the current date locale
Date.setLocale(I18n.locale);

View File

@ -24,6 +24,7 @@ cs:
you: "Vy"
ok: "ok"
or: "nebo"
now: "právě teď"
suggested_topics:
title: "Doporučená témata"

View File

@ -24,6 +24,7 @@ en:
you: "You"
ok: "ok"
or: "or"
now: "just now"
suggested_topics:
title: "Suggested Topics"

View File

@ -3,18 +3,7 @@ module AgeWords
def self.age_words(secs)
return "&mdash;" if secs.blank?
mins = (secs / 60.0)
hours = (mins / 60.0)
days = (hours / 24.0)
months = (days / 30.0)
years = (months / 12.0)
return "#{years.floor}y" if years > 1
return "#{months.floor}mo" if months > 1
return "#{days.floor}d" if days > 1
return "#{hours.floor}h" if hours > 1
return "&lt; 1m" if mins < 1
return "#{mins.floor}m"
return FreedomPatches::Rails4.distance_of_time_in_words(Time.now, Time.now + secs)
end
end