PHP:将C#64位时间戳转换为Unix时间戳

时间:2012-05-15 08:08:37

标签: c# php

我正在将一个C#函数复制到PHP。在C#中,GUID,DateTime和boolean被转换为字节。接下来,字节数组被合并和编码。最后一步是将其转换为base64。

以下部分存在字节数组:

GUID: 16 bytes
Timestamp: 8 bytes
Boolean: 1 byte

在php中,我已经转换了base64并将字符串解码回字节。我还设法将前16个字节转换为GUID。我验证了PHP返回的字节,它们是正确的。

现在我将8个字节转换为PHP中的时间戳。到目前为止我没有运气。我想问题是它返回一个int64。

C#

这是到datetime转换的C#字节数组:

public DateTime Timestamp;
......
byte[] timestamp_bytes = new byte[8];
input.Read(timestamp_bytes, 0, 8);
Timestamp = DateTime.FromBinary(System.BitConverter.ToInt64(timestamp_bytes, 0));

这是C#datetime到字节数组的转换:

public DateTime Timestamp;
......
byte[] timestamp_bytes = System.BitConverter.GetBytes(Timestamp.ToBinary());

当我输出Timestamp.ToString()时,我会在两种情况下得到 23-12-2011 09:54:56

PHP

在PHP中,我设法获得了8字节的十六进制:

$bin = pack("C*", 119, 23, 124, 173, 103, 143, 206, 136);
$hex = unpack("H*", $bin);

接下来我该怎么办?我已经尝试了一些转换方法,但我似乎从来没有得到正确的答案。

其他信息:

8个字节是:119,23,124,173,103,143,206,136

hexstring是:77177cad678fce88

我应该得到的日期时间:23-12-2011 09:54:56

php -r'echo PHP_INT_MAX;'返回9223372036854775807

C#应用程序不在我的权限范围内,所以我不能保证我可以改变它

3 个答案:

答案 0 :(得分:0)

我们来看看DateTime.ToBinary MethodDateTime.Ticks Property文档。

首先, DateTime 的二进制形式表示两个属性(Kind和Ticks),并且不清楚它们是如何在二进制字符串中连接的。然后, Ticks 属性是自耶稣基督诞生以来 一百万分之一秒 的数量

那么,如何进行?

  1. 尝试了解 Kind Ticks 属性是如何二进制存储的。我们需要 Ticks 。我的建议是尝试将一些典型的DateTime值转换为二进制并分析输出。从 DateTime.MinValue 开始,该对应于01-01-0001 00:00:00。您应该看到(我认为)全部为零,除了种类值(如果存在)。

  2. 获得64位 Ticks 值后,您可以使用floor($ticks / 10000000)获得秒数。最后你必须减去从第1年到1970年经过的秒数(Unix标准),这是一个常数,你可以将C#DateTime 01-01-1970 00:00:00转换成二进制......

  3. 祝你好运。

答案 1 :(得分:0)

为此,您需要在C#中转换为unix时间戳,并将此数据打包为二进制而不是8字节的DateTime对象序列化。到2038年,4个字节就足够了。

here借用(或窃取?),这是你在C#中创建Unix时间戳的方法:

public DateTime timestamp;
// ......
byte[] timestamp_bytes = new byte[8];
input.Read(timestamp_bytes, 0, 8);
timestamp = DateTime.FromBinary(System.BitConverter.ToInt64(timestamp_bytes, 0));

TimeSpan diff = (Timestamp - new DateTime(1970, 1, 1).toLocalTime());
int unix = (int) diff.TotalSeconds;
// unix is now a signed 32 bit integer representing the Unix timestamp in a way
// that PHP will understand

然后在PHP中,您可以将4个二进制字节转换回表示unix时间戳的整数,如下所示:

$timestamp = unpack('N', $binaryString);
echo date('d-m-Y H:i:s', $timestamp); // Should give 23-12-2011 09:54:56

答案 2 :(得分:0)

我最终得到了这个,解密后就解密了这个字符串。

        $byte_array = array_slice(unpack("C*", "\0" . $decrypted), 1);

        $timestamp_array = array_slice($byte_array, 0, 8);
        $guid_array = array_slice($byte_array, 8, 16);
        $is_read_only_array = array_slice($byte_array, 24, 1);

        // CONVERT GUID
        .....

        // CONVERT TIMESTAMP
        $timestamp_hex = "";
        foreach ($timestamp_array as $byte) {
            $timestamp_hex .= pack("C*", $byte);
        }
        $timestamp = hexdec($timestamp_hex);

        // CONVERT IS READ ONLY
        ....