以与 "ls -l" 命令相同的方式格式化 date/time
Formatting date/time in the same way as "ls -l" command
我正在 OS X 中实现 ls -la
命令的一个版本。我偶然注意到 ls
命令列出了一些文件的年份和其他文件的时间,如下所示:
-rwxr-xr-x 1 Jenna 197609 3584 Mar 13 2015 untitled1.exe*
drwxr-xr-x 1 Jenna 197609 0 Mar 2 07:48 Videos/
经过一些研究,我发现超过 6 个月的文件会得到一年,而那些没有得到实际时间的文件。如何让这些文件的日期和时间正确显示年份或时间?目前我有以下始终显示时间的代码:
int main()
{
struct stat *fileInfo;
char dir[] = "~/Desktop/file.txt";
stat(dir, &fileInfo);
printf("%.12s ", 4+ctime(&fileInfo->st_mtimespec));
return 0;
}
strftime
是你的朋友。将其格式化为 ls
并不是那么简单。 ls in coreutils 使用的两种格式是
"%b %e %Y"
"%b %e %H:%M"
这是 coreutils 中 ls 文档中的一段
/* TRANSLATORS: ls output needs to be aligned for ease of reading,
so be wary of using variable width fields from the locale.
Note %b is handled specially by ls and aligned correctly.
Note also that specifying a width as in %5b is erroneous as strftime
will count bytes rather than characters in multibyte locales. */
N_("%b %e %H:%M")
他们正在考虑诸如区域设置(即多字节字符等)之类的问题。他们还讨论了诸如当文件早于 N 个月时他们会更改其显示方式等问题。您可以在此处找到很多信息...
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c
对于您的需求,简单一些可能会更好,这里有一些代码可能会为您指明正确的方向。您可以通过将第三个参数更改为 strftime
.
来将格式更改为您想要的任何格式
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void) {
time_t t;
srand((unsigned) time(&t));
size_t i = 0;
struct timespec ttime;
while(i < 0xffffffff) {\
ttime.tv_sec = i;
i += 3600;
struct tm time_struct;
localtime_r(&ttime.tv_sec, &time_struct);
char time_str[1024];
if(rand() > RAND_MAX/2) {
strftime(time_str, sizeof(time_str), "a == %b %e %Y", &time_struct);
}
else {
strftime(time_str, sizeof(time_str), "b == %b %e %H:%M", &time_struct);
}
printf("%s\n", time_str);
}
exit(0);
}
试一试,看看效果如何。从手册页,调整它会让你真正接近你需要的东西。
size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
The strftime() function formats the information from timeptr into the
buffer s, according to the string pointed to by format.
如果我没记错的话,ls -l
输出一个date/time
或输出一个date/year
的决定因素是[=17]返回的mtime
年份=] 匹配 当前 年份。如果文件 mtime
年与 current
年匹配,则提供 date/time
信息,如果 mtime
年不是 当前 年,然后 date/year
提供信息。
为了进行比较,您需要为文件mtime
和now
填写一个struct tm
。下面的例子用localtime_r
填充每个struct tm
,进行比较,然后输出相应的文件详细信息。
(代码将 read/compare mtimes
s 并输出作为参数提供的所有文件名的时间格式。(占位符字符串用于为文件权限、数字、用户提供基本格式、组、大小等)
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#define MAXC 64
void dump_tm (struct tm *t);
int main(int argc, char **argv)
{
int i = 0;
char time_str[MAXC] = "";
time_t now = time (NULL);
struct stat sb;
struct tm tmfile, tmnow;
if (argc < 2) { /* validate sufficient arguments provided */
fprintf (stderr, "error: insufficient input, usage: %s <pathname>\n",
argv[0]);
return 1;
}
for (i = 1; i < argc; i++) { /* for each file given as arg */
if (stat(argv[i], &sb) == -1) { /* validate stat of file */
perror("stat");
return 1;
}
localtime_r (&sb.st_mtime, &tmfile); /* get struct tm for file */
localtime_r (&now, &tmnow); /* and now */
if (tmfile.tm_year == tmnow.tm_year) { /* compare year values */
strftime (time_str, sizeof (time_str), "%b %e %H:%M",
&tmfile); /* if year is current output date/time */
printf ("permission 1 user group 12345 %s %s\n",
time_str, argv[i]);
}
else { /* if year is not current, output time/year */
strftime (time_str, sizeof (time_str), "%b %e %Y",
&tmfile);
printf ("permission 1 user group 12345 %s %s\n",
time_str, argv[i]);
}
}
return 0;
}
示例ls -l
输出
$ ls -l tmp.c ls_time_date_fmt.c
-rw-r--r-- 1 david david 1312 Apr 6 03:15 ls_time_date_fmt.c
-rw-r--r-- 1 david david 2615 May 23 2014 tmp.c
计划Use/Output
$ ./bin/ls_time_date_fmt ls_time_date_fmt.c tmp.c
permission 1 user group 12345 Apr 6 03:15 ls_time_date_fmt.c
permission 1 user group 12345 May 23 2014 tmp.c
如果您有任何问题,请告诉我。
我正在 OS X 中实现 ls -la
命令的一个版本。我偶然注意到 ls
命令列出了一些文件的年份和其他文件的时间,如下所示:
-rwxr-xr-x 1 Jenna 197609 3584 Mar 13 2015 untitled1.exe*
drwxr-xr-x 1 Jenna 197609 0 Mar 2 07:48 Videos/
经过一些研究,我发现超过 6 个月的文件会得到一年,而那些没有得到实际时间的文件。如何让这些文件的日期和时间正确显示年份或时间?目前我有以下始终显示时间的代码:
int main()
{
struct stat *fileInfo;
char dir[] = "~/Desktop/file.txt";
stat(dir, &fileInfo);
printf("%.12s ", 4+ctime(&fileInfo->st_mtimespec));
return 0;
}
strftime
是你的朋友。将其格式化为 ls
并不是那么简单。 ls in coreutils 使用的两种格式是
"%b %e %Y"
"%b %e %H:%M"
这是 coreutils 中 ls 文档中的一段
/* TRANSLATORS: ls output needs to be aligned for ease of reading, so be wary of using variable width fields from the locale. Note %b is handled specially by ls and aligned correctly. Note also that specifying a width as in %5b is erroneous as strftime will count bytes rather than characters in multibyte locales. */ N_("%b %e %H:%M")
他们正在考虑诸如区域设置(即多字节字符等)之类的问题。他们还讨论了诸如当文件早于 N 个月时他们会更改其显示方式等问题。您可以在此处找到很多信息...
http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c
对于您的需求,简单一些可能会更好,这里有一些代码可能会为您指明正确的方向。您可以通过将第三个参数更改为 strftime
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(void) {
time_t t;
srand((unsigned) time(&t));
size_t i = 0;
struct timespec ttime;
while(i < 0xffffffff) {\
ttime.tv_sec = i;
i += 3600;
struct tm time_struct;
localtime_r(&ttime.tv_sec, &time_struct);
char time_str[1024];
if(rand() > RAND_MAX/2) {
strftime(time_str, sizeof(time_str), "a == %b %e %Y", &time_struct);
}
else {
strftime(time_str, sizeof(time_str), "b == %b %e %H:%M", &time_struct);
}
printf("%s\n", time_str);
}
exit(0);
}
试一试,看看效果如何。从手册页,调整它会让你真正接近你需要的东西。
size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
The strftime() function formats the information from timeptr into the buffer s, according to the string pointed to by format.
如果我没记错的话,ls -l
输出一个date/time
或输出一个date/year
的决定因素是[=17]返回的mtime
年份=] 匹配 当前 年份。如果文件 mtime
年与 current
年匹配,则提供 date/time
信息,如果 mtime
年不是 当前 年,然后 date/year
提供信息。
为了进行比较,您需要为文件mtime
和now
填写一个struct tm
。下面的例子用localtime_r
填充每个struct tm
,进行比较,然后输出相应的文件详细信息。
(代码将 read/compare mtimes
s 并输出作为参数提供的所有文件名的时间格式。(占位符字符串用于为文件权限、数字、用户提供基本格式、组、大小等)
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#define MAXC 64
void dump_tm (struct tm *t);
int main(int argc, char **argv)
{
int i = 0;
char time_str[MAXC] = "";
time_t now = time (NULL);
struct stat sb;
struct tm tmfile, tmnow;
if (argc < 2) { /* validate sufficient arguments provided */
fprintf (stderr, "error: insufficient input, usage: %s <pathname>\n",
argv[0]);
return 1;
}
for (i = 1; i < argc; i++) { /* for each file given as arg */
if (stat(argv[i], &sb) == -1) { /* validate stat of file */
perror("stat");
return 1;
}
localtime_r (&sb.st_mtime, &tmfile); /* get struct tm for file */
localtime_r (&now, &tmnow); /* and now */
if (tmfile.tm_year == tmnow.tm_year) { /* compare year values */
strftime (time_str, sizeof (time_str), "%b %e %H:%M",
&tmfile); /* if year is current output date/time */
printf ("permission 1 user group 12345 %s %s\n",
time_str, argv[i]);
}
else { /* if year is not current, output time/year */
strftime (time_str, sizeof (time_str), "%b %e %Y",
&tmfile);
printf ("permission 1 user group 12345 %s %s\n",
time_str, argv[i]);
}
}
return 0;
}
示例ls -l
输出
$ ls -l tmp.c ls_time_date_fmt.c
-rw-r--r-- 1 david david 1312 Apr 6 03:15 ls_time_date_fmt.c
-rw-r--r-- 1 david david 2615 May 23 2014 tmp.c
计划Use/Output
$ ./bin/ls_time_date_fmt ls_time_date_fmt.c tmp.c
permission 1 user group 12345 Apr 6 03:15 ls_time_date_fmt.c
permission 1 user group 12345 May 23 2014 tmp.c
如果您有任何问题,请告诉我。