Javascript 相对时间
因为相对时间是随时变化的,所以如果在页面里面直接生成相对时间的文本,那么就没法缓存成静态文件,不过用 js 可以解决这个问题。
首先,在页面里面还是用 rails 生成一般的时间,这样即使关掉了 js,也可以显示正常的时间。并套个 span:
然后就是 js 的事情了,找出这些 span,并且算出相对时间替换进去:
其中的 relative_time_text 接收分钟为参数,返回相对时间的文本:
var text;
if(!rtlang[local])
local = 'en';
if(m <= 1)
text = rtlang[local]['less than a minute'];
else if(m > 1 && m <= 45)
text = m + rtlang[local][' minutes'];
else if(m > 45 && m <= 90)
text = rtlang[local]['about 1 hour'];
else if(m > 90 && m <= 1440)
text = Math.round(m/60) + rtlang[local][' hour'];
else if(m > 1440 && m <= 2880)
text = rtlang[local]['1 day'];
else if(m > 2880 && m <= 43200)
text = Math.round(m/1440)+ rtlang[local][' days'];
else if(m > 43200 && m <= 86400)
text = rtlang[local]['about 1 month'];
else if(m > 86400 && m <= 525600)
text = Math.round(m/43200) + rtlang[local][' months'];
else if(m > 525600 && m <= 1051200)
text = rtlang[local]['about 1 year'];
else
text = Math.round(m/525600) + rtlang[local][' years'];
return text + rtlang[local][' ago'];
}
基本就是照着 rails 里那函数改的,rtlang 就是个 hash,保存多语言信息:
rtlang['en']['less than a minute'] = 'less than a minute';
rtlang['en'][' minutes'] = ' minutes';
rtlang['en']['about 1 hour'] = 'about 1 hour';
rtlang['en'][' hour'] = ' hour';
rtlang['en']['1 day'] = '1 day';
rtlang['en'][' days'] = ' days';
rtlang['en']['about 1 month'] = 'about 1 month';
rtlang['en'][' months'] = ' months';
rtlang['en']['about 1 year'] = 'about 1 year';
rtlang['en'][' years'] = ' years';
rtlang['en'][' ago'] = ' ago';
rtlang['zh_CN']['less than a minute'] = '小于一分钟';
rtlang['zh_CN'][' minutes'] = ' 分钟';
rtlang['zh_CN']['about 1 hour'] = '大约 1 小时';
rtlang['zh_CN'][' hour'] = ' 小时';
rtlang['zh_CN']['1 day'] = '1 天';
rtlang['zh_CN'][' days'] = ' 天';
rtlang['zh_CN']['about 1 month'] = '大约 1 个月';
rtlang['zh_CN'][' months'] = ' 个月';
rtlang['zh_CN']['about 1 year'] = '大约 1 年';
rtlang['zh_CN'][' years'] = ' 年';
rtlang['zh_CN'][' ago'] = ' 前';
这样如果要显示中文的相对时间,那么只需在页面尾部加上:
就搞定了~
中文相对时间
不知道啥时候开始,流行用相对时间来表示当前的日期,这种方法确实是不错,同 “2007 年 1 月 24 日” 相比,“1 天前” 这种表示确实看起来舒服多了,毕竟人们在思考时间的时候,大多数也是以当前的时间作为基点。
如果是个是个人气很旺的论坛之类,还可以看到某回复发表于 “n 分钟前” 这样的效果,顿时感觉人气和交互度高了很多。
Rails已经内置了对相对时间的支持,time_ago_in_words 这个 helper 就是干这个用的,比如要显示文章发表的相对时间:
这样就会显示为诸如 “post at 5 days ago” 这样的效果了~
只不过是英文的,要显示中文的就要翻译一下了,开始我想,把 time_ago_in_words 返回结果中的 days 替换成“天”、month 替换成“月”之类,后来去看了下源码,发现源码很短,重新写一个就行了。
time_ago_in_words 实际上是调用的 distance_of_time_in_words 这个函数,并且以 Time.now 作为第二个参数而已:
distance_of_time_in_words(from_time, Time.now, include_seconds)
end
这样的话,我们把 distance_of_time_in_words 中的英文改成中文就 ok 了:
-
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
-
from_time = from_time.to_time if from_time.respond_to?(:to_time)
-
to_time = to_time.to_time if to_time.respond_to?(:to_time)
-
distance_in_minutes = (((to_time - from_time).abs)/60).round
-
distance_in_seconds = ((to_time - from_time).abs).round
-
-
case distance_in_minutes
-
when 0..1
-
return (distance_in_minutes == 0) ? '不到 1 分钟' : '1 分钟' unless include_seconds
-
case distance_in_seconds
-
when 0..4 then '不到 5 秒'
-
when 5..9 then '不到 10 秒'
-
when 10..19 then '不到 20 秒'
-
when 20..39 then '半分钟'
-
when 40..59 then '不到 1 分钟'
-
else '1 分钟'
-
end
-
-
when 2..44 then "#{distance_in_minutes} 分钟"
-
when 45..89 then '大约 1 小时'
-
when 90..1439 then "大约 #{(distance_in_minutes.to_f / 60.0).round} 小时"
-
when 1440..2879 then '1 天'
-
when 2880..43199 then "#{(distance_in_minutes / 1440).round} 天"
-
when 43200..86399 then '大约 1 个月'
-
when 86400..525599 then "#{(distance_in_minutes / 43200).round} 个月"
-
when 525600..1051199 then '大约 1 年'
-
else "#{(distance_in_minutes / 525600).round} 年"
-
end
-
end
把上面的代码加到 application_helper.rb 中去,就可以看到中文的相对时间了~ 当然你也可以去掉 “大约” 这个繁琐的词,或者随便改成自己喜欢的中文表达方式~
过两天就做 Chito 的相对时间插件~