代码之家  ›  专栏  ›  技术社区  ›  Antti Haapala -- Слава Україні

AscTime-每月零日还是加空格?

  •  1
  • Antti Haapala -- Слава Україні  · 技术社区  · 7 年前

    我有以下程序演示如何使用 asctime .

    #include <stdio.h>
    #include <time.h>
    
    int main(void) {
        struct tm   broken_down;
        broken_down.tm_year = 2000 - 1900;
        broken_down.tm_mon = 0;
        broken_down.tm_mday = 1;
        broken_down.tm_hour = broken_down.tm_min = broken_down.tm_sec = 0;
    
        printf("Current date and time: %s", asctime(&broken_down));
    }
    

    这个程序打印 Current date and time: Sun Jan 1 00:00:00 2000 ideone.com ,即日期字段用空格填充。

    当我用msvc编译和运行这个程序时,它生成的日期字符串在月份的第几天前导零: Current date and time: Sun Jan 01 00:00:00 2000 .

    这种差异的原因是什么?哪种格式正确?

    1 回复  |  直到 7 年前
        1
  •  6
  •   Antti Haapala -- Слава Україні    7 年前

    与往常一样,微软(非)标准C库的作者对于正确实现标准字母并没有多大的思考。

    即使在原始标准中 C89/C90 出现以下文本

    描述

    这个 asctime 函数转换结构中的分解时间 指向 timeptr 在窗体中转换为字符串

    Sun Sep 16 01:03:52 1973\n\0
    

    使用以下等效算法。

    char *asctime(const struct tm *timeptr)
    {
        static const char wday_name[7][3] = {
                 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
        };
        static const char mon_name[12][3] = {
                 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        };
        static char result[26];
    
        sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
                 wday_name[timeptr->tm_wday],
                 mon_name[timeptr->tm_mon],
                 timeptr->tm_mday, timeptr->tm_hour,
                 timeptr->tm_min, timeptr->tm_sec,
                 1900 + timeptr->tm_year);
        return result;
    }
    

    不幸的是,该示例本身使用的日期是2位数字的月份日,但代码使用 %3d 这意味着一个十进制数字 在3个字符宽的字段中填充空格并右对齐 .

    给定故障时间的结果是 Sun Jan 1 00:00:00 2000 带有空格填充。


    在2.7.15之前,python 2一直在公开C标准库 阿斯克时间 现在,2.7.15中的输出已经被修改为使用带前导空格的硬编码格式,而不是导致平台依赖行为的换行符。python 2文档在其示例中也使用了一个具有2位数字的日期,这增加了进一步的混乱。