Saturday, September 6, 2014

Unix Prog: Time and Date(2)

1. gmtime, localtime

definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/time.h  
 ......  
 struct tm  
 {  
  int tm_sec;          /* Seconds.   [0-60] (1 leap second) */  
  int tm_min;          /* Minutes.   [0-59] */  
  int tm_hour;         /* Hours.    [0-23] */  
  int tm_mday;         /* Day.     [1-31] */  
  int tm_mon;          /* Month.    [0-11] */  
  int tm_year;         /* Year - 1900. */  
  int tm_wday;         /* Day of week. [0-6] */  
  int tm_yday;         /* Days in year.[0-365] */  
  int tm_isdst;         /* DST.     [-1/0/1]*/  
   
 # ifdef __USE_BSD  
  long int tm_gmtoff;      /* Seconds east of UTC. */  
  const char *tm_zone;     /* Timezone abbreviation. */  
 # else  
  long int __tm_gmtoff;     /* Seconds east of UTC. */  
  const char *__tm_zone;    /* Timezone abbreviation. */  
 # endif  
 };  
 ......  
 /* Return the `struct tm' representation of *TIMER  
   in Universal Coordinated Time (aka Greenwich Mean Time). */  
 extern struct tm *gmtime (const time_t *__timer) __THROW;  
   
 /* Return the `struct tm' representation  
   of *TIMER in the local timezone. */  
 extern struct tm *localtime (const time_t *__timer) __THROW;  
 ......  

example, time.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<time.h>  
   
 void printTm(struct tm *tp, time_t tv)  
 {  
  char *fp = "address: %p, sec: %d, min: %d, hour: %d, \  
 day: %d, mon: %d, year: %d, weekday: %d, year day: %d, dst: %d\n";  
  printf("number of seconds after epoch: %ld\n", tv);  
  printf(fp, tp, tp->tm_sec, tp->tm_min, tp->tm_hour, tp->tm_mday,  
      tp->tm_mon, tp->tm_year, tp->tm_wday, tp->tm_yday, tp->tm_isdst);  
 }  
   
 int main(int argc, char* argv[])  
 {  
  struct tm *tp;  
  time_t tv;  
   
  // Get the current time value  
  if((tv = time(NULL)) < 0) {  
   printf("time error!\n");  
   exit(1);  
  }  
   
  // convert to the UTC time  
  if((tp = gmtime(&tv)) == NULL) {  
   printf("gmtime error!\n");  
   exit(2);  
  }  
   
  printTm(tp, tv);  
   
  // convert to the local time  
  if((tp = localtime(&tv)) == NULL) {  
   printf("localtime error!\n");  
   exit(3);  
  }  
   
  printTm(tp, tv);  
   
  exit(0);  
 }  

shell:
Current time is: 2014/09/06 3:38pm Saturday.
1) Run the program without setting up the timezone. After getting the current time_t value, gmtime and localtime return the struct tm with same address. So whenever a system call returning "struct tm" is called, it probably just fill in at the same struct which will overwrite the old information. Because we don't setup the timezone, the local time info is same as UTC time.
2) Run the program while setting up the timezone. After getting the current time_t value, it just return us the global UTC time info and local time info.
dst:1 means daylight saving mode is on now.
 ubuntu@ip-172-31-23-227:~$ ./time.out  
 number of seconds after epoch: 1410032314  
 address: 0x7fcae72ffde0, sec: 34, min: 38, hour: 19, day: 6, mon: 8, year: 114, weekday: 6, year day: 248, dst: 0  
 number of seconds after epoch: 1410032314  
 address: 0x7fcae72ffde0, sec: 34, min: 38, hour: 19, day: 6, mon: 8, year: 114, weekday: 6, year day: 248, dst: 0  
 ubuntu@ip-172-31-23-227:~$ TZ=EST5EDT ./time.out  
 number of seconds after epoch: 1410032322  
 address: 0x7fa7b0964de0, sec: 42, min: 38, hour: 19, day: 6, mon: 8, year: 114, weekday: 6, year day: 248, dst: 0  
 number of seconds after epoch: 1410032322  
 address: 0x7fa7b0964de0, sec: 42, min: 38, hour: 15, day: 6, mon: 8, year: 114, weekday: 6, year day: 248, dst: 1  

2. mktime
mktime takes a broken down time, and converts it into a time_t value

definition:
 ubuntu@ip-172-31-23-227:~$ less /usr/include/time.h  
 ......  
 /* Return the `time_t' representation of TP and normalize TP. */  
 extern time_t mktime (struct tm *__tp) __THROW;  
 ......  

example, time.c:
 #include<stdio.h>  
 #include<stdlib.h>  
 #include<time.h>  
   
 int main(int argc, char* argv[])  
 {  
  struct tm *tp;  
  time_t tv;  
   
  // Get the current time value  
  if((tv = time(NULL)) < 0) {  
   printf("time error!\n");  
   exit(1);  
  }  
   
  printf("%ld, ", tv);  
   
  // convert to the local time  
  if((tp = localtime(&tv)) == NULL) {  
   printf("localtime error!\n");  
   exit(2);  
  }  
   
  // convert the struct tm to number of seconds  
  if((tv = mktime(tp)) < 0) {  
   printf("mktime error!\n");  
   exit(3);  
  }  
   
  printf("%ld\n", tv);  
   
  exit(0);  
 }  

shell:
Run the program to get the current time value, convert it to local time struct tm, and then use "mktime" command to convert struct tm back to time value. The result is: later value is same as the previous one. It also indicates that mktime is based on local time zone to convert the time value.

 ubuntu@ip-172-31-23-227:~$ ./time.out  
 1410033756, 1410033756  

No comments:

Post a Comment