2012-12-10 33 views
14

में ऑफसेट मैं एक युग समय मूल्य में एक struct tm चालू करने के लिए मानक mktime समारोह का उपयोग कर रहा हूँ। tm क्षेत्रों स्थानीय रूप से भर जाते हैं, और मैं जीएमटी के रूप में युग समय प्राप्त करने की आवश्यकता। tm एक gmtoff क्षेत्र आप स्थानीय GMT सिर्फ इस उद्देश्य के लिए सेकंड में ऑफसेट सेट करने के लिए अनुमति देने के लिए है।समय क्षेत्र जाओ जीएमटी सी

लेकिन मुझे यह पता नहीं लगा सकता कि उस जानकारी को कैसे प्राप्त करें। निश्चित रूप से कहीं मानक कार्य होना चाहिए जो ऑफ़सेट लौटाएगा? localtime यह कैसे करता है?

+1

"' tm' एक 'gmtoff' क्षेत्र है" -> कि एक गैर मानक सी पुस्तकालय विस्तार है। – chux

उत्तर

5

से पहले बुलाया जाना चाहिए मुझे लगता है मैं पूछ रहा से पहले खोज में थोड़ा और अधिक करना चाहिए था। यह पता चला है कि timegm फ़ंक्शन थोड़ा ज्ञात है जो gmtime के विपरीत करता है। यह जीएनयू और बीएसडी पर समर्थित है जो मेरे उद्देश्यों के लिए पर्याप्त है। एक और पोर्टेबल समाधान TZ पर्यावरण चर को "यूटीसी" के अस्थायी रूप से सेट करना है और फिर mktime का उपयोग करें, फिर TZ सेट करें।

लेकिन timegm मेरे लिए काम करता है।

+3

लिंक कहता है "ये कार्य गैर-मानक जीएनयू एक्सटेंशन हैं जो बीएसडी पर भी मौजूद हैं। उनके उपयोग से बचें।" – satur9nine

0

मेरा मानना ​​है कि निम्नलिखित लिनक्स में सच में कम से कम है: समयक्षेत्र जानकारी/usr/share/zoneinfo/से आता है। लोकलटाइम/etc/localtime पढ़ता है जो जोनिनोफ़ो से उपयुक्त फ़ाइल की एक प्रति होना चाहिए। आप समय क्षेत्र फ़ाइल पर zdump -v करके क्या अंदर देख सकते हैं (zdump sbin में हो सकता है, लेकिन आप ऊंचा अनुमतियाँ की जरूरत नहीं है इसके साथ समय क्षेत्र फ़ाइलों को पढ़ने के लिए)। यहां एक स्निप किया गया है:

 
/usr/share/zoneinfo/EST5EDT Sun Nov 6 05:59:59 2033 UTC = Sun Nov 6 01:59:59 2033 EDT isdst=1 gmtoff=-14400 
/usr/share/zoneinfo/EST5EDT Sun Nov 6 06:00:00 2033 UTC = Sun Nov 6 01:00:00 2033 EST isdst=0 gmtoff=-18000 
/usr/share/zoneinfo/EST5EDT Sun Mar 12 06:59:59 2034 UTC = Sun Mar 12 01:59:59 2034 EST isdst=0 gmtoff=-18000 
/usr/share/zoneinfo/EST5EDT Sun Mar 12 07:00:00 2034 UTC = Sun Mar 12 03:00:00 2034 EDT isdst=1 gmtoff=-14400 
/usr/share/zoneinfo/EST5EDT Sun Nov 5 05:59:59 2034 UTC = Sun Nov 5 01:59:59 2034 EDT

मुझे लगता है कि यदि आप चाहें तो आप इसे स्वयं पार्स कर सकते हैं। मुझे यकीन नहीं है कि एक stdlib फ़ंक्शन है जो केवल gmtoff लौटाता है (वहां अच्छा हो सकता है लेकिन मुझे नहीं पता ...)

संपादित करें: मैन tzfile zininfo फ़ाइल के प्रारूप का वर्णन करता है। आप उचित प्रकार की संरचना में बस एमएमएपी करने में सक्षम होना चाहिए। ऐसा लगता है कि zdump इसके एक कंगन के आधार पर क्या कर रहा है।

#define _GNU_SOURCE /* for tm_gmtoff and tm_zone */ 

#include <stdio.h> 
#include <time.h> 

/* Checking errors returned by system calls was omitted for the sake of readability. */ 
int main(void) 
{ 
    time_t t = time(NULL); 
    struct tm lt = {0}; 

    localtime_r(&t, &lt); 

    printf("Offset to GMT is %lds.\n", lt.tm_gmtoff); 
    printf("The time zone is '%s'.\n", lt.tm_zone); 

    return 0; 
} 

नोट::

19

बस निम्न कार्य time() द्वारा दिया अवधि के बाद सेकंड के रूप में ग्रीनविच में अगर मापा जाता है।

+0

मुझे वास्तव में यह आसान समाधान पसंद है, लेकिन मुझे आपके कोड के साथ एक समस्या मिली। मुझे लगता है कि 'संरचना tm = {0}; '' tt result = {0} होना चाहिए;' और फिर आप शेष कोड में 'tm' के बजाय 'परिणाम' का उपयोग कर सकते हैं। अगर आप इसे बदल सकते हैं तो मुझसे +1। – Serrano

+3

इसके अलावा मैं विंडोज़ के लिए कोड देखना चाहता हूं। किसी भी मदद की सराहना की! –

+2

'tm_gmtoff, tm_zone' गैर-सी स्टडी एक्सटेंशन हैं। – chux

4

स्थानीयसमय यह कैसे करता है?

localtime आदमी पृष्ठ के अनुसार

स्थानीयसमय() फ़ंक्शन में कार्य करता है जैसे कि वह tzset (3) और सेट बाहरी चर वर्तमान समय क्षेत्र के बारे में जानकारी के साथ tzname, समय क्षेत्र बुलाया कोऑर्डिनेटेड यूनिवर्सल समय (यूटीसी) और सेकंड में स्थानीय मानक समय

012 के बीच अंतर के साथ

तो आप या तो localtime() कह सकते हैं और आप timezone में अंतर होगा या tzset() फोन:

extern long timezone; 
.... 
tzset(); 
printf("%ld\n", timezone); 

नोट: यदि आप localtime_r() ध्यान दें कि यह उन चर आप की आवश्यकता होगी स्थापित करने के लिए आवश्यक नहीं है के साथ जाने के लिए चुन tzset()timezone स्थापित करने के लिए पहले फोन:

POSIX.1-2004 के अनुसार, स्थानीयसमय() व्यवहार करने के लिए के रूप में यद्यपि tzset() कहा जाता था की आवश्यकता है, जबकि localtime_r() हवलदार नहीं है ई आवश्यकता।पोर्टेबल कोड tzset के लिए() localtime_r()

2

स्थानीय समय ऑफसेट फ़ंक्शन प्राप्त करने का सार्वभौमिक संस्करण यहां है।
मैंने statckoverflow में the answer से कोड के टुकड़े उधार लिया।

int time_offset() 
{ 
    time_t gmt, rawtime = time(NULL); 
    struct tm *ptm; 

#if !defined(WIN32) 
    struct tm gbuf; 
    ptm = gmtime_r(&rawtime, &gbuf); 
#else 
    ptm = gmtime(&rawtime); 
#endif 
    // Request that mktime() looksup dst in timezone database 
    ptm->tm_isdst = -1; 
    gmt = mktime(ptm); 

    return (int)difftime(rawtime, gmt); 
}