1
        char buffer[800];
        struct tm str_time;

        str_time.tm_mday = Cur_Day;
        str_time.tm_mon = Cur_Month - 1;
        str_time.tm_year = entries[i].Year_Start - 1900;
        int len = strftime(buffer, 100, "%A, %d %B %Y", &str_time);
        printf("\n%s\n", buffer);

无论 Cur_Day 和 Cur_Month 的值如何,上述结果在一周中的哪一天总是星期日怎么样?

样本输出:

Sunday, 23 November 2012
------------------------
stuff

Sunday, 25 November 2012
------------------------
stuff

Sunday, 26 November 2012
------------------------
stuff
4

3 回答 3

3

您的str_time结构(如果它看起来是一个局部变量)在其字段中具有不确定的值,除非您明确设置它们。所做strftime的只是使用它拥有的值,它不会首先调整值以符合其他字段。

由于您没有设置tm_wday,它将保持原来的状态(看起来为 0,因为它总是星期天)。

如果您确实想根据其他字段调整字段,您应该查看mktime().

从标准(ISO C99):

mktime 函数将timeptr 指向的结构中以本地时间表示的分解时间转换为与time 函数返回的值编码相同的日历时间值。

结构的tm_wday和tm_yday组件的原始值被忽略,其他组件的原始值不限于上述范围。

成功完成后,结构的 tm_wday 和 tm_yday 组件的值被适当设置,其他组件被设置为表示指定的日历时间,但它们的值被强制为上述范围;在确定 tm_mon 和 tm_year 之前,不会设置 tm_mday 的最终值。

最好的办法是使用time()localtime()填充tm结构,然后在调用之前更改要更改的字段mktime()。这样,您就可以保证所有字段都具有合理的值。

以下程序显示了一种方法:

#include <stdio.h>
#include <time.h>

int main (void) {
    char buffer[100];
    time_t now;
    struct tm *ts;

    // Get today in local time and output it.

    now = time (NULL);
    struct tm *ts = localtime (&now);
    strftime (buffer, 100, "%A, %d %B %Y", ts);
    printf ("Now      = %s\n", buffer);

    // Advance day-of-month and make new date.
    // Probably need to intelligently handle month rollover.

    ts->tm_mday++;
    mktime (ts);
    strftime (buffer, 100, "%A, %d %B %Y", ts);
    printf ("Tomorrow = %s\n", buffer);

    return 0;
}

该程序的输出是:

Now      = Tuesday, 09 October 2012
Tomorrow = Wednesday, 10 October 2012

对于它的价值,这是一个完整的程序,它使用该方法为您提供给定日期的星期几(默认为今天)。

-y您可以使用可选的,-m-d参数以您想要的任何顺序更改年、月和日,并且可以根据需要更改任意次数,尽管每种类型只计算最后一个。

#include <stdio.h>
#include <time.h>

static int makeError (char *argVal, char *errStr) {
    printf ("Error with argument '%s': %s\n", argVal, errStr);
    printf ("Usage: dow [-y<year>] [-m<month>] [-d<day>]\n");
    return 1;
}

int main (int argc, char *argv[]) {
    int idx, intVal;
    char chVal;
    char buff[100];
    time_t now = time (NULL);
    struct tm *nowStr = localtime (&now);

    for (idx = 1; idx < argc; idx++) {
        chVal = (*argv[idx] != '-') ? '\0' : *(argv[idx] + 1);
        if ((chVal != 'y') && (chVal != 'm') && (chVal != 'd'))
            return makeError (argv[idx], "does not start with '-y/m/d'");

        intVal = atoi (argv[idx] + 2);
        if (intVal < 0)
            return makeError (argv[idx], "suffix is negative");
        sprintf (buff, "%d", intVal);
        if (strcmp (buff, argv[idx] + 2) != 0)
            return makeError (argv[idx], "suffix is not numeric");

        switch (chVal) {
            case 'y': nowStr->tm_year = intVal - 1900; break;
            case 'm': nowStr->tm_mon = intVal - 1; break;
            case 'd': nowStr->tm_mday = intVal; break;
        }
    }

    mktime (nowStr);
    strftime (buff, sizeof (buff), "%A, %d %B %Y", nowStr);
    printf ("%s\n", buff);

    return 0;
}

样本成绩单:

pax> ./dow
Tuesday, 09 October 2012

pax> ./dow -y2011
Sunday, 09 October 2011

pax> ./dow -y2000 -m1 -d1
Saturday, 01 January 2000
于 2012-10-09T02:31:12.343 回答
1

最可能的解释是,如果您要要求它打印星期几,则strftime需要具有有意义的值。tm_wday

这是避免自己计算的最简单的可用方法:

struct tm tm;

memset(&tm, 0, sizeof(struct tm));
tm.tm_mday = Cur_Day;
tm.tm_mon = Cur_Month - 1;
tm.tm_year = entries[i].Year_Start - 1900;
tm.tm_hour = 12;

(void) timegm(&tm); /* fills in the rest of `tm` as a side effect */

/* now call strftime */

如果你没有,timegm你可能可以mktime改用使用(如果你只想打印日期,在“本地”时间进行此计算的问题在很大程度上是无关紧要的)。不要使用timegmLinux 手册页中描述的“便携式版本” timegm,它几乎在每一行都有可移植性陷阱!

于 2012-10-09T02:32:30.233 回答
0

您需要设置str_time.tm_wday以便strftime()可以转换它。

有关示例,请参见localtime(3)strftime(3)

于 2012-10-09T02:30:09.473 回答