strftime发布星期几

时间:2012-10-09 02:24:49

标签: c

        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

3 个答案:

答案 0 :(得分:3)

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

由于你没有设置tm_wday,它将保留原来的任何东西(0看起来就是它,因为它总是星期天)。

如果 想要根据其他字段调整字段,则应查看mktime()

从标准(ISO C99):

  

mktime函数将故障时间(以本地时间表示)转换为   timeptr指向的结构为具有相同编码的日历时间值   时间函数返回的值。

     

忽略结构的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

答案 1 :(得分: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

如果您没有timegm,您可以使用timegm取而代之(如果您只想打印,那么在'本地'时间进行此计算的问题基本上无关紧要日期)。不要使用{{1}}的Linux联机帮助页中描述的“{{1}}的可移植版本”,它具有可移植性,几乎每行都会等待它!

答案 2 :(得分:0)

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

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