2014-03-24 67 views
2

附加是我正在使用的一種方法,它採用DateTime字符串的列表,它們的輸入格式(即yyyy-MM-dd HH:mm:ss)以及它們以小時形式的偏移量。Unix日期時間不一致時間轉換和24小時輸入錯誤

至於文化和「標準」,我使用InvariantCulture,我將時間轉換爲UTC。說與

public int unixFormat3(string dateTimeInput, string inputFormat, int hours) 
    { 
     DateTime result; 
     CultureInfo provider = CultureInfo.InvariantCulture; 
     result = DateTime.ParseExact(dateTimeInput, inputFormat, provider); 

     int unixTime = (Int32)(result.ToUniversalTime().AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds; 
     return unixTime; 
    } 

兩個問題的方法:

  1. 我使用這個網站作爲比較。如果我的輸入是2014-03-18 21:00:00,則根據我的方法,我的輸出是1395190800,它將轉換回2014-03-19 01:00:00。它有四個小時的差異。所期望的輸出是這樣的:

enter image description here

  • 如果我的輸入是2014-03-18 24:00:00,我得到這個錯誤:
  • The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.

    值得注意的是,它不允許在HH部分輸入24。這是一個奇怪的錯誤,因爲NodaTime處理它就好了......雖然這是無關緊要的,因爲我正在使用DateTime

    有沒有人有這方面的任何見解?

    編輯:

    在一些實驗,去除.ToUniversalTime()刪除我4個小時的偏差。爲什麼會出現這種情況?

    public int unixFormat3(string dateTimeInput, string inputFormat, int hours) 
    { 
        DateTime result; 
        CultureInfo provider = CultureInfo.InvariantCulture; 
        result = DateTime.ParseExact(dateTimeInput, inputFormat, provider); 
    
        int unixTime = (Int32)(result.AddHours(hours).Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc))).TotalSeconds; 
        return unixTime; 
    } 
    
    +0

    3/19 00:00不會工作? – bf2020

    +0

    它確實有效,但'24:00'沒有。對於DateTime庫,'24:00'和'00:00'似乎不是一回事。 – theGreenCabbage

    +0

    致電喬恩Skeet和馬特約翰遜:)。 – theGreenCabbage

    回答

    1

    System.DateTime對象將小時表示爲0到23之間的整數值(請參閱http://msdn.microsoft.com/en-us/library/vstudio/system.datetime.hour(v=vs.100).aspx)。據我所知,NodaTime不使用任何.NET提供的DateTimeDateTimeOffset類,並自行處理所有內容,這就是爲什麼它能夠正確處理24小時。

    至於爲什麼ToUniversalTime()正在增加一個偏移量,它可能是因爲ParseExact返回一個已經被調整的日期。 (什麼是result你打電話ToUniversalTime()之前的值?)

    您可能還希望改變您的呼叫使用此重載的ParseExact代替:

    result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal); 
    

    這告訴解析器承擔時間以UTC表示,如果在解析的字符串中未指定時區。作爲一個便箋,你應該聲明你的Unix時代是一個只讀的全局變量,並且使用TryParseExact而不是ParseExact

    public class UnixTime 
    { 
        public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); 
    
        public int unixFormat3(string dateTimeInput, string inputFormat, int hours) 
        { 
         int unixTime = -1; 
         DateTime result = DateTime.MinValue; 
         if (DateTime.TryParseExact(dateTimeInput, inputFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out result)) 
         { 
          unixTime = (int)(result.AddHours(hours).Subtract(UnixTime.Epoch)).TotalSeconds; 
         } 
    
         return unixTime; 
        } 
    } 
    
    +0

    非常感謝您的詳細解答。這是非常翔實的。你可以給我一個關於如何處理C#不處理24的建議嗎?這似乎很奇怪,我可以想象很多情況下會有24作爲輸入。 – theGreenCabbage

    +0

    使用'DateTimeStyles.AssumeUniversal' http://puu.sh/7HUMD/2f48f7e43d.png。如果沒有'ToUniversalTime()'或'DateTimeStyles.AssumeUniversal':http://puu.sh/7HUUv/a6cf577df3.png看來,當你不假設/到UTC時,代碼不會爲你補償。當你確實假設UTC時,它會抵消你。它究竟如何假設我的抵消?根據我的電腦和我的時區,我的時區是:「UTC -05:00」,而不是「-04:00」。 – theGreenCabbage

    +0

    哇。我對DateTimes和時區的瞭解越多,我就越困惑。由於輸入是'2014-03-18 21:00:00',因此它與時區無關。由於沒有語言環境或時區標籤,它在什麼時區是不明確的。你認爲這是默認的UTC? – theGreenCabbage

    相關問題