Solved

Getting 23 for year 2003 when bit mask file creation date

Posted on 2003-10-27
9
203 Views
Last Modified: 2010-04-15
Trying to print the make date and time of  files from folder.  Get large decimal results so am trying to convert to standard time & date format by bit masking.  Getting 23 instead of 2003 for the year.  Day, month, time-hour, minute and seconds covnverted correctly. function codes;

main()
{

  ..........................
............................
}
FILEBLOCK convert_time(int f_Time)
{


    FILEBLOCK nodeTIME;

    unsigned short smask = 31;
    unsigned short mmask = 2016;
    unsigned short hmask = 63488;

    nodeTIME.thetime.sec = f_Time &smask;  // fblock.ff_ftime sent from main & stored in f_Time
    nodeTIME.thetime.min = f_Time &mmask;      
    nodeTIME.thetime.hr  = f_Time &hmask;      

    nodeTIME.thetime.min = nodeTIME.thetime.min >> 5;
    nodeTIME.thetime.hr  = nodeTIME.thetime.hr >> 11;

    return nodeTIME;    // return to main & print

}



FILEBLOCK convert_date(int f_Date)
{

    FILEBLOCK nodeDATE;

     unsigned short dmask = 31;
    unsigned short mmask = 480;
    unsigned short ymask = 65024;


    nodeDATE.thedate.day   = f_Date &dmask;  // SIMILAR EXPLANATION AS IN convert_time()
    nodeDATE.thedate.month = f_Date &mmask;
    nodeDATE.thedate.year  = f_Date &ymask;

    nodeDATE.thedate.month = nodeDATE.thedate.month >> 5;
    nodeDATE.thedate.year  = nodeDATE.thedate.year >> 9;
     
    return nodeDATE;
}

Appreciate your help.
-Y
0
Comment
Question by:yunikon
  • 5
  • 3
9 Comments
 
LVL 7

Expert Comment

by:MrNed
ID: 9631877
Your masking an int with a number that doesnt fit in an int.

What exactly is stored in f_Time and f_Date, perhaps they should be unsigned int or unsigned long? My guess is that its simply a count of the number of seconds since some fixed date and so you should be dividing, not masking.
0
 

Author Comment

by:yunikon
ID: 9633266
Thanks for your reply.  Functios findfirst() and findnext() were used to find the files in main().  Structure ffblk's members, fblock.ff_fdate & fblock.ff_ftime  (struct  ffblk  fblock:  dir.h ) were sent from main to convert_date() & convert_time() during 2 function calls.  The sent structure members are integers.  That is why f_Time and f_Date are declared as int in the 2 concert_ functions.  The conversion fuctions converted the fblock.ff_fdate & fblock.ff_ftime members correctly except that the date  give's 23 instead of 2003 for the year.   2 files returned  12065 / 32595, and 19772 / 12059 respectively for the file creation dates and times before using the conversion functions.    Using the conversion functions gives the date and time in formats ddmmyear  & hrminsec.   year is showing 23 instead of 2003.
Thanks for helping.
-Y

0
 

Author Comment

by:yunikon
ID: 9633336
The dir.h documentation is showing fblock.ff_fdate & fblock.ff_ftime as unsigned short.  Will change type for f_Date & f_Time & see if it works.
0
 

Author Comment

by:yunikon
ID: 9633401
Changing the type hasn't worked.
-Y
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 45

Accepted Solution

by:
Kdo earned 60 total points
ID: 9633504

Hi yunikon,

A couple of things.  Using integer values as masks is a perverse thing to do.  (Yes -- we all know that 31 masks the lower 5 bits.)  It's much more descriptive to use octal or hex constants, depending on usage.  In this case,

 unsigned short smask = 31;

should be either of:

 unsigned short smask = 0x1F;
 unsigned short smask = 037;

or better yet, instead of forcing the function to store a constant at smask, define the constant:

#define MASK5 (0x1F)


Internally, many systems keep the year as (Year - BIAS).  Where the bias is often 1900, 1970, or 1980.  It sounds like your system is using a BIAS_YEAR of 1980.


Kent
0
 

Author Comment

by:yunikon
ID: 9634595
The _findfirst documentation says < bits 9 - 15, years since 1980, (eg. 9 means 1989) >.  23 + 1980 = 2003. So YEAR_BIAS is important. Added - nodeDATE.thedate.year += 1980; - to the above code and got the correct year.
Tried using hexa for mask but got 0 for the date month & the time minute ie., the second masks (mmask).  Will try octal.  What do you mean by -" ...descriptive to use octal or hex constants, depending on usage"-?.

0
 
LVL 45

Expert Comment

by:Kdo
ID: 9634685

If you're just trying to mask the bottom bits of a word, then 2**n-1 will give you the correct mask.  It's pretty common for programmers to be able to recite the powers of 2 up to 2**16 or so, but larger masks will almost certainly have to be derived, and not all masks require just the lower bits.

If (for whatever reason) I wanted to replace a center byte in a word, using the correct mask means a pretty simple operation.  

#define MYMASK  0xFF00


int32 Value;

Value = ((~MYMASK) & Value)  | NewValue;


Or perhaps you want to test if a particular three bits in a word are set:

#define  BIT4   0x10
#define  BIT8   0x100
#define  BIT13 0x2000
#define TESTMASK (BIT4|BIT8|BIT13)

if ((Value & TESTMASK) == TESTMASK)
  /*  All three bits are set  */


Seeing the way the mask is created is much more descriptive than seeing:

if ((Value & 8464) == 8464)


Go ahead and post your new code.  I'll gladly see where your mask definition went awry.

Kent


0
 

Author Comment

by:yunikon
ID: 9655750
Appreciate your comments.  This is the working code, YEAR_BIAS adjustment is made in the next-to-last line.


#include<stdio.h>
#include<dir.h>
#include<conio.h>


            // file attribute definitions

#define      NORMAL            0x00
#define      READONLY            0x01
#define      HIDDEN            0x02
#define      SYSTEM            0x04
#define      VOLLABEL            0x08
#define      DIR            0x10
#define      ARCHIVE            0x20



       typedef struct time {
                         int sec;
                                  int min;
                                  int hr;

                            }FILETIME;


       typedef struct date {
                                   int day;
                                      int month;
                                      int year;

                           }FILEDATE;



       typedef struct fileBlk {
                   char ff_reserved[22];
                                    char ff_attrib;
                                    unsigned short ff_ftime;
                                    unsigned short ff_fdate;
                                    long ff_fsize;
                                           char ff_name[13];
                                           FILETIME thetime;
                                       FILEDATE thedate;
                                       struct fileBlk *next_NODE;
                    }FILEBLOCK;



FILEBLOCK convert_time(unsigned short);

FILEBLOCK convert_date(unsigned short);

int main()
{


    char locatn[40];
    FILEBLOCK node;
    struct ffblk fblock;       // create file info block


    puts("\nENTER PATHNAME - drive, folder, *.* !\n\n");
    gets(locatn);

    if(findfirst(locatn, &fblock, NORMAL) != 0)   {   // LOCATE 1st FILE IN DERECTORY
         puts("\nERROR, NO FILE FOUND \n\n");
         getch();
         return 1;
    }

    printf("\nFILE_NAME\tFILE_SIZE\tCREATE_DATE\tCREATE_TIME\n\n");

    node = convert_date(fblock.ff_fdate);
    node = convert_time(fblock.ff_ftime);
   
    strcpy(node.ff_name, fblock.ff_name);      // COPY FILENAME TO CREATED NODE STRUCTURE

    printf("%s\t%d\t%d-%d-%d\t%d-%d-%d\n", node.ff_name, node.ff_fsize,
                      node.thedate.day, node.thedate.month, node.thedate.year, node.thetime.hr, node.thetime.min, node.thetime.sec);

    while(findnext(&fblock) == 0)  {          // LOCATE NEXT FILE IN DIRECTORY
         node = convert_date(fblock.ff_fdate);
                node = convert_time(fblock.ff_ftime);
                strcpy(node.ff_name, fblock.ff_name);

                printf("%s\t%d\t%d-%d-%d\t%d-%d-%d\n", node.ff_name, node.ff_fsize,
          node.thedate.day, node.thedate.month, node.thedate.year, node.thetime.hr, node.thetime.min, node.thetime.sec);
    }
    puts("\n\nEND\n\n");
    getch();
    return 0;

}




FILEBLOCK convert_time(unsigned short f_Time)
{


    FILEBLOCK nodeTIME;

       unsigned short smask = 31;
    unsigned short mmask = 2016;
    unsigned short hmask = 63488;


    nodeTIME.thetime.sec = f_Time &smask; // ffblock.ff_ftime was received from main at function
    nodeTIME.thetime.min = f_Time &mmask; // call, it is stored in int f_Time, so f_Time is used
    nodeTIME.thetime.hr  = f_Time &hmask; // here instead of fblock.ff_ftime.

    nodeTIME.thetime.min = nodeTIME.thetime.min >> 5;
    nodeTIME.thetime.hr  = nodeTIME.thetime.hr >> 11;

    return nodeTIME;

}



FILEBLOCK convert_date(unsigned short f_Date)
{

    FILEBLOCK nodeDATE;


       unsigned short dmask = 31;
    unsigned short mmask = 480;
    unsigned short ymask = 65024;


    nodeDATE.thedate.day   = f_Date &dmask;     // SIMILAR EXPLANATION AS IN convert_time funct.
    nodeDATE.thedate.month = f_Date &mmask;
    nodeDATE.thedate.year  = f_Date &ymask;

    nodeDATE.thedate.month = nodeDATE.thedate.month >> 5;
    nodeDATE.thedate.year  = nodeDATE.thedate.year >> 9;

    nodeDATE.thedate.year += 1980;   // BASE_YEAR FOR ff_fdate is 1980

    return nodeDATE;
}
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9657381

Man, I love it when code's easy to follow....  (Good looking code!)


The file attribute definitions are usually in one of the include files.  So are the time and stat structures.  On a linux system you can get them by:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


The only other thing to suggest is creating the masks with the #define statement, as I suggested earlier.

Kent
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now