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
答案 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)。