Greetings
Im working on a project that involves reading a file generated on another platform (OpenVMS running on Itanium). The file stores a date in a Quadword, according to the file documentation I have. The file spec docs do not specify the date format, but I did find documentation for how OpenVMS stores dates... the number of 100 nanosecond ticks since 00:00 November 17, 1858 in a Quadword. So I am making the assumption that the application that produces the file will also use the same storage method.
Any suggestions how I could turn this 8 byte string into a usable number? I have tried unpack, but there are no formats for a 64bit number.
To add insult to injury, my windows 64bit version of php seems to not be able to use 64 ints according to PHP_INT_MAX and PHP_INT_SIZE contstants.
Thanks!
PS: one of the dates in question is: 80 42 8D 73 2C F7 A9 00, straight out of a hex editor. Ive tried the conversion manually, but I am not sure if I did the conversion correctly... as the numbers I came up with wouldnt give anywhere near a current date.
php and reading a quadword
Moderator: General Moderators
Re: php and reading a quadword
Open VMS on an Itanium processor uses little-endian 64 bit integers. In other words the first byte is the low-order byte. This is the same order as IA32 processors running Windows. The internal type that PHP uses to store integer values is platform dependent, although it is at least a 32 bit signed value. But there are few, if any PHP platforms that support an internal type that can represent a 64 bit unsigned value, such as the VMS time you describe. Therefore for portability you will have to use a Gnu Multiple Precision (GMP) value to hold the time.
I haven't tested the following but I think it should work. Assuming that the quadword is in a string $qw:
$lo = ord($qw[0]) + 256*(ord($qw[1]) + 256*(ord($qw[2]) + 256*ord($qw[3])));
$hi = ord($qw[4]) + 256*(ord($qw[5]) + 256*(ord($qw[6]) + 256*ord($qw[7])));
$tm = gmp_add($lo , gmp_mul(256*256*256*256, $hi));
Based upon the PHP documentation $lo contains the low order 32 bit unsigned integer value from the quadword, and $hi contains the high order 32 bit unsigned integer value. Note, however, that if the PHP internal representation of integer values is the minimum 32 bit signed value, then if the value of either $lo or $hi is greater than the maximum possible 31 bit positive value, then the value will be represented internally as a 64 bit floating point value. This should not matter externally. However if the GMP functions turn out to have problems with floating point inputs (which they are not documented to accept), you can translate the values of $lo and $hi to string parameters using, for example sprintf.
I haven't tested the following but I think it should work. Assuming that the quadword is in a string $qw:
$lo = ord($qw[0]) + 256*(ord($qw[1]) + 256*(ord($qw[2]) + 256*ord($qw[3])));
$hi = ord($qw[4]) + 256*(ord($qw[5]) + 256*(ord($qw[6]) + 256*ord($qw[7])));
$tm = gmp_add($lo , gmp_mul(256*256*256*256, $hi));
Based upon the PHP documentation $lo contains the low order 32 bit unsigned integer value from the quadword, and $hi contains the high order 32 bit unsigned integer value. Note, however, that if the PHP internal representation of integer values is the minimum 32 bit signed value, then if the value of either $lo or $hi is greater than the maximum possible 31 bit positive value, then the value will be represented internally as a 64 bit floating point value. This should not matter externally. However if the GMP functions turn out to have problems with floating point inputs (which they are not documented to accept), you can translate the values of $lo and $hi to string parameters using, for example sprintf.
Re: php and reading a quadword
Thank you for the response, and the Info! I will give it a go when i get a chance 