2013-04-02 336 views
5

我试图将时间结构转换为FAT时间戳。我的代码如下所示:Unix时间戳到FAT时间戳

unsigned long Fat(tm_struct pTime) 
{ 
    unsigned long FatTime = 0; 

    FatTime |= (pTime.seconds/2) >> 1; 
    FatTime |= (pTime.minutes) << 5; 
    FatTime |= (pTime.hours) << 11; 
    FatTime |= (pTime.days) << 16; 
    FatTime |= (pTime.months) << 21; 
    FatTime |= (pTime.years + 20) << 25; 

    return FatTime; 
} 

是否有人拥有正确的代码?

+0

你的问题是什么? – 2013-04-02 11:55:13

回答

10
The DOS date/time format is a bitmask: 

       24    16     8     0 
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 
|Y|Y|Y|Y|Y|Y|Y|M| |M|M|M|D|D|D|D|D| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| 
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ 
\___________/\________/\_________/ \________/\____________/\_________/ 
    year  month  day  hour  minute  second 

The year is stored as an offset from 1980. 
Seconds are stored in two-second increments. 
(So if the "second" value is 15, it actually represents 30 seconds.) 

我不知道你使用的是tm_struct但如果它是http://www.cplusplus.com/reference/ctime/tm/然后

unsigned long FatTime = ((pTime.tm_year - 80) << 25) | 
         (pTime.tm_mon << 21) | 
         (pTime.tm_mday << 16) | 
         (pTime.tm_hour << 11) | 
         (pTime.tm_min << 5) | 
         (pTime.tm_sec >> 1); 
+0

如果'sizeof(int)'是2(如果代码是用于DOS实模式,则可能是这种情况),则需要使用一些类型转换。 –

+1

顺便说一句,转换为'unsigned'类型会更好,因为'signed'类型的移动不是完全可移植的。 –

+0

是UTC还是本地时区的FAT时间戳? – rustyx

1

Lefterisê了几乎正确的答案,但这里有一个小失误

你应该加1 tm_mon,因为tm struct将月份保存为从0到11(struct tm)的数字,但DOS日期/时间从1到12(FileTimeToDosDateTime)。 所以正确的是

unsigned long FatTime = ((pTime.tm_year - 80) << 25) | 
    ((pTime.tm_mon+1) << 21) | 
    (pTime.tm_mday << 16) | 
    (pTime.tm_hour << 11) | 
    (pTime.tm_min << 5) | 
    (pTime.tm_sec >> 1);