2010-03-09 10 views
6

जीएनयू date आदेश के लिए जानकारी पृष्ठों इस उदाहरण में शामिल हैं:सी में एक टाइमज़ोन से दूसरे में प्रोग्रामेटिक रूप से समय कैसे परिवर्तित करें?

उदाहरण के लिए, जीएनयू date कमांड के साथ जब एक पेरिस घड़ी 6 से पता चलता है कि विचाराधीन "क्या समय न्यूयॉर्क में है जवाब कर सकते हैं : 30am अक्टूबर 31, 2004? " `TZ =" यूरोप/पेरिस "के साथ शुरुआत एक तिथि का उपयोग करके 'के रूप में में दिखाया गया है निम्नलिखित खोल प्रतिलेख:

$ export TZ="America/New_York" 
$ date --date='TZ="Europe/Paris" 2004-10-31 06:30' 
Sun Oct 31 01:30:00 EDT 2004 

इस उदाहरण में,' --date TZ ' संकार्य अपने स्वयं के साथ शुरू होता है' ' सेटिंग, इसलिए के बाकी ऑपरेटिंग ' यूरोप/पेरिस 'नियमों के अनुसार संसाधित किए गए हैं, स्ट्रिंग 2004-10-31 06:30 का इलाज करते हुए जैसे कि पेरिस में थे। हालांकि, date कमान की उत्पादन के बाद से समग्र समय क्षेत्र नियमों के अनुसार कार्रवाई की है, यह न्यूयॉर्क समय का उपयोग करता है। (पेरिस में 2004 में छह घंटे न्यूयॉर्क के आगे सामान्य रूप से था, लेकिन इस उदाहरण एक संक्षिप्त हेलोवीन अवधि को दर्शाता है जब अंतराल पांच घंटे था।)

मैं में प्रोग्राम के एक ही बात अनिवार्य रूप से पूरा करने के लिए कोशिश कर रहा हूँ date प्रोग्राम लाखों बार कॉल किए बिना सी। असल में मैं एक टाइमज़ोन में मनमाने ढंग से दिनांक और समय लेने का तरीका ढूंढ रहा हूं और इसे किसी अन्य समय में समकक्ष दिनांक और समय में सीधे या यूटीसी से रूपांतरण के माध्यम से परिवर्तित कर रहा हूं। मुझे इनपुट और आउटपुट समय के प्रारूपों की परवाह नहीं है जब तक कि मैं मानक कार्यों (strftime/strptime/mktime/आदि) का उपयोग करके उन्हें कुशलतापूर्वक उपयोग कर सकता हूं।

date कार्यक्रम इस coreutils पैकेज के लिए आंतरिक जटिल दिनचर्या का उपयोग कर, मैं या तो मानक POSIX/लिनक्स दिनचर्या या एक बाहरी लाइब्रेरी का उपयोग सी में यह करने के लिए एक तरह से देख रहा हूँ पूरा करने के लिए प्रकट होता है। मैंने zoneinfo पर बहुत कुछ देखा जो आशाजनक लग रहा था लेकिन मुझे इसके साथ कुछ भी उपयोगी करने के लिए कोई पुस्तकालय नहीं मिल रहा है।

उत्तर

2

समय के लिए:

  • gmtime
  • जोड़ें साथ GMT समय प्राप्त/time_t.tm_hour
  • उपयोग mktime से घंटे घटाना renormalize को

तारीख गणना समान होगा लेकिन थोड़ा और जटिल।

+1

मैन्युअल गणनाओं के साथ कई सूक्ष्म मुद्दे शामिल हैं जिन्हें मैं डीएसटी जैसे संभालने से बचने की कोशिश कर रहा हूं। यह जानकारी ज़ोनिन्फो डेटाबेस में निहित है लेकिन इस तरह से नहीं है जो अब तक मेरे लिए उपयोगी साबित हुई है। –

+1

उदा।, यह काम विशेष रूप से वेनेज़ुएला में खराब है - जो आधिकारिक तौर पर यूटीसी -4: 30 – Quintus

3

मैं ऐसे समाधान के साथ आया जो लिनक्स पर ग्लिब के साथ काम करता प्रतीत होता है, मुझे नहीं पता कि यह व्यवहार कितना पोर्टेबल है, पोर्टेबिलिटी के बारे में कोई टिप्पणी या इसके बारे में जाने का बेहतर तरीका स्वागत होगा।

कन्वर्ट_टाइम।ग (कोई त्रुटि स्पष्टता के लिए जाँच):

#define _XOPEN_SOURCE 
#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main (int argc, char *argv[]) 
{ 
    struct tm mytm = {0}; 
    time_t mytime; 
    char buf[100]; 

    mytm.tm_isdst = -1; 
    putenv(argv[1]); 
    tzset(); 
    strptime(argv[2], "%Y-%m-%d %H:%M", &mytm); 
    mytime = mktime(&mytm); 

    putenv(argv[3]); 
    tzset(); 
    localtime_r(&mytime, &mytm); 
    strftime(buf, 100, "%a, %d %b %Y %H:%M:%S %z(%Z)", &mytm); 
    puts(buf); 

    return 0; 
} 

पहला तर्क स्रोत समय क्षेत्र (वास्तव में "TZ = समय-क्षेत्र" putenv को पारित करने के लिए) है, दूसरा तर्क निर्दिष्ट प्रारूप में समय, अंतिम तर्क है गंतव्य टाइमज़ोन है। मैं जोनिनोफ़ टाइमज़ोन नामों का उपयोग कर रहा हूं जो glibc zininfo डेटाबेस का उपयोग करने का समर्थन करता है।

कई डीएसटी परीक्षण कोने मामलों के परिणाम बराबर date आदेश के साथ-साथ this साइट है जो zoneinfo डेटाबेस का उपयोग करता से परिणाम के अनुरूप:

$ ./convert_time "TZ=America/New_York" "2005-05-31 06:30" "TZ=America/Indiana/Indianapolis" 
Tue, 31 May 2005 05:30:00 -0500(EST) 

$ ./convert_time "TZ=America/New_York" "2006-05-31 06:30" "TZ=America/Indiana/Indianapolis" 
Wed, 31 May 2006 06:30:00 -0400(EDT) 

$ ./convert_time "TZ=Europe/Paris" "2004-10-30 06:30" "TZ=America/New_York" 
Sat, 30 Oct 2004 00:30:00 -0400(EDT) 

$ ./convert_time "TZ=Europe/Paris" "2004-10-31 06:30" "TZ=America/New_York" 
Sun, 31 Oct 2004 01:30:00 -0400(EDT) 

$ ./convert_time "TZ=Europe/Paris" "2004-11-01 06:30" "TZ=America/New_York" 
Mon, 01 Nov 2004 00:30:00 -0500(EST) 
+1

यक है, लेकिन आप क्या कर सकते हैं? यह वही है जो मैन पेज कहता है: http://www.kernel.org/doc/man-pages/online/pages/man3/timegm.3.html। यह सिर्फ छिपे हुए थ्रेड असुरक्षित है। – smparkes

0

मैं वास्तव में एक ही जवाब तुमने किया था के लिए देख रहा था, और यह वह समाधान है जिसके साथ मैं आया था। निम्नलिखित नमूना कार्यक्रम स्थानीय सिस्टम समय लेता है और इसे किसी भी समय क्षेत्र में परिवर्तित करता है।

// compile: gcc snippet.c 
// usage: ./a.out Europe/Berlin Pacific/Nauru Asia/Hong_Kong Asia/Kabul 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 
#include <errno.h> 

int main(int argc, char *argv[]) 
{ 
     char buf[80]; 
     time_t tt = time(NULL); 
     struct tm tm; 
     int i; 

     if (!localtime_r(&tt, &tm)) { 
       printf("Could not convert time_t to tm struct. %s\n", strerror(errno)); 
       return 1; 
     } 

     printf("time_t: %ld\n", tt); 
     printf("timezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1], daylight); 
     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm); 
     printf("time: %s\n", buf); 

     for (i = 1; i < argc; ++i) { 
       printf("\ninput: %s\n", argv[i]); 

       snprintf(buf, sizeof(buf), "TZ=%s", argv[i]); 
       putenv(buf); 
       tzset(); 
       printf("\ttimezone: %ld, %s/%s, daylight:%d\n", timezone, tzname[0], tzname[1], daylight); 

       if (!localtime_r(&tt, &tm)) { 
         printf("Could not convert time_t to tm struct. %s\n", strerror(errno)); 
         return 1; 
       } 

       strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z %Z", &tm); 
       printf("\ttime: %s\n", buf); 
     } 

     return 0; 
} 
संबंधित मुद्दे

 संबंधित मुद्दे