2011-05-21 6 views
8

फ़ाइलें मैं जब निम्न विधि का उपयोग कर कन्वर्ट करने के लिए सही समय मिल पढ़ के अधिकांश:(मैं किसी अन्य तिथि प्राप्त) dateTime को FILETIME (विंडोज़ समय) से बदलने में सक्षम नहीं किया जा रहा

// works great most of the time 
private static DateTime convertToDateTime(System.Runtime.InteropServices.ComTypes.FILETIME time) 
{ 
    long highBits = time.dwHighDateTime; 
    highBits = highBits << 32; 
    return DateTime.FromFileTimeUtc(highBits + time.dwLowDateTime); 
} 

यहाँ मैं यह देखने के लिए दृश्य स्टूडियो में एक उदाहरण है कि यह विधि कभी-कभी उदाहरण के लिए कैसे काम नहीं करती है, मैं अपने कंप्यूटर और डीबग में वास्तविक फ़ाइल दिखाऊंगा। तो फ़ाइल है कि मेरे डिबग में होना होता है:

"एक: \ Users \ Tono \ दस्तावेज़ \ \ परियोजनाओं विजुअल स्टूडियो 2010 \ WpfApplication4 \ WpfApplication4 \ obj \ 86 \ डीबग \ App.g.cs" enter image description here

और यहाँ FILETIME कि मैं दिनांक समय में बदलने के लिए "मैं LastWriteTime जरूरत है जिस तरह से"

enter image description here

यहां आप देख सकते कोशिश कर रहा हूँ है कि dwHighDateTime = 30,136,437 है और यह भी कि dwLowDateTime = -+२१३८९७९२५० उस फाइल से।

और जब मैं अपने विधि के साथ साथ अन्य तकनीकों मैं निम्नलिखित तारीखों मिल चलाएँ: enter image description here

तो अब तक सब कुछ महान काम कर रहा है। लेकिन ऐसा क्यों है कि जब मैं खिड़कियों में उस विशिष्ट फ़ाइल को ब्राउज़ और देखता हूं तो मुझे एक अलग तारीख मिलती है! फ़ाइल की गुणों को देखते समय मुझे यह तारीख मिलती है: enter image description here

तिथियां क्यों मेल नहीं खाती हैं? मैं क्या गलत कर रहा हूं?

+2

आप इसे कठिन तरीके से क्यों कर रहे हैं? ऐसा लगता है कि आप FileInfo क्लास को बहुत अधिक लिख रहे हैं ... http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx –

+0

मुझे यकीन नहीं है कि ओपी यह कठिन तरीका क्यों कर रहा है । लंबे पथ नामों के साथ काम करते समय, यह पथ [MAX_LENGTH] = 260 बाइट्स से लंबा है, तो आपको अप्रबंधित कोड का उपयोग करने के लिए अधिकांश System.IO को फिर से लिखने के लिए आवश्यकता होगी। यहां और जानकारी प्राप्त करने के लिए यहां है: http://blogs.msdn.com/b/bclteam/archive/2007/02/13/long-paths-in-net-part-1-of-3-kim-hamilton .aspx –

+0

FileInfo के बजाय FILETIME/GetFileTime का उपयोग करने के लिए वैध परिदृश्य हैं: उदाहरण के लिए, यदि आप किसी फ़ाइल के आंकड़े प्राप्त करना चाहते हैं जिसका हैंडल आप पहले ही खोल चुके हैं (और किसी कारण से FileInfo के माध्यम से इसे फिर से खोल नहीं सकते हैं) –

उत्तर

15

आपको एलएस और एमएस मानों को थोड़ा सा गठबंधन करने की आवश्यकता है, अंकगणित रूप से नहीं।

प्रयास करें:

 ulong high = 30136437; 
     unchecked 
     { 
      int low = -2138979250; 
      uint uLow = (uint)low; 
      high = high << 32; 
      Date dt = DateTime.FromFileTime((long) (high | (ulong)uLow)); 
     } 

या निम्न में से कोई भी काम करना चाहिए:

long highBits = time.dwHighDateTime;  
highBits = highBits << 32;  

return DateTime.FromFileTimeUtc(highBits + (long) (uint) time.dwLowDateTime); 

return DateTime.FromFileTimeUtc(highBits | (long) (uint) time.dwLowDateTime); 

return DateTime.FromFileTimeUtc(highBits + ((long)low & 0xFFFFFFFF)) 

return DateTime.FromFileTimeUtc(highBits | ((long)low & 0xFFFFFFFF)) 

आप एक के बजाय जोड़ने के साथ प्राप्त कर सकते हैं बिटवाइज़-या यदि आप सुनिश्चित हैं मूल्यों सकारात्मक रहे हैं (और आम में कोई बिट नहीं है)। लेकिन bitwise- या इरादा बेहतर व्यक्त करता है।

+1

समय। dwLowDateTime ऋणात्मक मान के रूप में दिख रहा है (यह नहीं होना चाहिए) इसलिए इसे लंबे समय तक कास्टिंग गलत परिणाम देने जा रहा है। इसके बजाय आईआईआरसी आपको '(लम्बाई) ((uint) (time.dwLowDateTime) करने की आवश्यकता है) या इंटरऑप को ठीक करें ताकि यह एक यूंट के रूप में शुरू हो। – Yaur

+0

थके हुए लेकिन काम नहीं किया। मुझे लगता है कि मेरी विधि वह है जो गलत तारीख पढ़ रही है। मैं इसे समझने की कोशिश करता रहूंगा। –

0

dwLowDateTime और dwHighDateTimeuint होना चाहिए और ऐसा लगता है कि वे int हैं। इसे बदलने से सबसे अधिक संभावना ठीक हो जाएगी, हालांकि @ जो ने बताया कि आपको अभी भी के बजाय | का उपयोग करना चाहिए।

0

मैं कोशिश की है निम्नलिखित है और उनमें से गैर मुझे सही समय मिलता: है
enter image description here

और मैं here

+0

क्या आप सभी को इसके लिए ठीक लगता है? –

5

इस से विधि मिला एक और तरीका है कि मैं एक FileTime संरचना परिवर्तित करने के लिए देखा है लंबे समय तक (संरचना में कोडित ऑपरेटर का उपयोग करके), जिसे डेटटाइम का उपयोग करके आसानी से डेटटाइम में परिवर्तित किया जा सकता है।FromFileTime कार्य:

public struct FileTime 
{ 
    public uint dwLowDateTime; 
    public uint dwHighDateTime; 

    public static implicit operator long(FileTime fileTime) 
    { 
     long returnedLong; 
     // Convert 4 high-order bytes to a byte array 
     byte[] highBytes = BitConverter.GetBytes(fileTime.dwHighDateTime); 
     // Resize the array to 8 bytes (for a Long) 
     Array.Resize(ref highBytes, 8); 

     // Assign high-order bytes to first 4 bytes of Long 
     returnedLong = BitConverter.ToInt64(highBytes, 0); 
     // Shift high-order bytes into position 
     returnedLong = returnedLong << 32; 
     // Or with low-order bytes 
     returnedLong = returnedLong | fileTime.dwLowDateTime; 
     // Return long 
     return returnedLong; 
    } 
} 
3

मैं थोड़ा पार्टी के लिए देर हो रही है, लेकिन इस मज़बूती से मेरे लिए काम किया है:

public static class FILETIMEExtensions 
{ 
    public static DateTime ToDateTime(this System.Runtime.InteropServices.ComTypes.FILETIME time) 
    { 
     ulong high = (ulong)time.dwHighDateTime; 
     uint low = (uint)time.dwLowDateTime; 
     long fileTime = (long)((high << 32) + low); 
     try 
     { 
      return DateTime.FromFileTimeUtc(fileTime); 
     } 
     catch 
     { 
      return DateTime.FromFileTimeUtc(0xFFFFFFFF); 
     } 
    } 
} 

नोट: Windows Explorer विश्वास न करें। File.GetLastWriteTimeUtc विधि का उपयोग करें, उदाहरण के लिए, यह सत्यापित करने के लिए कि फ़ाइल एक्सटेंशन वास्तव में इस एक्सटेंशन विधि के विरुद्ध क्या है। एक्सप्लोरर में कुछ बग हैं जो कुछ स्थितियों में फ़ाइल समय अपडेट नहीं करते हैं। चीयर्स! :)

नोट: इसका परीक्षण करने के लिए, आपको अधिकतम मूल्यों का उपयोग करने की आवश्यकता है। तो, dwHighDateTime = dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF मानते हुए, यह (long)(((ulong)UInt32.MaxValue << 32) + UInt32.MaxValue) = -1 = 0xFFFFFFFFFFFFFFFF का पालन करता है। दुर्भाग्यवश, विंडोज एपीआई में फॉरेसी ऐसा लगता है कि अंततः किसी भी उपयोगी अनुप्रयोगों के लिए इसके साथ काम करने के लिए समय को long मान पर डाला जाना चाहिए (क्योंकि अधिकांश विंडोज एपीआई विधियां फ़ाइल समय को long मान के रूप में लेती हैं), जो कि इसका मतलब है कि एक बार अग्रणी बिट उच्च (1) dwHighDateTime पर, मान नकारात्मक हो जाता है। चलिए अधिकतम समय के साथ उच्च होने की कोशिश नहीं करते हैं। dwHighDateTime = Int32.MaxValue = 2147483647 = 0x7FFFFFFF और dwLowDateTime = UInt32.MaxValue = 4294967295 = 0xFFFFFFFF मानते हुए, यह (long)(((ulong)Int32.MaxValue << 32) + UInt32.MaxValue) = 0x7FFFFFFFFFFFFFFF का पालन करता है।

नोट: 0x7FFFFFFFFFFFFFFF पहले से ही DateTime.MaxValue.ToFileTimeUtc() = 2650467743999999999 = 0x24C85A5ED1C04000 की तुलना में बहुत बड़ी संख्या है कि बड़े को पहले से ही नेट में किसी भी व्यावहारिक अनुप्रयोगों के लिए बेकार प्रतिपादन करता है।

+0

यह समाधान मेरे लिए काम करता है, जबकि अन्य उत्तरों गलत परिणाम लौटाते हैं –

+0

@ डेविड रॉबर्ट्स ऐसा इसलिए है क्योंकि अन्य उत्तर उच्च दिनांक समय घटक में एक हस्ताक्षरित 64 बिट मान के रूप में कारक नहीं हैं ... इसके बजाय मुझे लगता है कि वे गलत तरीके से हस्ताक्षरित हैं 64 बिट मान, जो एक नकारात्मक परिणाम लौटा सकता है, जो गलत है। – Alexandru

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