Ruby 到 Javascript => 令人头疼的日期计算
Ruby to Javascript => Date calculation headaches
我正在尝试将以下 Ruby 片段重写为 JavaScript,但输出不是我所期望的。
这是原Ruby代码:
require 'date'
moment = DateTime.new(2014, 9, 27, 0, 0, 0, DateTime.now.offset)
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]]
elapsed = DateTime.now - moment
tense = elapsed > 0 ? 'since' : 'until'
interval = 1.0
parts = intervals.collect do |name, new_interval|
interval /= new_interval
number, elapsed = elapsed.abs.divmod(interval)
"#{number.to_i} #{name}#{'s' unless number == 1}"
end
puts "#{parts.join(', ')} #{tense} that moment."
这将输出类似 "x days, x hours, x seconds since that moment."
的内容
我目前的 JavaScript 代码是:
// Input: Nov 18 19:01:41 2014 MST
var since = function(date) {
var elapsed, interval, intervals, parts, tense;
date = Date.parse(date);
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]];
elapsed = (new Date).getTime() - date;
tense = elapsed > 0 ? 'since' : 'until';
interval = 1.0;
parts = intervals.map(function(item) {
var number;
interval /= item[1];
number = elapsed % interval;
elapsed = Math.floor(elapsed / interval);
return number + " " + item[0] + (number !== 1 ? 's' : void 0);
});
return console.log(parts.join(', ') + " " + tense);
};
然而,这不是预期的输出,给了我一些完全荒谬的东西:
0 days, 2.187114859220074e-7 hours, 0.000011154285782022377 minutes, 0.0000022063280195997896 seconds since that moment.
我试过 elapsed /= 1000
,但输出仍然不是预期的结果。
请参阅下面代码中的注释以进行修复:
var since = function(date) {
var elapsed, interval, intervals, parts, tense;
date = Date.parse(date);
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]];
elapsed = (new Date).getTime() - date;
// "elapsed" is in milliseconds when it was in days (Rational) in the
// Ruby version. Fix:
elapsed = elapsed / 1000 / 3600 / 24;
tense = elapsed > 0 ? 'since' : 'until';
interval = 1.0;
parts = intervals.map(function(item) {
var number;
interval /= item[1];
// You mixed "number" with "elapsed", and calculated them in
// the wrong order. Fix:
number = Math.floor(elapsed / interval);
elapsed = elapsed % interval;
return number + " " + item[0] + (number !== 1 ? 's' : '');
});
return console.log(parts.join(', ') + " " + tense);
};
since('Sep 27 19:01:41 2014 MST');
97 days, 15 hours, 33 minutes, 21 seconds since
我正在尝试将以下 Ruby 片段重写为 JavaScript,但输出不是我所期望的。
这是原Ruby代码:
require 'date'
moment = DateTime.new(2014, 9, 27, 0, 0, 0, DateTime.now.offset)
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]]
elapsed = DateTime.now - moment
tense = elapsed > 0 ? 'since' : 'until'
interval = 1.0
parts = intervals.collect do |name, new_interval|
interval /= new_interval
number, elapsed = elapsed.abs.divmod(interval)
"#{number.to_i} #{name}#{'s' unless number == 1}"
end
puts "#{parts.join(', ')} #{tense} that moment."
这将输出类似 "x days, x hours, x seconds since that moment."
的内容我目前的 JavaScript 代码是:
// Input: Nov 18 19:01:41 2014 MST
var since = function(date) {
var elapsed, interval, intervals, parts, tense;
date = Date.parse(date);
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]];
elapsed = (new Date).getTime() - date;
tense = elapsed > 0 ? 'since' : 'until';
interval = 1.0;
parts = intervals.map(function(item) {
var number;
interval /= item[1];
number = elapsed % interval;
elapsed = Math.floor(elapsed / interval);
return number + " " + item[0] + (number !== 1 ? 's' : void 0);
});
return console.log(parts.join(', ') + " " + tense);
};
然而,这不是预期的输出,给了我一些完全荒谬的东西:
0 days, 2.187114859220074e-7 hours, 0.000011154285782022377 minutes, 0.0000022063280195997896 seconds since that moment.
我试过 elapsed /= 1000
,但输出仍然不是预期的结果。
请参阅下面代码中的注释以进行修复:
var since = function(date) {
var elapsed, interval, intervals, parts, tense;
date = Date.parse(date);
intervals = [['day', 1], ['hour', 24], ['minute', 60], ['second', 60]];
elapsed = (new Date).getTime() - date;
// "elapsed" is in milliseconds when it was in days (Rational) in the
// Ruby version. Fix:
elapsed = elapsed / 1000 / 3600 / 24;
tense = elapsed > 0 ? 'since' : 'until';
interval = 1.0;
parts = intervals.map(function(item) {
var number;
interval /= item[1];
// You mixed "number" with "elapsed", and calculated them in
// the wrong order. Fix:
number = Math.floor(elapsed / interval);
elapsed = elapsed % interval;
return number + " " + item[0] + (number !== 1 ? 's' : '');
});
return console.log(parts.join(', ') + " " + tense);
};
since('Sep 27 19:01:41 2014 MST');
97 days, 15 hours, 33 minutes, 21 seconds since