2013-03-04 6 views
6

में परिवर्तित करने के लिए नोडाटाइम का उपयोग करना जो मैं पूरा करना चाहता हूं वह डेटटाइम (ईएसटी/ईडीटी में मानी गई स्ट्रिंग से पार्स) को यूटीसी में परिवर्तित करना है। मैं नोडाटाइम का उपयोग कर रहा हूं क्योंकि मुझे ओल्सन टाइमज़ोन का उपयोग करने की ज़रूरत है।अमान्य (छोड़े गए) डेटाटाइम मानों को यूटीसी

नोडाटाइम के जोनोकोकल मैपिंग रीसोलवर का उपयोग करते हुए एक अमान्य (छोड़ा गया) डेटटाइम को यूटीसी में कनवर्ट करना इनपुट के मिनट और सेकंड हिस्से को परिवर्तित नहीं कर रहा है क्योंकि मैंने अंतराल के बाद अंतराल की शुरुआत को वापस करने के लिए कस्टम रीसोलवर को कॉन्फ़िगर किया है। नोडाटाइम TimeZoneInfo.IsInvalidTime के समतुल्य प्रतीत नहीं होता है।

मैं छोड़े गए डेटाटाइम मानों को यूटीसी में परिवर्तित करने के लिए नोडाटाइम का उपयोग कैसे करूं और नीचे उल्लिखित कक्षा में GetUtc() विधि के परिणाम से मेल खाता हूं? (Utils.GetUtc विधि System.TimeZoneInfo NodaTime नहीं उपयोग करता है)

यह परीक्षण मामला है:

[TestMethod] 
public void Test_Invalid_Date() 
{ 
    var ts = new DateTime(2013, 3, 10, 2, 15, 45); 

    // Convert to UTC using System.TimeZoneInfo 
    var utc = Utils.GetUtc(ts).ToString(Utils.Format); 

    // Convert to UTC using NodaTime (Tzdb/Olson dataabase) 
    var utcNodaTime = Utils.GetUtcTz(ts).ToString(Utils.Format); 

    Assert.AreEqual(utc, utcNodaTime); 
} 

यह मैं क्या मिल रहा है है:

Assert.AreEqual विफल रहा है। अपेक्षित: < 2013-03-10 07: 15: 45.000000>। वास्तविक: < 2013-03-10 07: 00: 00.000000>।

using System; 

using NodaTime; 
using NodaTime.TimeZones; 

/// <summary> 
/// Functions to Convert To and From UTC 
/// </summary> 
public class Utils 
{ 
    /// <summary> 
    /// The date format for display/compare 
    /// </summary> 
    public const string Format = "yyyy-MM-dd HH:mm:ss.ffffff"; 

    /// <summary> 
    /// The eastern U.S. time zone 
    /// </summary> 
    private static readonly NodaTime.DateTimeZone BclEast = NodaTime.DateTimeZoneProviders.Bcl.GetZoneOrNull("Eastern Standard Time"); 


    private static readonly TimeZoneInfo EasternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); 

    private static readonly NodaTime.DateTimeZone TzEast = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/New_York"); 

    private static readonly ZoneLocalMappingResolver CustomResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter); 

    public static DateTime GetUtc(DateTime ts) 
    { 
     return TimeZoneInfo.ConvertTimeToUtc(EasternTimeZone.IsInvalidTime(ts) ? ts.AddHours(1.0) : ts, EasternTimeZone); 
    } 

    public static DateTime GetUtcTz(DateTime ts) 
    { 
     var local = LocalDateTime.FromDateTime(ts); 
     var zdt = TzEast.ResolveLocal(local, CustomResolver); 
     return zdt.ToDateTimeUtc();    
    } 

    public static DateTime GetUtcBcl(DateTime ts) 
    { 
     var local = LocalDateTime.FromDateTime(ts); 
     var zdt = BclEast.ResolveLocal(local, CustomResolver); 
     return zdt.ToDateTimeUtc(); 
    } 
} 

उत्तर

7

NodaTime TimeZoneInfo.IsInvalidTime के समतुल्य है प्रतीत नहीं होता:

यहाँ Utils वर्ग (भी github पर) है।

ठीक है, केवल एक प्रश्न पूछने के बजाय - और फिर फॉलो-ऑन पूछने के लिए - आप DateTimeZone.MapLocal का उपयोग करते हैं। यह आपको यूटीसी मैपिंग के लिए स्थानीय के बारे में सबकुछ बता सकता है: चाहे वह स्पष्ट, संदिग्ध, या अमान्य हो।

वैकल्पिक रूप से, ResolveLocal का उपयोग करें, लेकिन अपने स्वयं के कस्टम SkippedTimeResolver प्रतिनिधि के साथ।

उदाहरण के लिए, यह परिवर्तन करने के लिए मुझे अपने कोड काम करता है:

private static readonly ZoneLocalMappingResolver CustomResolver = 
    Resolvers.CreateMappingResolver(Resolvers.ReturnLater, AddGap); 

// SkippedTimeResolver which adds the length of the gap to the 
// local date and time. 
private static ZonedDateTime AddGap(LocalDateTime localDateTime, 
            DateTimeZone zone, 
            ZoneInterval intervalBefore, 
            ZoneInterval intervalAfter)   
{ 
    long afterMillis = intervalAfter.WallOffset.Milliseconds; 
    long beforeMillis = intervalBefore.WallOffset.Milliseconds; 
    Period gap = Period.FromMilliseconds(afterMillis - beforeMillis); 
    return zone.AtStrictly(localDateTime + gap); 
} 

(वहाँ निश्चित रूप से, यह कर के अन्य समकक्ष तरीके हैं।)

मैं व्यक्तिगत रूप से बचने की कोशिश कर सुझाव देंगे DateTime से कनवर्ट करना जब तक आपको वास्तव में नहीं करना है - मैं नोडा टाइम में जितना संभव हो उतना करूँगा।

+0

मैंने पुराने, लापता, Google कोड साइट के बजाय nodatime.org पर होस्ट किए गए अपने नए एपीआई दस्तावेज़ों का नेतृत्व करने के लिए इस उत्तर में संदर्भ लिंक अपडेट किए हैं। – clarkitect

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