in reply to Re: Unpack for VMS binary files
in thread Unpack for VMS binary files

low_long is the least-significant 32 bits of the quadword date, while high_long is the most significant 32 bits. Make sure that you've unpacked things correctly--the code assumes that a VMS system put the bytes on disk, and in VMS endian-order. If that's not the case, then you'll have problems, of course.

Also, what are the dates supposed to be? Running the conversion on the first date gives me a date of Wed Dec 22 00:14:00 1993, which might well be correct. (Hard to say there)

Replies are listed 'Best First'.
Re: Re: Re: Unpack for VMS binary files
by maderman (Beadle) on Feb 23, 2003 at 21:56 UTC
    Whilst parsing the VMS binary file, I have unpacked it with the template:
    my $template="V2 v12";
    Where V/v are a long/short in "VAX" (little-endian) order. As I've already unpacked the data, there isn't a need to redo the unpack commands in the subroutine - just pass the low_long and high_long as is into the sub. There is one problem: the data in the binary file starts at 00:00:00 and ends at 23:40:40 for 1-1-2003. Printing out the output from the sub produces 11:00:00 through to 23:40:40 and _then_ 00:00:00 through to 10:59:40 for 2-1-2003! Regards, Stacy.

      Elian's code wants to do the unpacking. Try something like this.

      @vals = unpack("x8 v12",$buf); $timelow = substr($buf,0,4); $timehigh = substr($buf,4,4);

      @vals will contain all the short values. This unpack will skip the first eight bytes (the time field) so the time is no longer returned. Instead, the time is pulled out of the buffer in packed form with substr. You can then pass $timelow and $timehigh to Elian's conversion function.

      --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
        Yep, your solution works except the time string (in my case) is 32 bytes. Therefore:
        $timelow = substr($record,0,16); $timehigh = substr($record,16,32); &quad_to_epoch("$timelow $timehigh");
        However,when I print the $Unix_based_time value with print scalar localtime($Unix_based_time), the output starts at 1st Jan 2003 11:00:00 to 23:59:40 and then 2nd Jan 00:00:00 to 10:59:40! The file should start at 00:00:00 Jan 1st and end at 23:59:40 on the same day... Regards, Stacy.