2016-04-06 3 views
2

Ich implementiere eine Version von ls -la Befehl in OS X. Ich habe zufällig festgestellt, dass ls Befehl listet Jahre für einige Dateien und Zeiten für andere wie folgt:Formatieren von Datum/Uhrzeit auf die gleiche Weise wie "ls -l" Befehl

-rwxr-xr-x 1 Jenna 197609  3584 Mar 13 2015 untitled1.exe* 
drwxr-xr-x 1 Jenna 197609  0 Mar 2 07:48 Videos/ 

Nach einigen Recherchen fand ich heraus, dass Dateien, die älter als 6 Monate im Jahr, während diejenigen, die nicht bekommt die aktuelle Zeit erhalten werden. Wie erhalte ich das Datum und die Uhrzeit dieser Dateien, um entweder das Jahr oder die Uhrzeit korrekt anzuzeigen? Zur Zeit habe ich den folgenden Code, der immer die Zeit anzeigt:

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

    return 0; 

} 
+1

Werfen Sie einen Blick auf [strftime] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html). Sie können auch 'difftime' verwenden, um herauszufinden, wie alt die Datei ist. – rici

Antwort

1

Wenn ich mich richtig erinnere, der bestimmende Faktor von ls -l zur Ausgabe ein date/time oder Ausgang ein date/year ist, ob das mtime Jahr zurück von stat entspricht der aktuellen Jahre. Wenn die Datei mtime Jahr dem current Jahr entspricht, dann wird date/time Information zur Verfügung gestellt, wenn das mtime Jahr nicht das gegenwärtige Jahr ist, dann date/year Information wird zur Verfügung gestellt.

Um den Vergleich durchzuführen, müssen Sie struct tm für die Datei mtime und now ausfüllen.Das folgende Beispiel verwendet localtime_r, um jedes struct tm zu füllen, macht den Vergleich und gibt dann die Dateidetails entsprechend aus.

(Der Code liest/vergleicht mtimes s und gibt das Zeitformat für alle als Argumente bereitgestellten Dateinamen aus. (Eine Platzhalterzeichenfolge wird verwendet, um grundlegende Formatierungen für Dateiberechtigungen, Anzahl, Benutzer, Gruppe, Größe usw. bereitzustellen).)

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

Beispiel ls -l Ausgabe

$ 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 

Programm 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 

Lassen Sie mich wissen, wenn Sie irgendwelche Fragen haben.

2

strftime ist dein Freund hier. Formatieren Sie es wie ls ist nicht so geradlinig. Die beiden Formate, die ls in coreutils verwendet werden

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

Heres einen Absatz aus der Dokumentation der ls in coreutils

/* ÜBERSETZERN: ls Ausgang zur Erleichterung des Lesens ausgerichtet werden muss, Seien Sie also vorsichtig bei der Verwendung von Feldern mit variabler Breite aus dem Gebietsschema. Hinweis% b wird speziell von ls verarbeitet und korrekt ausgerichtet. Beachten Sie auch, dass die Angabe einer Breite wie in% 5b fehlerhaft ist, da strftime Bytes und nicht Zeichen in Multibyte-Gebietsschemas zählt. */ N _ ("% b% e% H:% M")

Sie sind unter Berücksichtigung Dinge wie Locale dh Mehrbytezeichen etc. Sie auch Dinge wie besprechen, wenn eine Datei ist älter als N Monate sie ändern, wie es angezeigt usw. Sie hier viele Informationen finden ...

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

Für Ihre Bedürfnisse etwas einfacher könnte in Ordnung sein, heres einen Code, den Sie in die richtige Richtung zeigen könnte. Sie können das Format ändern, indem Sie das dritte Argument in strftime ändern.

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

Versuchen Sie es und sehen Sie, was es tut. Von der Manpage aus werden Sie durch das Optimieren sehr nah an das gebracht, was Sie brauchen.

size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr); 

Die Strftime() Funktion formatiert die Informationen von timeptr in den Puffer s nach der String von Format zu spitz.

+0

Nur um zu verdeutlichen, was macht dieser Code? –

+0

Der Code generiert nur Zufallszahlen von '3600' -' 0xffffffff', die entweder die kurze oder die lange Version des Datumsformats ausgeben, abhängig davon, ob 'rand()> RAND_MAX/2' ist. Es hat absolut nichts damit zu tun, wie "ls -l" entscheidet, ob ein Jahr angezeigt werden soll oder nicht. –

+0

Lassen Sie mich es auf Linux und Mac versuchen. – Harry

Verwandte Themen