将UTC转换为十进制时间

时间:2016-12-03 22:54:15

标签: javascript date datetime calendar timezone

背景

我想基于旧的法语版本创建一个新的日期/时间系统,并进行一些修改。

这涉及将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 = month)组成日/月名称

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

问题

  1. 数学是否正确?
  2. 时区有什么问题吗?我'已经 尝试将所有Date对象转换为UTC但JavaScript可以 棘手的
  3. 我可以改进代码吗?月份选择似乎是这样 可以改进,但我无法找到更好的方法来计算36 和37个月。如果(num%36.5 === 1)不起作用?
  4. 谢谢!

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

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

1 个答案:

答案 0 :(得分:1)

  

数学是否正确?

您没有说哪个月有35天,哪些有36天,所以我们必须接受 if 语句是否正确。您不会显示 date 的创建方式,因此可能会或可能不会。而且你不会说闰年会发生什么,这个系统似乎每年只有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;

所以1标准毫秒= 2.314814814814815十进制毫秒

在日期函数中,表达式为:

new Date(date.getUTCFullYear(), 0, 0)
如果您在1月1日之后再<=>
new Date(date.getUTCFullYear(), 0, 1);

很可能你有一天出去了。否则,代码似乎是正确的。对我来说,获取十进制时间函数将更简单:

&#13;
&#13;
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));
&#13;
&#13;
&#13;