天天看點

C語言中對時間和日期的處理

大部分的作業系統有辦法得到目前的日期和時間。通過定義在time.h的庫函數,ANSI C能以許多不同的形式得到這個資訊。函數time傳回一個類型為time_t的值(通常為long),該函數在運作期間對目前的日期和時間進行編碼。然後你可以将這個傳回值傳遞給其他能對該值進行解碼和格式化的函數。

大多數作業系統為檔案維護時間/日期戳。至少你能得知一個檔案最後被修改的時間。(常用的make工 具使用這一資訊來決定一個檔案是否需要被重新編譯,或者一個應用程式是否需要被重新連接配接)。由于檔案系統在不同平台上有所不同,沒有什麼通用的函數得到一 個檔案的時間/日期戳,是以ANSI 标準沒有定義這樣的函數。然而,大多數流行的作業系統(包括MS-DOS和VAX/VMS)提供了UNIX函數stat,該函數傳回相關的檔案資訊,包括用time_t表示的最後修改時間。

#include <stdio.h>

#include <time.h>

#define BUFSIZE 128

main()

{

   time_t tval;

   struct tm *now;

   char buf[BUFSIZE];

   char *fancy_format =

     "Or getting really fancy:\n"

     "%A, %B %d, day %j of %Y.\n"

     "The time is %I:%M %p.";

   /* Get current date and time */

   tval = time(NULL);

   now = localtime(&tval);

   printf("The current date and time:\n"

         "%d/%02d/%02d %d:%02d:%02d\n\n",

     now->tm_mon+1, now->tm_mday, now->tm_year,

     now->tm_hour, now->tm_min, now->tm_sec);

   printf("Or in default system format:\n%s\n",

         ctime(&tval));

   strftime(buf,sizeof buf,fancy_format,now);

   puts(buf);

   return 0;

}

/*  Output

The current date and time:

10/06/92 12:58:00

Or in default system format:

Tue Oct 06 12:58:00 1992

Or getting really fancy:

Tuesday, October 06, day 280 of 1992.

The time is 12:58 PM.

*/

/* End of File */

#include <stdlib.h>

   time_t start, stop;

   int ndays;

   time(&start);

   now = localtime(&start);

   /* Enter an interval in days */

   fputs("How many days from now? ",stderr);

   if (scanf("%d",&ndays) !=1)

      return EXIT_FAILURE;

   now->tm_mday += ndays;

   if (mktime(now) != -1)

      printf("New date: %s",asctime(now));

   else

      puts("Sorry. Can't encode your date.");

   /* Calculate elapsed time */

   time(&stop);

   printf("Elapsed program time in seconds: %f\n",

     difftime(stop,start));

   return EXIT_SUCCESS;

/* Output

How many days from now? 45

New date: Fri Nov 20 12:40:32 1992

Elapsed program time in seconds: 1.000000

struct Date

   int day;

   int month;

   int year;

};

typedef struct Date Date;

Date* date_interval(const Date *, const Date *);

/* date_int.c: Compute duration between two dates */

#include "date.h"

#define isleap(y) \

 ((y)%4 == 0 && (y)%100 != 0 || (y)%400 == 0)

static int Dtab [2][13] =

  {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},

  {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

Date *date_interval(const Date *d1, const Date *d2)

   static Date result;

   int months, days, years, prev_month;

   /* Compute the interval - assume d1 precedes d2 */

   years = d2->year - d1->year;

   months = d2->month - d1->month;

   days = d2->day - d1->day;

   /* Do obvious corrections (days before months!)

    *

    * This is a loop in case the previous month is

    * February, and days < -28.

    */

   prev_month = d2->month - 1;

   while (days < 0)

   {

      /* Borrow from the previous month */

      if (prev_month == 0)

         prev_month = 12;

      --months;

      days += Dtab[isleap(d2->year)][prev_month--];

   }

   if (months < 0)

      /* Borrow from the previous year */

      --years;

      months += 12;

   /* Prepare output */

   result.month = months;

   result.day = days;

   result.year = years;

   return &result;

/* tdate.c: Test date_interval() */

   Date d1, d2, *result;

   int nargs;

   /* Read in two dates - assume 1st precedes 2nd */

   fputs("Enter a date, MM/DD/YY> ",stderr);

   nargs = scanf("%d/%d/%d%*c", &d1.month,

     &d1.day, &d1.year);

   if (nargs != 3)

   fputs("Enter a later date, MM/DD/YY> ",stderr);

   nargs = scanf("%d/%d/%d%*c", &d2.month,

     &d2.day, &d2.year);

   /* Compute interval in years, months, and days */

   result = date_interval(&d1, &d2);

   printf("years: %d, months: %d, days: %d\n",

      result->year, result->month, result->day);

/* Sample Execution:

Enter a date, MM/DD/YY> 10/1/51

Enter a later date, MM/DD/YY> 10/6/92

years: 41, months: 0, days: 5 */

/* ftime.c: Compare file time stamps */

#include <sys/stat.h>

   struct stat fs1, fs2;

   if (stat("time1.c",&fs1) == 0 &&

      stat("time2.c",&fs2) == 0)

      double interval =

        difftime(fs2.st_mtime,fs1.st_mtime);

      printf("time1.c %s newer than time2.c\n",

        (interval < 0.0) ? "is" : "is not");

      return EXIT_SUCCESS;

time1.c is not newer than time2.c */

/* touch.c: Update a file's time stamp */

void touch(char *fname)

   FILE *f = fopen(fname,"r+b");

   if (f != NULL)

      char c = getc(f);

      rewind(f);

      putc(c,f);

      fopen(fname,"wb");

   fclose(f);

繼續閱讀