将UTC转换为十进制时间



背景

我想根据具有一些修改的旧法语版本创建一个新的日期/时间系统。

这涉及将UTC日期/时间转换为新数量:

  • 12个月=> 10个月
  • 52周=> 36.5周
  • 每月28/31天=>每月36/37天
  • 24小时=> 20小时
  • 60分钟=> 100分钟
  • 60秒=> 100秒

我已经在JavaScript中编码了一个时钟作为概念证明,但不确定我是否正确计算了所有内容,此外,这是否是最好的方法:

代码

1)getDecimaldate()计算一年中的一天,然后在每月36或37天的新日历内进行哪个月。然后计算本月的新日期。

function getDecimalDate(date) {
    var oldDay = 1000 * 60 * 60 * 24,
        startYear = new Date(Date.UTC(date.getUTCFullYear(), 0, 0)),
        day = Math.floor((date - startYear) / oldDay),
        num = 0,
        month = 1;
    if (day > 36) { num += 36; month = 2; }
    if (day > 73) { num += 37; month = 3; }
    if (day > 109) { num += 36; month = 4; }
    if (day > 146) { num += 37; month = 5; }
    if (day > 182) { num += 36; month = 6; }
    if (day > 219) { num += 37; month = 7; }
    if (day > 255) { num += 36; month = 8; }
    if (day > 292) { num += 37; month = 9; }
    if (day > 328) { num += 36; month = 10; }
    return { day: day - num, month: month, year: date.getUTCFullYear(), num: num };
}

2)getDecimaltime()计算自午夜以来毫秒的数量,然后将其从每天的旧毫秒更改为新总数,然后计算小时,分钟等

function getDecimalTime(date) {
    var oldDay = 1000 * 60 * 60 * 24,
        newDay = 1000 * 100 * 100 * 20,
        startDay = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())),
        delta = ((date - startDay) / oldDay) * newDay;
    var hours = Math.floor(delta / 10000000) % 20;
    delta -= hours * 10000000;
    var minutes = Math.floor(delta / 100000) % 100;
    delta -= minutes * 100000;
    var seconds = Math.floor(delta / 1000) % 100;
    delta -= seconds * 1000;
    var milliseconds = Math.floor(delta) % 1000;
    return { milliseconds: milliseconds, seconds: seconds, minutes: minutes, hours: hours };
}

您可以在此处看到一个工作版本:https://jsfiddle.net/kmturley/7mrwc3x3/9/

结果

请记住,我使用拉丁语(Nov = 9,die = Day,Dec = 10,mense = noter = noter)

  • 字符串 - 12月3日星期六=> Novdie Decmense 10
  • 日期-03-12-2016 => 10-10-2016
  • 时间-22:47:52 => 18:98:43

问题

  1. 数学正确吗?
  2. 时区有任何问题吗?我有尝试将所有日期对象转换为UTC,但JavaScript可以是棘手
  3. 我可以改进代码吗?一个月的选择似乎是这样可以改进,但我找不到更好的计数方法和37天。如果(num%36.5 === 1)无法使用?

谢谢!

更新 - 2016年12月7日 - 基于解决方案的新版本:https://jsfiddle.net/kmturley/7mrwc3x3/10/

https://github.com/kmturley/decimal time

数学正确吗?

您没有说哪个月有35天,哪个月有36天,因此我们必须接受如果语句正确。您不会显示如何创建 date ,因此它可能还可以,也可能不正确。而且您不会说LEAP年会发生什么,该系统似乎每年只有365天。

以下内容:

  • 24小时=> 20小时
  • 60分钟=> 100分钟
  • 60秒=> 100秒

似乎不正确。您实际上是说:

  • 1天= 20小时
  • 1个小时= 100分钟
  • 1小数分钟= 100个小数秒
  • 1个小数秒= 1000小数毫秒

您将时间限制在MS上并扩展到十进制MS的策略看起来不错,我只会发表以下评论。

getDecimaltime 中,通过首先复制 date ,然后将其UTC小时设置为零,可以简单地计算 startday

startDay = new Date(+date);
startDate.setUTCHours(0,0,0,0);

然后扩展:

var diffMilliseconds = date - startDate;
var decimalMilliseconds = diffMilliseconds / 8.64e7 * 2.0e8;

SO 1标准毫秒= 2.314814814814815小数毫秒

日期函数,表达式:

new Date(date.getUTCFullYear(), 0, 0)

将创建上一年12月31日(即0日期)的日期,如果您是1月1日之后,则应该是:

new Date(date.getUTCFullYear(), 0, 1);

很可能有一天。否则,代码似乎是正确的。对我来说,获得小数时间函数将更简单,为:

function getDecimalTime(date) {
  // Pad numbers < 10
  function z(n){return (n<10?'0':'')+n;}
  // Copy date so don't modify original
  var dayStart = new Date(+date);
  var diffMs = date - dayStart.setUTCHours(0,0,0,0);
  
  // Scale to decimal milliseconds
  var decMs = Math.round(diffMs / 8.64e7 * 2.0e8);
  
  // Get decimal hours, etc.
  var decHr  = decMs / 1.0e7 | 0;
  var decMin = decMs % 1.0e7 / 1.0e5 | 0;
  var decSec = decMs % 1.0e5 / 1.0e3 | 0;
  decMs      = decMs % 1.0e3;
  return z(decHr) + ':' + z(decMin) + ':' + z(decSec) + '.' + ('0' + z(decMs)).slice(-3);
}
// Helper to format the time part of date
// as UTC hh:mm:ss.sss
function formatUTCTime(date) {
  function z(n){return (n<10?'0':'')+n;}
  return z(date.getUTCHours()) + ':' + 
         z(date.getUTCMinutes()) + ':' + 
         z(date.getUTCSeconds()) + '.' + 
         ('00' + date.getUTCMilliseconds()).slice(-3);
}
// Test 00:00:00.003 => 00:00:00.007
// i.e. 3ms * 2.31decms => 6.93decms
var d = new Date(Date.UTC(2016,0,1,0,0,0,3));
console.log(getDecimalTime(d));
// Test 12:00:00.000 => 10:00:00.000
// i.e. noon to decimal noon
var d = new Date(Date.UTC(2016,0,1,12,0,0,0));
console.log(getDecimalTime(d));
// Test current time
d = new Date();
console.log(formatUTCTime(d));
console.log(getDecimalTime(d));

最新更新