asctime - 月份中的哪一天零或空格填充?

问题描述 投票:0回答:2

我有以下程序演示了

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));
}

此程序在

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

当我使用 MSVC 编译并运行该程序时,它会生成月份中某天带前导零的日期字符串:

Current date and time: Sun Jan 01 00:00:00 2000

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

c visual-c++ language-lawyer msvcrt time.h
2个回答
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
,带有空格填充。


Python 2,直到 2.7.15 为止,都按原样公开 C 标准库

asctime
输出,减去换行符,这导致了平台相关的行为。它已在 2.7.15 中修复为使用带前导空格的硬编码格式。 Python 2 文档在其示例中也使用了 2 位数的日期,这进一步增加了混乱。


0
投票

Microsoft 在 Visual Studio 2015 中使 asctime“一致”。当前版本具有预期的空间填充。

https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-change-history-2003-2015?view=msvc-140

为了避免混淆,请使用当前版本的 VC++

或者,如果您在当前版本中重新编译后使用输出时遇到问题(就像我最近所做的那样),请确保解析生成日期的任何外部进程都已更新以期望实际格式。

© www.soinside.com 2019 - 2024. All rights reserved.