【问题标题】:Converting UTC to Decimal time将 UTC 转换为十进制时间
【发布时间】:2017-04-18 14:45:58
【问题描述】:

背景

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

这涉及将 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 => 10-10-2016
  • 时间 - 22:47:52 => 18:98:43

问题

  1. 数学正确吗?
  2. 时区有问题吗?我有 尝试将所有 Date 对象转换为 UTC 但 JavaScript 可以 棘手
  3. 我可以改进代码吗?月份选择似乎是这样 可以改进,但我想不出更好的方法来数 36 和 37 天的月份。 if (num % 36.5 === 1) 不起作用?

谢谢!

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

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

【问题讨论】:

  • Are there any issues with timezones? i've tried converting all Date objects to UTC but JavaScript can be tricky.. 时区并不比偏移更复杂,所以我个人会保留这些函数的 UTC 位。
  • 所有日期对象都是 UTC。时区偏移量来自主机,非 UTC 方法使用该偏移量来计算“本地”值。如果您使用所有 UTC 方法,那么您将获得 UTC 值并且不使用时区偏移量。
  • 好点,我有一些不必要的代码将 UTC 转换为 UTC :)

标签: javascript date datetime calendar timezone


【解决方案1】:

数学正确吗?

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

以下内容:

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

似乎不正确。你的意思是:

  • 1 天 = 20 个小数小时
  • 1 个十进制小时 = 100 个十进制分钟
  • 十进制的 1 分钟 = 十进制的 100 秒
  • 1 十进制秒 = 1000 十进制毫秒

您以毫秒为单位获取时间并缩放为十进制毫秒的策略似乎很好,我将只制作以下 cmets。

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)

将为上一年的 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));

【讨论】:

猜你喜欢
  • 2021-07-22
  • 2016-05-09
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 2014-03-13
  • 2018-01-24
  • 1970-01-01
相关资源
最近更新 更多