.NET Framework中的DateTime类型的二进制表示和JavaScript中的Date类型互转

.NET Framework中的DateTime类型的二进制表示和JavaScript中的Date类型互转

在.NET Framework中,DateTime类型是表示日期和时间值的结构体。它可以存储从公元1年1月1日到公元9999年12月31日之间的日期和时间。

而在JavaScript中,Date类型也是表示日期和时间值的对象。它可以存储从1970年1月1日 00:00:00 UTC到某个日期时间点之间的毫秒数。

在实际开发中,我们可能需要将.NET Framework中的DateTime类型的值转换为JavaScript中的Date类型的值,或者将JavaScript中的Date类型的值转换为.NET Framework中的DateTime类型的值。这个过程中,需要用到二进制表示的转换方法。

.NET Framework中的DateTime类型的二进制表示

在.NET Framework中,DateTime类型的值其实是一个64位整数,其中01-62位表示自公元1年1月1日0时0分0秒以来经过的100纳秒数,后63-64位则标识时间类型枚举。其中01(bit64 bit63),标识UTC时间。

        // The data is stored as an unsigned 64-bit integer
        //   Bits 01-62: The value of 100-nanosecond ticks where 0 represents 1/1/0001 12:00am, up until the value
        //               12/31/9999 23:59:59.9999999
        //   Bits 63-64: A four-state value that describes the DateTimeKind value of the date time, with a 2nd
        //               value for the rare case where the date time is local, but is in an overlapped daylight
        //               savings time hour and it is in daylight savings time. This allows distinction of these
        //               otherwise ambiguous local times and prevents data loss when round tripping from Local to
        //               UTC time.
        private readonly ulong _dateData;
        
        public long ToBinary()
        {
            if ((_dateData & KindLocal) != 0)
            {
                // Local times need to be adjusted as you move from one time zone to another,
                // just as they are when serializing in text. As such the format for local times
                // changes to store the ticks of the UTC time, but with flags that look like a
                // local date.

                // To match serialization in text we need to be able to handle cases where
                // the UTC value would be out of range. Unused parts of the ticks range are
                // used for this, so that values just past max value are stored just past the
                // end of the maximum range, and values just below minimum value are stored
                // at the end of the ticks area, just below 2^62.
                TimeSpan offset = TimeZoneInfo.GetLocalUtcOffset(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
                long ticks = Ticks;
                long storedTicks = ticks - offset.Ticks;
                if (storedTicks < 0)
                {
                    storedTicks = TicksCeiling + storedTicks;
                }
                return storedTicks | (unchecked((long)KindLocal));
            }
            else
            {
                return (long)_dateData;
            }
        }

具体地,我们可以使用以下代码获取任意一个DateTime类型的值的二进制表示:

DateTime dateTime = DateTime.Now;
//转换二进制表示
var bin = dateTime.ToBinary();
//二进制标识转换为DateTime
var dateTime = System.DateTime.FromBinary(5249903872152447175);

JavaScript中的Date类型的二进制表示

JavaScript中的Date类型的值是一个64位浮点数,其中前53位表示毫秒数,后11位表示毫秒数的小数部分。

二进制表示的互转

将.NET Framework中的DateTime类型的二进制表示转换为JavaScript中的Date类型的值,我们需要先将前62位和后2位分离出来,再按照指定格式进行拼接。需要注意的是具体地,我们可以使用以下代码实现:

function fromDateTimeBinary(value) {
    var UNIX_EPOCH = 62135596800000n;
    //注意使用BigInt
    //去掉63 64位,将时间默认为UTC
    value = (BigInt(value) & 0x3fffffffffffffffn) // value & 0x3fffffffffffffff;
    value = value / 10000n;
    value = Number(value - UNIX_EPOCH)
    return new Date(Number(value)); 
}

function toDateTimeBinary(date) {
  var ticks = (BigInt(date.getTime()) * 10000n) + 621355968000000000n;
  //将标志位置为UTC时间
  ticks = (BigInt(ticks) | 0x4000000000000000n)
  //注意返回的是个BigInt
  return ticks;
}

//测试
console.log(fromDateTimeBinary(5249898290583602010));
console.log(toDateTimeBinary(new Date()));

//标准输出:
//2023-06-01T14:40:15.621Z
//5249903898125757904n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值