简体   繁体   English

以与“ ls -l”命令相同的方式格式化日期/时间

[英]Formatting date/time in the same way as “ls -l” command

I am implementing a version of ls -la command in OS X. I happened to notice that ls command lists years for some files and times for others as shown below: 我正在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/

After some research, I found out that files older than 6 months gets a year while those that are not get the actual time. 经过研究,我发现6个月以上的文件可以得到一年,而6个月以上的文件不能得到实际时间。 How do I get the date and times of these files to correctly display either the year or time ? 如何获取这些文件的日期和时间以正确显示年份或时间? Currently I have the following code which always displays the time: 目前,我有以下代码始终显示时间:

int main()
{
   struct stat *fileInfo;
   char dir[] = "~/Desktop/file.txt";
   stat(dir, &fileInfo); 
   printf("%.12s ", 4+ctime(&fileInfo->st_mtimespec));

   return 0;

}

strftime is your friend here. strftime是您的朋友在这里。 Formatting it like ls is not that straight forward. ls一样格式化不是那么简单。 The two formats that ls in coreutils is using are ls在coreutils中使用的两种格式是

"%b %e  %Y"
"%b %e %H:%M"

Heres one paragraph from the docs of the ls in coreutils 这是coreutils中ls文档的一个段落

/* TRANSLATORS: ls output needs to be aligned for ease of reading, so be wary of using variable width fields from the locale. / *译者:ls的输出需要对齐以便于阅读,因此请谨慎使用语言环境中的可变宽度字段。 Note %b is handled specially by ls and aligned correctly. 注意%b由ls特别处理并正确对齐。 Note also that specifying a width as in %5b is erroneous as strftime will count bytes rather than characters in multibyte locales. 还要注意,在%5b中指定宽度是错误的,因为strftime将计算字节数而不是多字节语言环境中的字符。 */ N_("%b %e %H:%M") * / N _(“%b%e%H:%M”)

They're taking into consideration things like Locale ie multibyte characters etc. They also discuss things like when a file is older than N months they change how it's displayed etc. You can find a lot of information here... 他们正在考虑诸如语言环境(即多字节字符等)之类的问题。他们还讨论诸如文件大于N个月时它们会更改其显示方式之类的问题。您可以在此处找到很多信息...

http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c

For your needs something simpler might be fine, heres some code that might point you in the correct direction. 对于您的需求,更简单的方法可能会有用,以下代码可能会为您指明正确的方向。 You can change the format to whatever you want by changing the third argument to strftime . 通过将第三个参数更改为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);
}

Try it and see what it does. 试试看,看看它能做什么。 From the man page, tweaking it will get you really close to what you need. 在手册页上进行调整可让您真正接近所需。

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. strftime()函数根据format指向的字符串将来自timeptr的信息格式化为缓冲区s。

If I recall correctly, the determining factor used by ls -l to output a date/time or output a date/year is whether the mtime year returned by stat matches the current year. 如果我没记错的话, ls -l用于输出date/time或输出date/year的决定因素是stat返回的mtime年是否与当前年相匹配。 If the file mtime year matches the current year, then date/time information is provided, if the mtime year is not the current year, then date/year information is provided. 如果文件mtime年与current年匹配,则提供date/time信息,如果mtime年不是当前年,则提供date/year信息。

In order to make the comparison, you need to fill a struct tm for both the file mtime and now . 为了进行比较,您需要为文件mtimenow都填充一个struct tm The following example uses localtime_r to fill each struct tm , makes the comparison, and then outputs the file details accordingly. 下面的示例使用localtime_r填充每个struct tm ,进行比较,然后相应地输出文件详细信息。

(the code will read/compare mtimes s and output the time format for all filenames provided as arguments. (a placeholder string is used to provide basic formatting for the file permissions, number, user, group, size, etc.) (代码将读取/比较mtimes并输出所有作为参数提供的文件名的时间格式。(占位符字符串用于提供文件权限,数字,用户,组,大小等的基本格式)

#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;
}

Example ls -l Output 示例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

Program 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

Let me know if you have any questions. 如果您有任何疑问,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM