mirror of
https://github.com/discourse/discourse.git
synced 2024-11-23 03:59:50 +08:00
1st attempt to support i18n in dates and times
This commit is contained in:
parent
052887c296
commit
2e76e337a6
|
@ -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
|
||||
|
|
|
@ -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>");
|
||||
|
|
134
app/assets/javascripts/external/humane.js
vendored
134
app/assets/javascripts/external/humane.js
vendored
|
@ -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);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
36
app/assets/javascripts/locales/date_locales.js
Normal file
36
app/assets/javascripts/locales/date_locales.js
Normal 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);
|
|
@ -24,6 +24,7 @@ cs:
|
|||
you: "Vy"
|
||||
ok: "ok"
|
||||
or: "nebo"
|
||||
now: "právě teď"
|
||||
|
||||
suggested_topics:
|
||||
title: "Doporučená témata"
|
||||
|
|
|
@ -24,6 +24,7 @@ en:
|
|||
you: "You"
|
||||
ok: "ok"
|
||||
or: "or"
|
||||
now: "just now"
|
||||
|
||||
suggested_topics:
|
||||
title: "Suggested Topics"
|
||||
|
|
|
@ -3,18 +3,7 @@ module AgeWords
|
|||
def self.age_words(secs)
|
||||
return "—" 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 "< 1m" if mins < 1
|
||||
return "#{mins.floor}m"
|
||||
return FreedomPatches::Rails4.distance_of_time_in_words(Time.now, Time.now + secs)
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user