首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >as3十六进制值到时间戳的转换从十六进制到MS: 32位十六进制值十进制

as3十六进制值到时间戳的转换从十六进制到MS: 32位十六进制值十进制
EN

Stack Overflow用户
提问于 2014-07-29 18:08:44
回答 1查看 2.7K关注 0票数 1

我试图了解如何将MS: 32位格式中的十六进制值转换/解码为人类可读的日期和时间。我已经找到了一种方法,用Unix时间戳/纪元来实现到正常日期,但对于我的十六进制值(MS: 32位格式)却不起作用。有人有什么想法吗?

代码语言:javascript
复制
var hex = "38BFFD44";
var decimal = parseInt (hex, 16);
var date = new Date(decimal*1000);
trace(date);

哪一项应产出:

代码语言:javascript
复制
Tue Jul 29 23:57:48 GMT+0000 2014

而是输出日期:

代码语言:javascript
复制
Fri Mar 3 17:58:28 GMT+0000 2000

我已经尝试添加补偿的秒的偏移到日期,但这是行不通的,它最终提出了不正确的时间和增加的日子。我确信这与十进制转换有关?

代码语言:javascript
复制
date.seconds += 1402677061;

我一直在阅读更多关于MS:DOS 32位转换的文章,并在"EnCase计算机取证--官方EnCE: EnCase认证审查员“-中找到了这段内容。

“要正确组合和计算此值,必须按以下顺序将十六进制值输入到科学计算器中:00120003。这将存储的值转换为小endian.。由此开始的集群世界的最终十进制值为1,179,651。”

所以我做了一个脚本来复制这个,但似乎仍然不起作用。

代码语言:javascript
复制
function toDec(n:*, endianness: * = null): String {

    var bigEndian: Boolean;
    if (endianness == null) {
        endianness = Endian.BIG_ENDIAN;
    }
    if (endianness is Boolean) {
        bigEndian = Boolean(endianness);
    } else {
        bigEndian = endianness == Endian.BIG_ENDIAN;
    }

    var string: String = n.toUpperCase();

    if (!bigEndian) {
        var i: int = 0;
        var reversed: Array = [];
        while (i < string.length) {
            var byte: String = string.charAt(i++) + string.charAt(i++);
            reversed.unshift(byte);
        }
        string = reversed.join("");
    }

    return string;
}

var hex = "38BFFD44";
var sdecimal = parseInt(toDec(hex,Endian.LITTLE_ENDIAN), 16);
var sdate = new Date(sdecimal);    

var bdecimal = parseInt(toDec(hex,Endian.BIG_ENDIAN), 16);
var bdate = new Date(bdecimal);

trace("small_endian.decimal = "+sdecimal);
trace("big_endian.decimal   = "+bdecimal);
trace("small_endian.date    = "+sdate);
trace("big_endian.date      = "+bdate);

输出:

代码语言:javascript
复制
small_endian.decimal = 1157480248
big_endian.decimal   = 952106308
small_endian.date    = Wed Jan 14 09:31:20 GMT+0000 1970
big_endian.date      = Mon Jan 12 00:28:26 GMT+0000 1970
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-07-30 06:52:08

在MS-DOS中,时间戳的每一部分都被编码在32位时间戳的特定位内.

这是一个exFAT时间戳:

代码语言:javascript
复制
╔═══════╦══════╦═════════════════════════════╦══════════════════════════════════╗
║ Bits  ║ Size ║         Description         ║             Comments             ║
╠═══════╬══════╬═════════════════════════════╬══════════════════════════════════╣
║ 0-4   ║    5 ║ Seconds (2-second interval) ║ 0..29 (29 represents 58 seconds) ║
║ 5-10  ║    6 ║ Minutes                     ║ 0..59                            ║
║ 11-15 ║    5 ║ Hour                        ║ 0..23                            ║
║ 16-20 ║    5 ║ Day                         ║ 1..31                            ║
║ 21-24 ║    4 ║ Month                       ║ 1..12                            ║
║ 25-31 ║    7 ║ Year (as offset from 1980)  ║ 0 represents 1980                ║
╚═══════╩══════╩═════════════════════════════╩══════════════════════════════════╝

这是一个由两个单词组成的结构(每个单词是一个16位的无符号整数)- FatDate和FatTime,如DosDateTimeToFileTime中所示。

代码语言:javascript
复制
BOOL WINAPI DosDateTimeToFileTime(
  _In_   WORD wFatDate,
  _In_   WORD wFatTime,
  _Out_  LPFILETIME lpFileTime
);

将这个十六进制值解析为一个ActionScript date作为时间戳,因为时代是行不通的。

此外,还有一个令人着迷的问题。这个值必须是小endian。

将0x38BFFD44从大端(952106308)转换为小endian (1157480248)产生了预期的输出。

在ActionScript中,这应该是:

代码语言:javascript
复制
var t:uint = 1157480248; // 0x38BFFD44 as little endian;

var date:Date = new Date(
    1980 + ((t & 0xfe000000) >> 25), // year
    ((t & 0x1e00000) >> 21) - 1,     // month
    ((t & 0x1f0000) >> 16),          // day
    ((t & 0xf800) >> 11),            // hour
    ((t & 0x7e0) >> 5),              // minute
    2 * (t & 0x1f)                   // second
    );

产出:

2014年7月29日23:57:48格林尼治时间-0500

您将不得不考虑时区偏移的UTC。

参考文献:

  • 如何将时间戳转换为实际的DateTime?
  • MS-DOS日期和时间格式
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25022124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档