C 中的 ctime 函数 returns 对于 atime、mtime 和 ctime 的不同值相同的字符串?

ctime functions in C returns same string for differing values of atime, mtime, and ctime?

在 minGW-W64 中使用 stat() 函数时,它的结构 returns,这里 info,为什么 ctime return info.st_atimemtimectime 的字符串完全相同,即使它们的整数值不同?

如果使用localtime分别获取每个时间分量,结果会有所不同并且显得准确;也就是说,它们与我观察到的文件夹中的日期相匹配。

ctime(&info.st_atime )  versus   localtime(&info.st_atime )->tm_wday,
                                 localtime(&info.st_atime )->tm_mon,
                                 localtime(&info.st_atime )->tm_mday,
                                 localtime(&info.st_atime )->tm_hour,
                                 localtime(&info.st_atime )->tm_min,
                                 localtime(&info.st_atime )->tm_sec,
                                 localtime(&info.st_atime )->tm_year

三年前有人问过类似的 question 没有答案。

有谁知道为什么以及在 minGW-W64 中是否有关于日期的文档?

谢谢。


这是完整的代码示例。这是一个丑陋的 printf 集。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>

int main (void)

{
  DIR *dp;
  struct dirent *ep;
  struct stat info;
  int rc;
  char fl_name[300];

  dp = opendir("./SQLite3");

  if ( dp != NULL )
    {
      while ( ep = readdir( dp ) )
        {
          printf( "Name : %s, ", ep->d_name );
          if ( *( ep->d_name ) == '.' )
            { 
              printf(" non-useful file\n");
              continue;
            }

          sprintf( fl_name, "%s%s", "./SQLite3/", ep->d_name );

          if ( ( rc = stat( fl_name, &info ) ) != 0 )
             {
               printf( "rc : %d\n", rc );
               printf( "errno : %d, strerror : %s\n", errno, strerror( errno ) );
               break;
             }

          printf( "mode : %d, size : %d,\nst_atime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n"           
                                        "st_mtime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n"          
                                        "st_ctime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %d\n\n",

                  info.st_mode, info.st_size, 
                  ctime(&info.st_atime ),
                  localtime(&info.st_atime )->tm_wday,
                  localtime(&info.st_atime )->tm_mon,
                  localtime(&info.st_atime )->tm_mday,
                  localtime(&info.st_atime )->tm_hour,
                  localtime(&info.st_atime )->tm_min,
                  localtime(&info.st_atime )->tm_sec,
                  localtime(&info.st_atime )->tm_year,
                  info.st_atime,

                  ctime(&info.st_mtime ),
                  localtime(&info.st_mtime )->tm_wday,
                  localtime(&info.st_mtime )->tm_mon,
                  localtime(&info.st_mtime )->tm_mday,
                  localtime(&info.st_mtime )->tm_hour,
                  localtime(&info.st_mtime )->tm_min,
                  localtime(&info.st_mtime )->tm_sec,
                  localtime(&info.st_mtime )->tm_year,
                  info.st_mtime,

                  ctime(&info.st_ctime ),
                  localtime(&info.st_ctime )->tm_wday,
                  localtime(&info.st_ctime )->tm_mon,
                  localtime(&info.st_ctime )->tm_mday,
                  localtime(&info.st_ctime )->tm_hour,
                  localtime(&info.st_ctime )->tm_min,
                  localtime(&info.st_ctime )->tm_sec,
                  localtime(&info.st_ctime )->tm_year ),
                  info.st_ctime;    
        }    
      printf( "Now : %ld\n", time(NULL) );
      printf( "Broke" );
      (void) closedir (dp);
    }
  else
    perror ("Couldn't open the directory");    
  return 0;
}

一个文件的结果如下所示。

Name : testing.c, mode : 33206, size : 21092,
st_atime : Thu Nov 26 23:56:20 2020
local : 4 10 26 23 : 56 : 20 120,
integer value : 1606452980
st_mtime : Thu Nov 26 23:56:20 2020
local : 5 10 27 0 : 16 : 58 120,
integer value : 1606454218
st_ctime : Thu Nov 26 23:56:20 2020
local : 6 9 31 23 : 8 : 28 120,
integer value : 5767254

请注意,来自 ctime() 的数据字符串是相同的,尽管所有三个的整数值不同。此外,ctime 的整数值格式与 atimemtime 的格式不同。 atimemtime 似乎是自 1970 年 1 月 1 日以来的秒数,但我不知道 ctime 是什么,因为 5767254.

谢谢。


根据@KamilCuk 的评论修复了代码。我的愚蠢和丑陋的 printf 是原因。以下更改和新结果。

  struct tm *local_tm_ptr;

    
          local_tm_ptr = localtime(&info.st_atime );
          printf( "mode : %d, size : %d,\nst_atime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n",           
                  info.st_mode, info.st_size, 
                  ctime(&info.st_atime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_atime );


          local_tm_ptr = localtime(&info.st_mtime );
          printf( "st_mtime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n",
                  ctime(&info.st_mtime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_mtime );


          local_tm_ptr = localtime(&info.st_ctime );
          printf( "st_ctime : %slocal : %d %d %d %d : %d : %d %d,\ninteger value : %ld\n\n",
                  ctime(&info.st_ctime ),
                  local_tm_ptr->tm_wday,
                  local_tm_ptr->tm_mon,
                  local_tm_ptr->tm_mday,
                  local_tm_ptr->tm_hour,
                  local_tm_ptr->tm_min,
                  local_tm_ptr->tm_sec,
                  local_tm_ptr->tm_year,
                  info.st_ctime );

新结果。

Name : testing.c, mode : 33206, size : 21092,
st_atime : Thu Nov 26 23:56:20 2020
local : 4 10 26 23 : 56 : 20 120,
integer value : 1606452980
st_mtime : Fri Nov 27 00:16:58 2020
local : 5 10 27 0 : 16 : 58 120,
integer value : 1606454218
st_ctime : Sat Oct 31 23:08:28 2020
local : 6 9 31 23 : 8 : 28 120,
integer value : 1604200108

你基本上是在做:

static char buffer[20]; // static buffer internal for asctime
char *my_asctime(int a) { // asctime
    snprintf(buffer, 20, "%d", a); // asctime converts the input to some output
    return buffer; // and returns pointer to internal buffer
}
int main() {
    printf("%s %s %s %s\n", 
       my_asctime(1),
       my_asctime(2),
       my_asctime(3),
       my_asctime(4)
   );
    // **Any** of the outputs are valid:
    // 1 1 1 1
    // 2 2 2 2
    // 3 3 3 3
    // 4 4 4 4
}

所有asctime(理智的实现)写入相同的内存和return 相同的指针。因此,当执行 printf 时,它只会打印同一内存的内容。请注意,函数参数的 order of evaluation 彼此无序,但函数调用的评估顺序不确定。 asctime 的任何一种可能结果都有效。使用 asctime_r 或在单独的 printf 中一个接一个地调用。