2009-08-13 6 views
17

Bir zaman dilimi ofsetinin (dakikalar içinde) olduğu ve saat dilimini belirlemek için gereken bir senaryo var. Tüm verilerin mevcut olmadığını biliyorum (örneğin, -240 dakikalık bir kayma ile birkaç zaman dilimi olabilir), ancak "en iyi tahmin" kabul edilebilir.Saat dilimini UTC ofseti ile nasıl belirleyebilirim?

foreach (var info in TimeZoneInfo.GetSystemTimeZones()) 
{ 
    if (info.BaseUtcOffset.TotalMinutes == timezoneOffset) 
    { 
     // do something here if this is a valid timezone 
    } 
} 

Bu sorta çalışır, ancak ben biraz beni atma Gün ışığından yararlanma hesap gerekir:

İlk geçiş bu benziyordu. Gün ışığından yürürlükte değildir ve DST sırasında yaklaşık% 70 doğru olduğumda kullanıcıya onlar için doğru zamanı gösterebilir Bunun anlamı içinde "yeterince iyi" çalışır

foreach (var info in TimeZoneInfo.GetSystemTimeZones()) 
{ 
    var extra = info.IsDaylightSavingTime(DateTime.Now) ? 60 : 0; 
    if (info.BaseUtcOffset.TotalMinutes + extra == timezoneOffset) 
    { 
     // do something here if this is a valid timezone 
    } 
} 

: Ben bu korkunç kesmek ekledi. Hala ... bu benim gözbebeklerimin korkunç bir kodu.

Bunu yapmanın daha iyi bir yolu var mı? Daha fazla zerafet iyi olurdu ve daha fazla doğruluk daha iyi olurdu.

Güncelleme

Teknik olarak ben JavaScript tarihi konusundaki alabilirsiniz herhangi bir bilgi erişimi vardır. "Ofset" adlı gizli bir alan yerleştirdiğim bir sayfam var. Ofset alanını DateTime(). GetTimezoneOffset() ile dolduran bir JQuery işlevi var. Ben yardımcı olacak DateTime nesnesinde bir şey görmemekle birlikte, belki bu fikirler için başka yollar açacaktır.

+0

@Sailing Judo: Cevabım için bir kod ekledim, bu da Javascript'in evrensel bir zaman damgasını yerel bir tanıma dönüştürmesine izin veriyor. – Kip

cevap

16

Kısa cevap: Yapamazsınız.

Yaz saati uygulaması bunu imkansız kılar. Örneğin, yalnızca UTC ofsetinden, yaz aylarında Arizona ve Kaliforniya arasındaki farktan veya kışın Arizona ve New Mexico'dan (Arizona DST'yi gözlemlemediği için) karar vermenin bir yolu yoktur.

Ayrıca, farklı ülkelerin DST'yi hangi saatlerde gözlemledikleri de vardır. Örneğin, ABD'de DST daha erken başlar ve Avrupa’dan daha sonra sona erer.

Yakın bir tahmin (örneğin, +/- bir saat) mümkündür, ancak kullanıcılara zaman göstermek için kullanıyorsanız, kaçınılmaz olarak bazılarına yanlış zaman göstereceksiniz.


Güncelleme: Birincil amaç, kullanıcının yerel saat diliminde bir zaman damgası göstermektir gibi yorumlarla itibaren görünüyor. Yapmak istediğiniz şey buysa, saati UTC zaman damgası olarak göndermeniz ve ardından kullanıcının tarayıcısını Javascript ile yeniden yazmanız gerekir. Javascript'in etkin olmaması durumunda, hala kullanılabilir bir UTC zaman damgası görürler. İşte ben this Greasemonkey script içinde kullanılan this question, ile geldi bir işlev. İhtiyaçlarınıza uyacak şekilde ince ayar yapmak isteyebilirsiniz. İşte

//@param timestamp An ISO-8601 timestamp in the form YYYY-MM-DDTHH:MM:SS±HH:MM 
//Note: Some other valid ISO-8601 timestamps are not accepted by this function 
function parseISO8601(timestamp) 
{ 
    var regex = new RegExp("^([\\d]{4})-([\\d]{2})-([\\d]{2})T([\\d]{2}):([\\d]{2}):([\\d]{2})([\\+\\-])([\\d]{2}):([\\d]{2})$"); 
    var matches = regex.exec(timestamp); 
    if(matches != null) 
    { 
    var offset = parseInt(matches[8], 10) * 60 + parseInt(matches[9], 10); 
    if(matches[7] == "-") 
     offset = -offset; 

    return new Date(
     Date.UTC(
     parseInt(matches[1], 10), 
     parseInt(matches[2], 10) - 1, 
     parseInt(matches[3], 10), 
     parseInt(matches[4], 10), 
     parseInt(matches[5], 10), 
     parseInt(matches[6], 10) 
    ) - offset*60*1000 
    ); 
    } 
    return null; 
} 

Ben, kullanıcının yerel saat diliminde bir çözümlenir zaman damgası görüntülemek için bloguma kullanmak bir işlevdir. Yine, istediğiniz formata değiştirebilirsiniz.

var weekDays = new Array("Sunday", "Monday", "Tuesday", "Wednesday", 
     "Thursday", "Friday", "Saturday"); 
var months = new Array("January", "February", "March", "April", "May", "June", 
     "July", "August", "September", "October", "November", "December"); 

function toLocalTime(date) 
{ 
    var hour = date.getHours(); 
    var ampm = (hour < 12 ? "am" : "pm"); 
    hour = (hour + 11)%12 + 1; 

    var minutes = date.getMinutes(); 
    if(minutes < 10) 
    minutes = "0" + minutes; 

    return weekDays[date.getDay()] + ", " 
     + months[date.getMonth()] + " " 
     + date.getDate()   + ", " 
     + date.getFullYear()  + " at " 
     + hour     + ":" 
     + minutes     + " " 
     + ampm; 
} 
+0

Bu doğru, tek başına ofset, saat dilimini belirlemek için yeterli bilgi değildir. Eriştiğiniz başka bilgiler var mı? Bir saat dilimi için kullanıcı sorabilir miyim? –

+0

@Matt: Teknik olarak, herhangi bir şeye erişebilirim Javascript bana söyleyebilir, ancak istemcinin DST durumunda olup olmadığını döndürecek javascript DateTime nesnesinde bir şey göremiyorum. –

+0

@Matt: Ayrıca, tüm bu alıştırma, bir şekilde kendim için alabilirsem, bilgi için kullanıcıyı rahatsız etmeme girişimi. Bir saat dilimi için kullanıcı mutlak son çare olarak. Aslında, saat diliminde * çoğunlukla * doğru bir tahminin olması doğruyu sormaktan iyidir (benim durumumda). –

5

Sadece UTC'den gelen ofseti bilmek, DST nedeniyle hangi saat dilimine girdiğinizi söyleyemezsiniz. Zamanın bir kısmına bakıp DST'nin geçerli olup olmadığını tahmin etmeye çalışmayı düşünebilirsiniz, ancak farklı yargı alanları DST'nin tanımını değiştirdiği için politik kaygılar neredeyse imkansızdır.

1

Bazı hilelerle,% 99 oranında doğru olabilir ve diğer% 1'i kapatabilirsiniz. Son derece kapsamlı bir uygulama için jstimezonedetect'a bakın. Zayıf bir adamın yaklaşımı, olası her raporlanan zaman dilimi dengelemesini elinizin en iyi tahmininize elle eşlemek olacaktır. Tahmin edeceğinizden beri, bu konuda da açık olabilirsiniz!