在做一個時間管理的APP中遇到一些問題
windows linux mac下time.h中都有關於localtime()的定義。
它不是一個保險可靠的方法,使用的時候需要小心。
參考 http://blog.csdn.net/maocl1983/article/details/6221810
在此對原作者表示感謝。
localtime是個靜態的定義,每次得到同一個地址,
不保證得到真確的時間,看具體的代碼:
1 dev-mini:cronc devone$ cat localtime.cpp
2 #include <time.h>
3 #include <cstdio>
4 #include <cstdlib>
5
6 int main( int argc, char *argv[])
7 {
8 time_t tNow =time(NULL);
9 time_t tEnd = tNow + 1800;
10
11 struct tm* ptm = localtime(&tNow);
12 struct tm* ptmEnd = localtime(&tEnd);
13
14 char szTmp[ 50] = { 0};
15 strftime(szTmp, 50, " %H:%M:%S ",ptm);
16 char szEnd[ 50] = { 0};
17 strftime(szEnd, 50, " %H:%M:%S ",ptmEnd);
18
19 printf( " %s \n ",szTmp);
20 printf( " %s \n ",szEnd);
21
22 return EXIT_SUCCESS;
23 }
24 dev-mini:cronc devone$ g++ -o localtime localtime.cpp
25 dev-mini:cronc devone$ ./localtime
26 14: 34: 37
27 14: 34: 37
28 dev-mini:cronc devone$
2 #include <time.h>
3 #include <cstdio>
4 #include <cstdlib>
5
6 int main( int argc, char *argv[])
7 {
8 time_t tNow =time(NULL);
9 time_t tEnd = tNow + 1800;
10
11 struct tm* ptm = localtime(&tNow);
12 struct tm* ptmEnd = localtime(&tEnd);
13
14 char szTmp[ 50] = { 0};
15 strftime(szTmp, 50, " %H:%M:%S ",ptm);
16 char szEnd[ 50] = { 0};
17 strftime(szEnd, 50, " %H:%M:%S ",ptmEnd);
18
19 printf( " %s \n ",szTmp);
20 printf( " %s \n ",szEnd);
21
22 return EXIT_SUCCESS;
23 }
24 dev-mini:cronc devone$ g++ -o localtime localtime.cpp
25 dev-mini:cronc devone$ ./localtime
26 14: 34: 37
27 14: 34: 37
28 dev-mini:cronc devone$
time_t 類型時間 + 1800 ,但是結果輸出都是后者。
修改代碼如下:
1 hzsx@hzsx-server:~/file/test$ cat localtime.cpp
2 #include <time.h>
3 #include <cstdio>
4 #include <cstdlib>
5
6 using namespace std;
7
8 int main( int argc, char *argv[])
9 {
10 time_t tNow =time(NULL);
11 time_t tEnd = tNow + 1800;
12
13 // struct tm* ptm = localtime(&tNow);
14 // struct tm* ptmEnd = localtime(&tEnd);
15 struct tm ptm = { 0 };
16 struct tm ptmEnd = { 0 };
17 localtime_r(&tNow, &ptm);
18 localtime_r(&tEnd, &ptmEnd);
19
20 char szTmp[ 50] = { 0};
21 strftime(szTmp, 50, " %H:%M:%S ",&ptm);
22 char szEnd[ 50] = { 0};
23 strftime(szEnd, 50, " %H:%M:%S ",&ptmEnd);
24 printf( " %s \n ",szTmp);
25 printf( " %s \n ",szEnd);
26
27 return EXIT_SUCCESS;
28 }
29 hzsx@hzsx-server:~/file/test$ g++ -o localtime localtime.cpp
30 hzsx@hzsx-server:~/file/test$ ./localtime
31 14: 07: 45
32 14: 37: 45
33 hzsx@hzsx-server:~/file/test$
2 #include <time.h>
3 #include <cstdio>
4 #include <cstdlib>
5
6 using namespace std;
7
8 int main( int argc, char *argv[])
9 {
10 time_t tNow =time(NULL);
11 time_t tEnd = tNow + 1800;
12
13 // struct tm* ptm = localtime(&tNow);
14 // struct tm* ptmEnd = localtime(&tEnd);
15 struct tm ptm = { 0 };
16 struct tm ptmEnd = { 0 };
17 localtime_r(&tNow, &ptm);
18 localtime_r(&tEnd, &ptmEnd);
19
20 char szTmp[ 50] = { 0};
21 strftime(szTmp, 50, " %H:%M:%S ",&ptm);
22 char szEnd[ 50] = { 0};
23 strftime(szEnd, 50, " %H:%M:%S ",&ptmEnd);
24 printf( " %s \n ",szTmp);
25 printf( " %s \n ",szEnd);
26
27 return EXIT_SUCCESS;
28 }
29 hzsx@hzsx-server:~/file/test$ g++ -o localtime localtime.cpp
30 hzsx@hzsx-server:~/file/test$ ./localtime
31 14: 07: 45
32 14: 37: 45
33 hzsx@hzsx-server:~/file/test$
兩段代碼在linux和mac下通過。
localtime()函數是靜態分配的,共享同一個結構體。所以下一次調用會覆蓋上次的結果。
libc里提供了一個可重入版的函數localtime_r(),如同windows下的localtime_s(),這是一個
安全版本的函數。但是兩者的參數位置正好相反。
下面這段代碼 使用了安全版本的LOCALTIME_R(),在win linux mac下都具有通用性。
1 #include <iostream>
2 #include <time.h>
3 #include <cstdlib>
4 #ifdef WIN32
5 #define LOCALTIME_R(tm,ti) localtime_s(tm,ti)
6 #else
7 #define LOCALTIME_R(tm,ti) localtime_r(ti,tm)
8 #endif
9 int main()
10 {
11 struct tm tmnow = { 0};
12 time_t long_time;
13 time(&long_time);
14 LOCALTIME_R(&tmnow,&long_time);
15 char buftime[ 80];
16 strftime(buftime, 80, " time is : %Y-%m-%d %H:%M:%S ", &tmnow);
17 std::cout << buftime << std::endl;
18 return EXIT_SUCCESS;
2 #include <time.h>
3 #include <cstdlib>
4 #ifdef WIN32
5 #define LOCALTIME_R(tm,ti) localtime_s(tm,ti)
6 #else
7 #define LOCALTIME_R(tm,ti) localtime_r(ti,tm)
8 #endif
9 int main()
10 {
11 struct tm tmnow = { 0};
12 time_t long_time;
13 time(&long_time);
14 LOCALTIME_R(&tmnow,&long_time);
15 char buftime[ 80];
16 strftime(buftime, 80, " time is : %Y-%m-%d %H:%M:%S ", &tmnow);
17 std::cout << buftime << std::endl;
18 return EXIT_SUCCESS;
19 }