Gmail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
MS-DOS standard date format
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  5 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
b_art_osh  
View profile  
 More options Apr 19 2009, 6:18 am
Newsgroups: comp.os.msdos.programmer
From: b_art_osh <bb.bart...@gmail.com>
Date: Sun, 19 Apr 2009 03:18:41 -0700 (PDT)
Local: Sun, Apr 19 2009 6:18 am
Subject: MS-DOS standard date format
Hi everyone,

Recently i'm trying to write a program in C++ that reads ZIP files.
One of the properties of a local file header is last modification date
and last modification time. I found in a ZIP file format specification
that "The date and time are encoded in standard MS-DOS format". And
here's my question: how do i decode it? I was trying to find some
information about in the internet, but i can't find anything useful,
so please, if any of you could help me in any way,  i would really
appreciate it.

Here's an exapmle of what i'm trying to achieve:
MY PROGRAM:
Last mod file time: 7423 (hex)
Last mod file date: 3658 (hex)
7-ZIP:
Modified: 2007-02-24, 14:33:06


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Rod Pemberton  
View profile  
(1 user)  More options Apr 19 2009, 8:05 am
Newsgroups: comp.os.msdos.programmer
From: "Rod Pemberton" <do_not_h...@nohavenot.cmm>
Date: Sun, 19 Apr 2009 08:05:01 -0400
Local: Sun, Apr 19 2009 8:05 am
Subject: Re: MS-DOS standard date format
"b_art_osh" <bb.bart...@gmail.com> wrote in message

news:ca29de47-b1ed-4c0f-af8f-fbfd7d52ba70@h2g2000yqg.googlegroups.com...

RBIL (Ralf Brown's Interrupt List) via DJGPP website:

http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html
http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html
http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html

http://www.delorie.com/djgpp/doc/rbinter/ix/

RBIL is also available on the web in html from another site and from Mr.
Brown's website as a collection of files.

InfoZip has PKZIP compatible compressors/decompressors with open source.
I.e., you can check what they did.
http://www.info-zip.org/

Let's attempt to manually decode a value using description at links above:

> Last mod file time: 7423 (hex)

bits 15-11 1110    14
bits 5-10 100001   33
bits 0-4  00011      3

Since the lower four bits are /2, 14:33:06...

In C, you might (lots of options...) do something like this (untested):

dos_seconds=(dos_time&0x1F)*2;
dos_minutes=(dos_time>>5)&0x3F;
dos_hours=(dos_time>>11);
sprintf(dos_time_string,"%02d:%02d:%02d",dos_hours,dos_minutes,dos_seconds) ;

The year-month-day is similar except the size of the two upper fields will
be different, so you'll need different shifts and hex and-constants.  You'll
also have to add 1980 to the year.

Rod Pemberton


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
b_art_osh  
View profile  
 More options Apr 19 2009, 9:17 am
Newsgroups: comp.os.msdos.programmer
From: b_art_osh <bb.bart...@gmail.com>
Date: Sun, 19 Apr 2009 06:17:35 -0700 (PDT)
Local: Sun, Apr 19 2009 9:17 am
Subject: Re: MS-DOS standard date format
It works like a charm :))) Here's what i wrote:

cout << "Last mode file time: ";
cout << dec << setw(2) << (zip.LastModFileTime >> 11) << ":";
cout << setw(2) << ((zip.LastModFileTime >> 5) & 0x3F) << ":";
cout << setw(2) << (zip.LastModFileTime & 0x1F) * 2 << endl;

cout << dec << (zip.LastModFileDate & 0x1F) << ".";
cout << ((zip.LastModFileDate >> 5) & 0x0F) << ".";
cout << ((zip.LastModFileDate >> 9) & 0x7F) + 1980 << endl;

OUTPUT:
Last mod file time: 14:33:06
Last mod file date: 24.02.2007

It's simple and efficient so double jackpot :) Thanks again Rod :)


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dr J R Stockton  
View profile  
 More options Apr 19 2009, 11:43 am
Newsgroups: comp.os.msdos.programmer
From: Dr J R Stockton <reply0...@merlyn.demon.co.uk>
Date: Sun, 19 Apr 2009 16:43:21 +0100
Local: Sun, Apr 19 2009 11:43 am
Subject: Re: MS-DOS standard date format
In comp.os.msdos.programmer message <ca29de47-b1ed-4c0f-af8f-fbfd7d52ba7
0...@h2g2000yqg.googlegroups.com>, Sun, 19 Apr 2009 03:18:41, b_art_osh
<bb.bart...@gmail.com> posted:

Two consecutive words, or a longword, YYYYYYYMMMMDDDDD hhhhhmmmmmmsssss

YYYYYYY is years from 1980 = 0
sssss is (seconds/2).

3658 = 0011 0110 0101 1000 = 0011011 0010 11000 = 27 2 24 = 2007-02-24
7423 = 0111 0100 0010 0011 - 01110 100001 00011 = 14 33 2 =   14:33:06

Note that the MSB changes 2043/4.

--
 (c) John Stockton, nr London, UK.    ?...@merlyn.demon.co.uk     Turnpike v6.05.
 Web  <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
 PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
 Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bill Buckels  
View profile  
 More options Apr 19 2009, 2:29 pm
Newsgroups: comp.os.msdos.programmer
From: "Bill Buckels" <bbuck...@mts.net>
Date: Sun, 19 Apr 2009 13:29:22 -0500
Local: Sun, Apr 19 2009 2:29 pm
Subject: Re: MS-DOS standard date format

"Rod Pemberton" <do_not_h...@nohavenot.cmm> wrote:
>In C, you might (lots of options...)

Excellent post! Yes lots of options...

// ------------------------------------------------------------------------
// System       : Win9X/NT
// Program      : touch.c
// Description  : modify file times
//                handles long filenames under Win9X/NT
// Written by   : Bill Buckels
// Date Written : March 2000
// Revision     : 1.0 First Release
// Errata       : Used Workarounds for incorrect adjustment of localtime
//                For some reason the conversion from clock date to
//                file date is out by an hour... and I don't completely
//                understand why. But if workarounds are OK then
//                no plan to fix.
// ------------------------------------------------------------------------

#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <string.h>
#include <direct.h>
#include <time.h>
#include <sys/types.h>
#include <sys/utime.h>
#include <sys/stat.h>

/* global vars. */

struct tm TouchTime;                /* global structure */

char *timestr = "29:59:59",         /* verification pattern */
     *alttime = "29:59",
     *datestr = "19-39-2999",
     *altdate = "19-39-99",
     *timearg = "HH:MM:SS",         /* command line args - intial values */
     *datearg = "MM-DD-CCYY",
     searcharg[_MAX_PATH] = "*.*";  /* file spec - initial value */

int force = 0,
    nocreate = 0,
    verbose = 0,
    TouchNow = 0;  /* if this flag is set, the filetime is now */

/* positions in the date string MM-DD-CCYY or HH:MM:SS */
#define POS_1 0
#define POS_2 3
#define POS_3 6

/* get the command line options */
/* assign the values to the globals */

int GetOptions(char *arg)
{
  int len,
      idx,
      val,
      found = 0;

  char c;

  /* parse switches */
  if (arg[0] == '-') {
    for (idx = 0; arg[idx] != 0; idx++) {
      c = tolower(arg[idx]);
      switch(c) {
        case 'f': force = 1;    break;   /* force readonly */
        case 'c': nocreate = 1; break;   /* don't create 0 length */
        case 'v': verbose = 1;  break;   /* verbose mode */
      }
    }
    return (found);
  }

  len = strlen(arg);

  /* check for time pattern HH:MM:SS */
  if (len == strlen(timestr)) {
    found = 1;
    for (idx = 0; arg[idx] != 0; idx++) {
      if (timestr[idx] == ':' && arg[idx] == ':')
        continue;
      if (arg[idx] >= '0' && arg[idx] <= timestr[idx])
        continue;
      found = 0;
      break;
    }
    if (found)  {
      strcpy(timearg, arg);
      TouchTime.tm_hour = atoi(&timearg[POS_1]);
      TouchTime.tm_min  = atoi(&timearg[POS_2]);
      TouchTime.tm_sec  = atoi(&timearg[POS_3]);
      return found;
    }
  }

  /* check for alternate time pattern HH:MM */
  if (len == strlen(alttime)) {
    found = 1;
    for (idx = 0; arg[idx] != 0; idx++) {
      if (alttime[idx] == ':' && arg[idx] == ':')
        continue;
      if (arg[idx] >= '0' && arg[idx] <= alttime[idx])
        continue;
      found = 0;
      break;
    }
    if (found)  {
      TouchTime.tm_hour = atoi(&arg[POS_1]);
      TouchTime.tm_min  = atoi(&arg[POS_2]);
      TouchTime.tm_sec  = 0;
      sprintf(timearg, "%002d:%002d:%002d",
        TouchTime.tm_hour, TouchTime.tm_min, TouchTime.tm_sec);
      return found;
    }
  }

  /* check for date pattern - MM-DD-CCYY */
  if (len == strlen(datestr)) {
    found = 1;
    for (idx = 0; arg[idx] != 0; idx++) {
      if (datestr[idx] == '-' && arg[idx] == '-')
        continue;
      if (arg[idx] >= '0' && arg[idx] <= datestr[idx])
        continue;
      found = 0;
      break;
    }
    if (found)  {
      strcpy(datearg, arg);
      TouchTime.tm_mon  = atoi(&datearg[POS_1]) - 1;
      TouchTime.tm_mday = atoi(&datearg[POS_2]);
      TouchTime.tm_year = atoi(&datearg[POS_3]) - 1900;
      return found;
    }
  }

  /* check for alternate date pattern MM-DD-YY */
  if (len == strlen(altdate)) {
    found = 1;
    for (idx = 0; arg[idx] != 0; idx++) {
      if (altdate[idx] == '-' && arg[idx] == '-')
        continue;
      if (arg[idx] >= '0' && arg[idx] <= altdate[idx])
        continue;
      found = 0;
      break;
    }
    if (found)  {
      TouchTime.tm_mon  = atoi(&arg[POS_1]) - 1;
      TouchTime.tm_mday = atoi(&arg[POS_2]);
      TouchTime.tm_year = atoi(&arg[POS_3]);

      /* no file times in DOS before 1980 - use fixed date window of 1980 */
      /* for Y2K rollover... */

      if (TouchTime.tm_year < 80)
        TouchTime.tm_year += 100;
      sprintf(datearg, "%002d-%002d-%4d",
        TouchTime.tm_mon + 1, TouchTime.tm_mday, TouchTime.tm_year + 1900);
      return found;
    }
  }

  /* usually assume arg is a filename unless it's a date or a time */
  /* in this day and age almost anything goes for filenames */
  if (len < 3 || (arg[2] != ':' && arg[2] != '-')) {
    found = 1;
    strcpy(searcharg, arg);
  }

  return (found);

}

/* function Touch() - the crux of the biscuit    */
/* uses the _utime function to modify file times */

/* In DOS we used the _dos_setftime function to modify the file time
   after opening a file. In Windows we can do basically the same thing
   with the SetFileTime API function. But we don't want to use Windows
   calls since this is a console application and we can't use DOS
   calls since DOS is dead and didn't handle long names anyways.

   Fortunately the Unix Style _utime function offers us a way to modify
   the file times without even opening the file.

   The _utime function sets the modification time for the file specified
   by filename. The process must have write access to the file in order
   to change the time. Under Windows NT and Windows 95, you can change
   the access time and the modication time in the _utimbuf structure. If
   times is a NULL pointer, the modification time is set to the current
   local time. Otherwise, times must point to a structure of type
   _utimbuf, defined in SYS\UTIME.H.

   The _utimbuf structure stores file access and modification times used
   by _utime to change file-modification dates. The structure has the
   following fields, which are both of type time_t:

   actime

   Time of file access

   modtime

   Time of file modification

   _utime is identical to _futime except that the filename argument of
   _utime is a filename or a path to a file, rather than a handle to an
   open file.

   _wutime is a wide-character version of _utime; the filename argument
   to _wutime is a wide-character string. These functions behave
   identically otherwise.

*/

int Touch(unsigned char *fname, time_t time_access, time_t time_write)
{
  struct _utimbuf timbuf, *ptimbuf = NULL; /* structure for call to _utime
*/
  struct tm *worktime, OldTime;
  time_t worktime_t;
  int status = 0,
      readonly = 0;

  /* sometimes we will need to reset the filedate without resetting the time
*/
  /* and sometimes we will need to reset the filetime without the date */
  /* so we need to save the original file date in case this occurs and */
  /* reset only the portion that the user has requested */

  worktime = localtime(&time_write);
  memcpy(&OldTime, worktime, sizeof(struct tm));

  /* preserve orginal time or date if no args */
  if (strcmp(timearg, "HH:MM:SS") == 0) {
    TouchTime.tm_hour = OldTime.tm_hour;
    TouchTime.tm_min  = OldTime.tm_min;
    TouchTime.tm_sec  = OldTime.tm_sec;
  }
  if (strcmp(datearg, "MM-DD-CCYY") == 0) {
    TouchTime.tm_year = OldTime.tm_year;
    TouchTime.tm_mon  = OldTime.tm_mon;
    TouchTime.tm_mday = OldTime.tm_mday;
  }

  /* build the new time */
  /* incorrect behaviour if date and time were current time */
  /* daylight saving time was not adjusting properly in mktime */
  /* out by an hour - so cludge required */
  /* now using a NULL _timbuf structure if setting to current time */

  if (TouchNow == 0) {
    timbuf.modtime = timbuf.actime = mktime(&TouchTime);
    ptimbuf = (struct _utimbuf *)&timbuf;
  }

  if (force) {
    /* if readonly try to set write mode before touching */
    /* save old mode to reset readonly after touching */
    readonly = _access(fname, 2);
    if (readonly) {
       _chmod(fname, _S_IWRITE);
    }
  }

  if( _utime( fname, ptimbuf ) == -1 )
    status = 0;       /* _utime failed so return 0 */
  else
    status = 1;

  if (force && readonly) {
    _chmod(fname, _S_IREAD);  /* try to force old mode back for read only */
  }

  if (status && verbose) {
    printf("%002d:%002d:%002d ",
      TouchTime.tm_hour, TouchTime.tm_min, TouchTime.tm_sec);
    printf("%002d-%002d-%4d ",
      TouchTime.tm_mon + 1, TouchTime.tm_mday, TouchTime.tm_year + 1900);
    printf("%s\n", fname);
  }
  return status;

}

void main(int argc, char **argv)
{
  int idx,
      found = 0;

  unsigned char path_buffer[_MAX_PATH],
           drive[_MAX_DRIVE],
           dir[_MAX_DIR],
           rootname[_MAX_FNAME],
           ext[_MAX_EXT],
           buf[11];          /* work buffer for date and time */

  long findhandle;
  struct _finddata_t wild_card;
  time_t now_t;
  struct tm *today,          /* work structures for date and time */
            CurrentTime;
  FILE *fp;

  puts("Touch(C) v1.0 CopyLeft Bill Buckels 2000. All Rights Reversed.");

  if(argc < 2) {
    puts("Usage is : \"touch -cfv mm-dd-ccyy hh:mm:ss FileName*.*\"");
    puts("- or -   : \"touch -cfv mm-dd-yy hh:mm FileName*.*\"");
    exit (1);
  }

  /* parse the command line */
  for (idx = 1; idx < argc; idx++) {
    GetOptions(argv[idx]);
  }

  /* if no date and time have been entered at all, use current time */
  /* also we set the filetime slightly differently because wierd */
  /* behaviour cause conversion to be out by an hour in some cases */

  if (strcmp(timearg, "HH:MM:SS") == 0 &&
      strcmp(datearg, "MM-DD-CCYY") == 0) {

    time(&now_t);
    today = localtime(&now_t);
    memcpy(&CurrentTime, today, sizeof(struct tm));

    sprintf(buf, "%002d:%002d:%002d",
      CurrentTime.tm_hour, CurrentTime.tm_min,
...

read more »


    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2010 Google