2011-04-08 16 views
14

से डेलाइट सेविंग टाइम की गणना करना मैं एक Arduino और रीयल टाइम घड़ी चिप के साथ काम कर रहा हूं। चिप लीप साल और इस तरह की क्षतिपूर्ति करता है, इसलिए इसमें हमेशा सही तिथि होगी, लेकिन यह डेलाइट सेविंग टाइम को संभाल नहीं पाती है, मुझे क्षेत्रीय जटिलताओं के कारण लगता है। घड़ी मुझे दिन, महीना, और वर्ष (1 आधारित) और सप्ताह के दिन (रविवार = 0 शनिवार = 6) दे सकती है।केवल दिनांक

क्योंकि मुझे उपयोगकर्ता दर्ज दिनांक और समय के साथ तुलना करने की आवश्यकता है, मुझे डेलाइट सेविंग टाइम के लिए समायोजित दिनांक और समय पता होना चाहिए। यदि वर्तमान तिथि डेलाइट सेविंग टाइम में है तो मैं घड़ी से समय में केवल एक घंटे जोड़ सकता हूं और मेरे पास जो चाहिए वह है।

कठिन हिस्सा यह निर्धारित कर रहा है कि मैं डेलाइट सेविंग टाइम में हूं या नहीं, क्योंकि यह साल-दर-साल बदलता है। मुझे केवल यह ख्याल है कि यह मेरे स्थान (माउंटेन टाइम) में काम करता है। मेरे प्लेटफार्म के लिए कोई व्यापक तिथि पुस्तकालय नहीं दिखता है, और मुझे लगता है कि वैसे भी यह अधिक होगा। क्या यह निर्धारित करने के लिए एक सरल सूत्र है कि मैं डीएसटी में हूं या नहीं?

उत्तर

30

यह वास्तव में भ्रामक सरल है। कुछ तथ्य हैं जो हमारी मदद करेंगे:

  1. यूएस में अधिकांश में, डीएसटी मार्च के दूसरे रविवार को शुरू होता है और नवंबर के पहले रविवार को 2:00 बजे समाप्त होता है।
  2. मार्च में दूसरा रविवार हमेशा 8 वें और 14 वें समावेशी के बीच होगा।
  3. नवंबर में पहला रविवार हमेशा 1 और 7 वें समावेशी के बीच होगा।
  4. सप्ताह संख्या का दिन काफी सुविधाजनक है क्योंकि सप्ताह का दिन आपको पिछले रविवार को देगा।

इन तथ्यों निम्न कोड के लिए नेतृत्व (सी #, लेकिन तुच्छता से अपने मंच के लिए पोर्टेबल):

public bool IsDST(int day, int month, int dow) 
    { 
     //January, february, and december are out. 
     if (month < 3 || month > 11) { return false; } 
     //April to October are in 
     if (month > 3 && month < 11) { return true; } 
     int previousSunday = day - dow; 
     //In march, we are DST if our previous sunday was on or after the 8th. 
     if (month == 3) { return previousSunday >= 8; } 
     //In november we must be before the first sunday to be dst. 
     //That means the previous sunday must be before the 1st. 
     return previousSunday <= 0; 
    } 

यह पता चला तुम भी, साल यह करने के लिए पता करने की जरूरत नहीं है जब तक क्योंकि आप सप्ताह के मूल्य के अपने दिन पर भरोसा कर सकते हैं।

मैंने एक त्वरित इकाई परीक्षण लिखा और सत्यापित किया कि यह कोड 1800 से 2200 तक सभी तिथियों के लिए TimeZone.IsDayLightSavingsTime() से सहमत है। मुझे 2 बजे के नियम के लिए जिम्मेदार नहीं था, लेकिन आप आसानी से यह जांच कर सकते हैं कि सप्ताह का दिन रविवार है और तिथि 8 और 14 (मार्च में) या 1 और 7 (नवंबर में) के बीच है।

+1

यदि वह कोड वास्तव में 1800 से 2006 तक सभी तिथियों के लिए 'टाइमज़ोन.इएसडेलाइट्सविंग्सटाइम() 'से सहमत है, तो' टाइमज़ोन.आईएसडेलाइट्सविंग्सटाइम()' टूटा हुआ है। 1 9 66 तक अमेरिका में राष्ट्रीय स्तर पर डेलाइट बचत समय भी मौजूद नहीं था (दो विश्व युद्धों के दौरान कुछ अवधि के अलावा)। और 2007 तक, यह अप्रैल में पहला रविवार शुरू हुआ और अक्टूबर में अंतिम रविवार को समाप्त हुआ, 1 974-19 75 में जब अवधि डीएसटी साल भर दौड़ती थी। – Anomie

+0

प्रलेखन का कहना है कि यह ऐतिहासिक नहीं है। यह केवल वर्तमान संस्कृति के लिए नियम लागू करता है। सटीक ऐतिहासिक डेटा प्राप्त करने के लिए एक और सुविधा है। – captncraig

+0

तो कम से कम टूटने का दस्तावेज है। – Anomie

2

हालांकि यह गणना करने के लिए कि क्या एक विशेष तिथि वर्तमान नियमों के तहत एक विशेष स्थान के लिए डीएसटी में है आसान है, ध्यान दें कि डीएसटी नेताओं की लहर में है और किसी भी बिंदु पर परिवर्तन हो सकता है। मैं एक घड़ी निर्मित पूर्व -2007 कि स्वचालित रूप से डेलाइट सेविंग टाइम के लिए समायोजित कर देता है, और अब मैं इसे चार बार एक साल बदलने के लिए: दो बार जब वास्तविक परिवर्तन होता है, और दो बार यह अब-गलत तरीके से वर्ष दिनांकों पर ही बदल जाता है जब ।

इस मामले में, आप उपयोगकर्ता की तारीख और समय के साथ-साथ समय-क्षेत्र में प्रवेश होने के सरल समीचीन द्वारा पूरी तरह से डीएसटी की उपेक्षा करने में सक्षम हो सकता है। या आप अधिकांश उपभोक्ता उपकरणों की तरह कर सकते हैं और उपयोगकर्ता को समय-समय पर स्थानीय समय क्षेत्र में समय समायोजित करने दें।

लेकिन यदि आपको वास्तव में डीएसटी को संभालने की ज़रूरत है और वास्तव में चीजों को सही करना चाहते हैं, तो zoneinfo database का उपयोग करें और सुनिश्चित करें कि इसे किसी भी तरह से अपडेट किया जा सकता है। यदि आप किसी कारण से ऐसा नहीं कर सकते हैं, तो कम से कम उपयोगकर्ता को नियमों को ओवरराइड करने दें। और यदि यह भी बहुत मुश्किल है, तो कम से कम उपयोगकर्ता को स्वत: समायोजन बंद करने का विकल्प दें (मेरी बेवकूफ अलार्म घड़ी के विपरीत)।

+0

ध्यान दें कि मैं एक एम्बेडेड प्लेटफ़ॉर्म के साथ काम कर रहा हूं, इसलिए स्मृति प्रीमियम पर है। वह डेटाबेस हार्डवेयर विस्तार के बिना मेरी उपलब्ध स्मृति से बड़ी परिमाण के कई आदेश है। यह प्रोजेक्ट एक ही इंस्टॉलेशन के लिए है, इसलिए मुझे वास्तव में केवल यह ख्याल है कि यह एक ही समय क्षेत्र में सटीक रहता है। यदि डीएसटी नियम बदलते हैं तो मैं इसे पुन: प्रोग्राम कर सकता हूं, लेकिन यदि मैं इससे बच सकता हूं तो मैन्युअल रूप से समय समायोजित करने के लिए मैं इसे दो बार पुन: प्रोग्राम नहीं करूंगा। – Muggz

6

मध्य यूरोप के लिए कोड

public static bool IsDst(int day, int month, int dow) 
    { 
     if (month < 3 || month > 10) return false; 
     if (month > 3 && month < 10) return true; 

     int previousSunday = day - dow; 

     if (month == 3) return previousSunday >= 25; 
     if (month == 10) return previousSunday < 25; 

     return false; // this line never gonna happend 
    } 

टेस्ट समारोह

static void Main(string[] args) 
    { 
     TimeZoneInfo tzf2 = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time"); 

     var date = new DateTime(2014, 01, 1, 5, 0,0); 
     bool wasSummer = false; 

     while (date <= new DateTime(3000,1,1)) 
     {           
      var dow = (int) date.DayOfWeek; 

      var isDst = IsDst(date.Day, date.Month, dow);    

      DateTime f2 = TimeZoneInfo.ConvertTime(date, tzf2); 
      var isSummer = f2.IsDaylightSavingTime(); 

      if (isSummer != isDst) 
      { 
       Console.WriteLine("ERROR"); 
       Console.WriteLine(date); 
      } 

      if (isSummer != wasSummer) 
      { 
       Console.WriteLine(date.AddDays(-1).ToShortDateString()); 
      } 

      date = date.AddDays(1); 
      wasSummer = isSummer; 
     } 

     Console.ReadKey(); 

}

0

मार्च 14 वीं और (रेंज में हर दिन 2014-3000 वर्ष के लिए परीक्षण किया) 7 नवंबर हमेशा का हिस्सा हैं सप्ताह में प्रकाश व्यवस्था संयुक्त राज्यों में होती है .. वे रविवार या शनिवार या सप्ताह के बीच में हो सकते हैं लेकिन वे हमेशा उस सप्ताह का हिस्सा होते हैं। नीचे दिया गया कोड रविवार को मिलेगा कि उन दो तिथियों में वर्ष का हिस्सा है, जिसमें प्रश्न की तारीख होती है। फिर उस तारीख को 2 घंटे जोड़ते हैं जिसमें दिन की रोशनी बचत वास्तव में होती है। फिर आप डेलाइट बचत की शुरुआत और समाप्ति तिथियों के खिलाफ प्रश्न की तारीख की तुलना करें और जीएमटी ऑफसेट द्वारा समय समायोजित करें। यह प्रक्रिया अन्य देशों के लिए शुरू और समाप्ति तिथियों के लिए काम कर सकती है। आप एक टेबल सेट कर सकते हैं जिसमें डेलाइट सेविंग एंड के साथ प्रत्येक देश कोड और डाक कोड हो और तिथियां शुरू करें और दोनों अवधि के लिए जीएमटी ऑफसेट शुरू करें। तारीखें एक महीने के पहले रविवार के लिए पहली बार 7 वीं, 14 वीं, 21 वीं और 28 वीं होगी। आप अधिकतम 30 सितंबर या 31 अक्टूबर के महीने के अंतिम रविवार के लिए अधिकतम दिन में डाल देंगे।

मार्च में 2 रविवार

:

cdate("3/14/" & format(now(),"yyyy"))-format(cdate("3/14/" & format(now(),"yyyy")),"W")+1+2/24 

1 रविवार नवंबर:

cdate("11/7/" & format(now(),"yyyy"))-format(cdate("11/7/" & format(now(),"yyyy")),"W")+1+2/24 

पूर्व।

If(now() < cdate("3/14/" & format(now(),"yyyy"))-format(cdate("3/14/" & format(now(),"yyyy")),"W")+1+2/24, dateadd("H",-5,now()), if(now() < cdate("11/7/" & format(now(),"yyyy"))-format(cdate("11/7/" & format(now(),"yyyy")),"W")+1+2/24, dateadd("H",-6,now()), dateadd("H",-5,now()))) 

t_SQL उदाहरण

मामला है जब [date2check] < DATEADD (hh, 2, कास्ट ('3/14 /' + कास्ट (DatePart (yyyy, [date2check]) nvarchar के रूप में (4)) एएस डेटाटाइम) + 1 - DATEPART (डब्ल्यू, सीएएसटी ('3/14 /' + सीएएसटी (DATEPART (yyyy, [date2check]) AS nvarchar (4)) एएस डेटाटाइम))) फिर डेटैड (एचएच, - DST_GMT_TM_ZN_DIFF, [date2check]) ELSE केस जब [date2check] < DATEADD (एचएच, 2, CAST ('11/7/'+ CAST (DATEPART (yyyy, [date2check]) AS nvarchar (4)) एएस डेटाटाइम) + 1 - DATEPART (डब्ल्यू, सीएएसटी ('11/7/'+ सीएएसटी (DATEPART (yyyy, [date2check]) AS nvarchar (4)) के रूप में datetime))) तो DATEADD (hh, - STD_GMT_TM_ZN_DIFF, [date2check]) और DATEADD (hh, - DST_GMT_TM_ZN_DIFF, [date2check]) END END

+2

कृपया कुछ पाठ जोड़ें जो वर्णन कर रहा है कि यहां क्या हो रहा है। धन्यवाद! –

+0

आपको स्पष्टीकरण को उत्तर में ही रखना चाहिए। साथ ही, आप अपना अंतिम कोड स्निपेट प्रारूपित करना चाहेंगे ताकि यह अस्पष्ट रूप से पठनीय हो। –

0

मैं इस दृष्टिकोण के साथ कोशिश कर रहा हूँ और मैं इसे सरल और सटीक लगता है:

// मार्च के पहले रविवार के लिए के रूप में अगर डॉव = 1 रविवार के लिए अगर (महीने == 3 & & दिन> = 8 & & दिन < = 14 & & डॉव = 1) लौट सच

// नवंबर के दूसरे रविवार के लिए अगर रविवार के लिए DoW = 1 यदि (महीने == 11 & & दिन> = 1 & & दिन < = 7 & & डॉव = 1) यह सच है लौटने

0

यहाँ मेरा उत्तर है, और मैं कोई सुधार का स्वागत करते हैं। यह माना जाता है कि वर्ष 2000 और 20 99 के बीच शामिल हैं। संदर्भ लिंक के माध्यम से और जानकारी उपलब्ध है।

int timezone = 0; // Set to correct initial value depending on where you are (or via GPS if you like). 
    // Calculate day of week for Daylight savings time. 
    int day_of_week = (day_of_month + int(2.6 * (((month + 12 - 3) % 12) + 1) - 0.2) - 40 + 
       (month < 3 ? year-1 : year) + int((month < 3 ? year-1 : year)/4) + 5) % 7; 
    // Adjust timezone based on Daylight savings time for northern hemisphere, USA 
    if ((month > 3 && month < 11) || 
     (month == 3 && day_of_month >= 8 && day_of_week == 0 && hour >= 2) || // DST starts 2nd Sunday of March; 2am 
     (month == 11 && day_of_month < 8 && day_of_week > 0) || 
     (month == 11 && day_of_month < 8 && day_of_week == 0 && hour < 2)) { // DST ends 1st Sunday of November; 2am 
    timezone++; 
    } 

सप्ताह गणना संदर्भ का दिन: How to determine the day of the week, given the month, day and year
डीएसटी परीक्षण संदर्भ के रूप में और captncraig द्वारा उत्तर दिया मेरे अपने तर्क और उसके जवाब की व्याख्या इस लेख के माध्यम से है।

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