जवाबों:
विकिपीडिया का लेख_ लेख इस पर कुछ प्रकाश डालता है। लब्बोलुआब यह है कि time_t
सी विनिर्देश में प्रकार की गारंटी नहीं है।
time_t
डेटाप्रकार आईएसओ सी पुस्तकालय प्रणाली समय मान संग्रहीत करने के लिए परिभाषित में एक डेटा प्रकार है। ऐसे मान मानकtime()
लाइब्रेरी फ़ंक्शन से वापस किए जाते हैं । यह प्रकार एक मानक हेडर में परिभाषित टाइपडिफ है। ISO C एक अंकगणितीय प्रकार के रूप में time_t को परिभाषित करता है, लेकिन इसके लिए कोई विशेष प्रकार , सीमा, संकल्प या एन्कोडिंग निर्दिष्ट नहीं करता है। अनिर्दिष्ट भी समय के मूल्यों पर लागू अंकगणितीय संचालन के अर्थ हैं।यूनिक्स और पोसिक्स-कंप्लायंट सिस्टम
time_t
एकsigned integer
(आमतौर पर 32 या 64 बिट्स चौड़े) प्रकार को लागू करते हैं, जो यूनिक्स के शुरू होने के बाद से कुछ सेकंड की संख्या का प्रतिनिधित्व करता है : 1 जनवरी, 1970 की मध्यरात्रि यूटीसी (लीप सेकंड की गिनती नहीं)। कुछ सिस्टम नकारात्मक समय मानों को सही ढंग से संभालते हैं, जबकि अन्य नहीं करते हैं। 32-बिटtime_t
प्रकार का उपयोग करने वाले सिस्टम वर्ष 2038 समस्या के लिए अतिसंवेदनशील होते हैं ।
time_t
ऑन-डिस्क डेटा संरचना का उपयोग करके हो सकता है। हालाँकि, चूंकि फाइलसिस्टम को अक्सर अन्य ऑपरेटिंग सिस्टम द्वारा पढ़ा जाता है, ऐसे कार्यान्वयन-निर्भर प्रकारों के आधार पर फाइल सिस्टम को परिभाषित करना मूर्खतापूर्ण होगा। उदाहरण के लिए, एक ही फाइल सिस्टम 32-बिट और 64-बिट सिस्टम दोनों पर उपयोग किया जा सकता है, और time_t
आकार बदल सकता है। इस प्रकार, फाइलसिस्टम को अधिक सटीक रूप से परिभाषित करने की आवश्यकता है ("32-बिट हस्ताक्षरित पूर्णांक देने वाले सेकंड की संख्या, 1970 की शुरुआत के बाद से, यूटीसी में") केवल की तुलना में time_t
।
time.h
सामग्री की सूची पर पुनर्निर्देशित करता है । यह लेख cppreference.com से लिंक करता है, लेकिन उद्धृत सामग्री कहीं नहीं पाई जा सकती है ...
time_t
वह हस्ताक्षरित है। pubs.opengroup.org/onlinepubs/9699919799/basedefs/… यह बताता है कि विभिन्न चीजों में "हस्ताक्षरित पूर्णांक प्रकार" या "अहस्ताक्षरित पूर्णांक प्रकार" होना चाहिए, लेकिन time_t
यह केवल यह कहता है कि यह "पूर्णांक प्रकार होगा" । एक कार्यान्वयन time_t
अहस्ताक्षरित हो सकता है और अभी भी POSIX- अनुरूप हो सकता है।
[root]# cat time.c
#include <time.h>
int main(int argc, char** argv)
{
time_t test;
return 0;
}
[root]# gcc -E time.c | grep __time_t
typedef long int __time_t;
इसके $INCDIR/bits/types.h
माध्यम से परिभाषित किया गया है:
# 131 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/typesizes.h" 1 3 4
# 132 "/usr/include/bits/types.h" 2 3 4
typedef __int32_t __time_t;
और typedef __time_t time_t;
ए FreeBSD freebsd-test 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #8: Sun Aug 7 18:23:48 UTC 2011 root@freebsd-test:/usr/obj/usr/src/sys/MYXEN i386
। आपके परिणाम स्पष्ट रूप से लिनक्स (जैसे कम से कम 2.6.32-5-xen-amd64 पर डेबियन से) में सेट किए गए हैं।
__time_t
और नहीं time_t
की अंतर्निहित प्रकार खोजने के लिए time_t
? एक कदम आगे बढ़ाना?
typedef __time_t time_t;
, भले ही ओपी ने पाया हो , आसपास के कोड की परीक्षा में यह सुनिश्चित करने की भी आवश्यकता है कि टाइपफेड वास्तव में इस्तेमाल किया गया था और न केवल एक सशर्त संकलन का हिस्सा था। typedef long time_t;
शायद मिल भी गया हो।
मानक
विलियम ब्रेंडल ने विकिपीडिया को उद्धृत किया, लेकिन मैं इसे घोड़े के मुंह से पसंद करता हूं।
C99 N1256 मानक ड्राफ्ट 7.23.1 / 3 "समय के घटक" कहते हैं:
घोषित प्रकार size_t (7.17 में वर्णित) घड़ी_टी और time_t हैं जो अंकगणितीय प्रकार हैं जो समय का प्रतिनिधित्व करने में सक्षम हैं
और 6.2.5 / 18 "प्रकार" कहते हैं:
पूर्णांक और फ्लोटिंग प्रकारों को सामूहिक रूप से अंकगणितीय प्रकार कहा जाता है।
POSIX 7 sys_types.h कहता है:
[CX] time_t पूर्णांक प्रकार होगा।
जहां [CX]
है के रूप में परिभाषित :
[सीएक्स] आईएसओ सी मानक के लिए विस्तार।
यह एक विस्तार है क्योंकि यह एक मजबूत गारंटी देता है: फ्लोटिंग पॉइंट्स बाहर हैं।
एक-लाइनर
क्वासोई द्वारा बताई गई फ़ाइल बनाने की आवश्यकता नहीं है :
echo | gcc -E -xc -include 'time.h' - | grep time_t
Ubuntu 15.10 GCC 5.2 पर शीर्ष दो लाइनें हैं:
typedef long int __time_t;
typedef __time_t time_t;
से कुछ उद्धरण के साथ कमांड ब्रेकडाउन man gcc
:
-E
: "प्रीप्रोसेसिंग स्टेज के बाद रुकें; कंपाइलर को ठीक से न चलाएं।"-xc
: C भाषा निर्दिष्ट करें, क्योंकि इनपुट स्टैड से आता है जिसमें कोई फ़ाइल एक्सटेंशन नहीं है।-include file
: "प्रक्रिया फ़ाइल जैसे कि" #include "फ़ाइल" "प्राथमिक स्रोत फ़ाइल की पहली पंक्ति के रूप में दिखाई दी।"-
: स्टड से इनपुटgcc -E -xc -include time.h /dev/null | grep time_t
उत्तर निश्चित रूप से कार्यान्वयन-विशिष्ट है। अपने प्लेटफ़ॉर्म / कंपाइलर के लिए निश्चित रूप से जानने के लिए, इस आउटपुट को अपने कोड में कहीं जोड़ें:
printf ("sizeof time_t is: %d\n", sizeof(time_t));
यदि उत्तर 4 (32 बिट्स) है और आपका डेटा 2038 से आगे जाने के लिए है , तो आपके पास अपने कोड को स्थानांतरित करने के लिए 25 वर्ष हैं।
यदि आप अपना डेटा स्ट्रिंग के रूप में संग्रहीत करते हैं तो भी आपका डेटा ठीक रहेगा, भले ही यह कुछ सरल हो:
FILE *stream = [stream file pointer that you've opened correctly];
fprintf (stream, "%d\n", (int)time_t);
तो बस इसे उसी तरह से वापस पढ़ें (फ़्रेड, fscanf, आदि को एक इंट में), और आपके पास अपने समय की भरपाई का समय है। .Net में एक समान वर्कअराउंड मौजूद है। मैं विन और लिनक्स सिस्टम के बीच 64-बिट युग संख्या को बिना किसी समस्या के (एक संचार चैनल पर) पास करता हूं। यह बाइट-ऑर्डर करने के मुद्दों को लाता है, लेकिन यह एक और विषय है।
Paxdiablo की क्वेरी का उत्तर देने के लिए, मैं कहूंगा कि यह "19100" मुद्रित है क्योंकि कार्यक्रम इस तरह से लिखा गया था (और मैं मानता हूं कि मैंने खुद को 80 के दशक में किया था:
time_t now;
struct tm local_date_time;
now = time(NULL);
// convert, then copy internal object to our object
memcpy (&local_date_time, localtime(&now), sizeof(local_date_time));
printf ("Year is: 19%02d\n", local_date_time.tm_year);
printf
"1900 के बाद से वर्ष" के साथ एक शून्य गद्देदार स्ट्रिंग हो (की परिभाषा: बयान तय स्ट्रिंग "19 साल है" प्रिंट tm->tm_year
)। 2000 में, यह मान 100 है, जाहिर है। "%02d"
दो शून्य के साथ पैड, लेकिन दो अंकों से अधिक समय तक नहीं काटता है।
सही तरीका है (केवल अंतिम पंक्ति में परिवर्तन):
printf ("Year is: %d\n", local_date_time.tm_year + 1900);
नया सवाल: उस सोच के लिए तर्क क्या है?
%zu
प्रारूप size_t
मानों का उपयोग प्रारूप मानों के अनुसार करना चाहिए (जैसा sizeof
कि उनके द्वारा दिया गया है ), क्योंकि वे अहस्ताक्षरित हैं ( u
) और लंबाई size_t ( z
) ·
printf ("sizeof time_t is: %d\n", (int) sizeof(time_t));
और z
मुद्दे से बचें ।
विजुअल स्टूडियो 2008 के तहत, यह __int64
परिभाषित करता है जब तक कि आप परिभाषित नहीं करते _USE_32BIT_TIME_T
। आप केवल दिखावा करने से बेहतर हैं कि आप यह नहीं जानते कि इसे किस रूप में परिभाषित किया गया है, क्योंकि यह प्लेटफॉर्म से प्लेटफॉर्म में बदल सकता है (और करेगा)।
time_t
प्रकार का है long int
, वरना यह है 64 बिट मशीनों पर long long int
।
आप इन हेडर फ़ाइलों में इसे सत्यापित कर सकते हैं:
time.h
: /usr/include
types.h
और typesizes.h
:/usr/include/x86_64-linux-gnu/bits
(नीचे दिए गए कथन एक के बाद एक नहीं हैं। उन्हें Ctrl + f खोज का उपयोग करके शीर्ष लेख फ़ाइल में पाया जा सकता है।)
में 1 time.h
typedef __time_t time_t;
2) में types.h
# define __STD_TYPE typedef
__STD_TYPE __TIME_T_TYPE __time_t;
3) में typesizes.h
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
#if defined __x86_64__ && defined __ILP32__
# define __SYSCALL_SLONG_TYPE __SQUAD_TYPE
#else
# define __SYSCALL_SLONG_TYPE __SLONGWORD_TYPE
#endif
4) में फिर से types.h
#define __SLONGWORD_TYPE long int
#if __WORDSIZE == 32
# define __SQUAD_TYPE __quad_t
#elif __WORDSIZE == 64
# define __SQUAD_TYPE long int
#if __WORDSIZE == 64
typedef long int __quad_t;
#else
__extension__ typedef long long int __quad_t;
long int
हर जगह नहीं है। देखें stackoverflow.com/questions/384502/…
यह अधिकांश विरासत प्लेटफार्मों पर एक 32-बिट हस्ताक्षरित पूर्णांक प्रकार है। हालाँकि, इससे आपका कोड वर्ष 2038 बग से पीड़ित होगा । इसलिए आधुनिक सी लाइब्रेरीज़ को इसके बजाय एक हस्ताक्षरित 64-बिट इंट होने के लिए परिभाषित किया जाना चाहिए, जो कुछ अरब वर्षों के लिए सुरक्षित है।
आमतौर पर आप इन अंतर्निहित कार्यान्वयन-विशिष्ट टाइपिडिफ को gcc bits
या asm
हेडर डायरेक्टरी में देख पाएंगे । मेरे लिए, यह है/usr/include/x86_64-linux-gnu/bits/types.h
।
आप केवल विशिष्ट grep को देख सकते हैं, या उस तरह के प्रीप्रोसेसर इनविटेशन का उपयोग कर सकते हैं, जो Quassnoi द्वारा सुझाया गया है कि कौन से विशिष्ट शीर्ष लेख देखें।
आखिरकार एक time_t typedef क्या है?
रोबस्ट कोड को परवाह नहीं है कि प्रकार क्या है।
सी प्रजातियाँ time_t
एक वास्तविक प्रकार की तरह होती हैंdouble, long long, int64_t, int
, आदि।
यहां तक कि यह भी हो सकता है unsigned
कि कई बार फ़ंक्शन से वापसी मान इंगित करते हैं कि त्रुटि नहीं है -1
, लेकिन(time_t)(-1)
- यह कार्यान्वयन विकल्प असामान्य नहीं है।
मुद्दा यह है कि "जरूरत-से-पता" प्रकार दुर्लभ है। जरूरत से बचने के लिए कोड लिखा होना चाहिए।
फिर भी एक आम "जरूरत-से-पता" तब होता है जब कोड कच्चे प्रिंट करना चाहता है time_t
। सबसे व्यापक पूर्णांक प्रकार पर कास्टिंग सबसे आधुनिक मामलों को समायोजित करेगा।
time_t now = 0;
time(&now);
printf("%jd", (intmax_t) now);
// or
printf("%lld", (long long) now);
double
या के लिए कास्टिंग long double
भी काम करेगा, फिर भी अनुभवहीन दशमलव उत्पादन प्रदान कर सकता है
printf("%.16e", (double) now);
double difftime(time_t time1, time_t time0)
एक समान घटाव दृष्टिकोण के लिए प्रदान करता है ।
time_t
सिर्फ typedef
8 बाइट्स ( long long/__int64
) के लिए है, जो सभी कंपाइलर और ओएस को समझते हैं। वापस दिनों में, यह केवल long int
(4 बाइट्स) के लिए हुआ करता था, लेकिन अब नहीं। आप को देखो, तो time_t
में crtdefs.h
आप दोनों कार्यान्वयन मिलेगा लेकिन ओएस का उपयोग करेगा long long
।
long int
।