【问题标题】:Unix timestamp to FAT timestampUnix 时间戳到 FAT 时间戳
【发布时间】:2013-03-23 16:43:49
【问题描述】:

我正在尝试将时间结构转换为 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;
}

有人有正确的代码吗?

【问题讨论】:

  • 你有什么问题?

标签: c datetime time timestamp fat32


【解决方案1】:
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 + 1) << 21) |
                        (pTime.tm_mday << 16) |
                        (pTime.tm_hour << 11) |
                        (pTime.tm_min << 5) |
                        (pTime.tm_sec >> 1);

编辑:我在 cmets 中提到的月份添加了 +1

【讨论】:

  • 如果sizeof (int) 为 2,则需要进行一些类型转换(如果代码用于 DOS 实模式,则可能是这种情况)。
  • 顺便说一句,转换为unsigned 类型会更好,因为signed 类型的转换不是完全可移植的。
  • FAT 时间戳是 UTC 还是本地时区?
  • 它曾经处于系统时间设置的任何位置,即本地时区。但是 FAT 是非常广泛采用的格式,不同实现的行为可能在细节上有所不同。
  • 小心,tm_mon 从 0 开始计算月份,所以我认为应该将 (pTime.tm_mon &lt;&lt; 21) 更改为 ((pTime.tm_mon+1) &lt;&lt; 21),就像下面的其他答案一样。
【解决方案2】:

您也可以使用位域和库time.h。在我的项目中,我将 UNIX 时间戳转换为 FatFs 时间。

        #include <time.h>

        #pragma pack (push,1)
        typedef struct{
            unsigned Sec :5;
            unsigned Min :6;
            unsigned Hour :5;
            unsigned Day :5;
            unsigned Month :4;
            unsigned Year :7;
        }FatDate_t;
        #pragma pack (pop)

        DWORD get_fattime(void){ 
            time_t ts=GetDateTimeNow();
            struct tm * tmInfo = gmtime( &ts );
            uint32_t Result=0;
            FatDate_t *fatDate;
            fatDate=(FatDate_t *)&Result;
            fatDate->Year=tmInfo->tm_year-80;
            fatDate->Month=tmInfo->tm_mon+1;
            fatDate->Day=tmInfo->tm_mday;

            fatDate->Hour=tmInfo->tm_hour;
            fatDate->Min=tmInfo->tm_min;
            fatDate->Sec=tmInfo->tm_sec>>1;

            return Result;
        }

【讨论】:

    【解决方案3】:

    Lefteris E 给出了几乎正确的答案,但这里有一个小错误

    您应该在 tm_mon 中加 1,因为 tm 结构将月份保留为从 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-15
      • 2021-02-12
      • 2013-03-11
      • 2011-11-26
      • 2010-10-02
      • 2012-03-10
      • 1970-01-01
      • 2013-06-03
      相关资源
      最近更新 更多