Solved

Getting 23 for year 2003 when bit mask file creation date

Posted on 2003-10-27
9
208 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
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 

Author Comment

by:yunikon
ID: 9633401
Changing the type hasn't worked.
-Y
0
 
LVL 45

Accepted Solution

by:
Kent Olsen 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:Kent Olsen
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:Kent Olsen
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Passing a array as parameter - C 2 100
Global Keyboard Hooks Blocked 4 81
Acrinis True image 2 92
Synchronization using condition variables to avoid locking in C 8 90
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…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

809 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