2017-11-21 16 views
5

मेरे पास कुछ कोड है जो फ़ाइल ऑब्जेक्ट को फाइल के नाम के रूप में उपयोग करता है ताकि प्रत्येक बार अलग-अलग फ़ाइल नाम हों लेकिन अजीब चीज यह है कि एक नई तिथि ऑब्जेक्ट एक ही देता है प्रत्येक लूप पुनरावृत्ति के लिए toString()। मेरा मतलब है, निम्नलिखित:नई तिथि() ऑब्जेक्ट एक ही मान देता है

SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss"); 
String fileName = sdf.format((d = new Date())) + ".jpg"; 

Log.d("Date", d.toString()); 

लूप में निष्पादित किया गया है।

साइड नोट: चूंकि यह जावा एपीआई से संबंधित है, इसलिए मैंने इस सवाल को एंड्रॉइड के रूप में टैग नहीं किया है, लेकिन ओएस जो इस कोड को निष्पादित करता है वह एंड्रॉइड है।

AFAIK, new Date() init value के रूप में System.currentTimeMilis() का उपयोग करता है, इस असामान्य व्यवहार के कारण क्या हो सकता है?

+3

जावा 8 दिनांक और समय के लिए नए एपीआई की शुरुआत की। आप यहां एक त्वरित रूप से देख सकते हैं: http://www.baeldung.com/java-8-date-time-intro – Touniouk

+1

आपको मिली सेकेंड का उपयोग करना होगा, और यदि आप थ्रेड का उपयोग कर रहे हैं तो नैनोसेकंद – shareef

+2

का उपयोग करें, आपके पास सेकंड की सटीकता है। क्या आप वाकई अंतर के मिलीसेकंड के साथ कोड को दूसरे सेकेंड में निष्पादित नहीं किया गया है? मैं फ़ाइल नाम के एक अद्वितीय भाग में System.currentTimeMillis() का उपयोग करने की सिफारिश करता हूं। –

उत्तर

5

आप अपना समय yyyyMMdd_HHmmss के रूप में प्रारूपित करते हैं, लेकिन लूप के रन को केवल मिलीसेकंड की आवश्यकता होती है, इसलिए अधिक सटीक समय प्राप्त करने के लिए yyyyMMdd_HHmmssSSS का उपयोग करें।

जैसा कि जॉन स्कीट ने अपनी टिप्पणी में उल्लेख किया है, एक लूप का रन एक मिलीसेकंड से भी कम ले सकता है (आपके द्वारा किए गए कार्यों के आधार पर), ताकि आप इस समाधान के साथ भी मुद्दों में भाग सकें!

+2

बेशक एक मिलीसेकंड में कई बार चलाने के लिए बहुत संभव है। मुझे लगता है कि जवाब में इसका उल्लेख करना उचित है। –

+0

@ सेर्जजे एम क्षमा करें, हां, मेरी धारणा पर संभावनाएं गलत हैं, मैंने – shareef

+0

से पहले मेरी टिप्पणी हटा दी है, यह कोई समस्या नहीं है ;-) – Sergej

0

पाश में जावा एक सेकंड से अधिक तेजी से यह एक ही रहना होगा यकीन है कि इसकी हमेशा अद्वितीय विशेष रूप से बहु में पिरोया समारोह बनाने के लिए है।

की तरह इस

SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SSSSSSS"); 

कुछ संकेत somthing उपयोग आप अभ्यस्त ज्यादा डिबग मुसीबत में जाना तो

printDate("dd.MM.yyyy HH:mm:ss.SSS");//02.05.2010 21:45:58.073 
    printDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//02.05.2010 21:45:58.000073 
    printDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//02.05.2010 21:45:58.073000 
    printDate("dd.MM.yyyy HH:mm:ss.'000000'");//02.05.2010 21:45:58.000000 

    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS");//good 
    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSSSSS");//good 
    tryToParseDate("dd.MM.yyyy HH:mm:ss.SSS'000'");//bad 
    tryToParseDate("dd.MM.yyyy HH:mm:ss.'000000'");//good 

संदर्भ:

उत्तर @slartidan

String-Date conversion with nanoseconds

सिफारिश के रूप में जब मैं इस स्थिति का सामना करना पड़ा:

1)तो S3 एडब्ल्यूएस से बोल रहा हूँ

फ़ाइलों यह फ़ाइल के शुरू में अद्वितीय के रूप में नामित किया जाना चाहिए नाम यह हैशिंग और बहुत तेजी से खोज करेगा। अनुकूलित करने के लिए एडब्ल्यूएस एस 3 सर्वोत्तम प्रथाओं के रूप में।

public static String genarateFileName(String name) { 
     StringBuilder sb = new StringBuilder(name); 
     sb.insert(0, IdUtil.getUniqueUuid());in short to increase performance of S3 put and get etc..) 
     if (sb.lastIndexOf(".") != -1) { 
      sb.insert(sb.lastIndexOf("."), "_" + System.nanoTime()); 
     } else { 
      sb.append("_").append(System.nanoTime()); 
     } 

     return sb.toString(); 
    } 

2)यादृच्छिक नैनो

public static String getUniqueUuid() { 
     int rand = (int) (Math.random() * 100); 
     return Integer.toHexString(rand) + Long.toHexString(java.lang.System.nanoTime()); 
    } 

3 उत्पन्न करने के लिए) मैं यादृच्छिक स्ट्रिंग की जांच के साथ दोनों यादृच्छिक नैनो का उपयोग नीचे कुछ लंबाई के यादृच्छिक स्ट्रिंग उत्पन्न कर

/** 
    * Generate a random uuid of the specified length. Example: uuid(15) returns 
    * "VcydxgltxrVZSTV" 
    * 
    * @param len the desired number of characters 
    * @return 
    */ 
    public static String uuid(int len) { 
     return uuid(len, CHARS.length); 
    } 

    /** 
    * Generate a random uuid of the specified length, and radix. Examples: <ul> 
    * <li>uuid(8, 2) returns "01001010" (8 character ID, base=2) <li>uuid(8, 
    * 10) returns "47473046" (8 character ID, base=10) <li>uuid(8, 16) returns 
    * "098F4D35" (8 character ID, base=16) </ul> 
    * 
    * @param len the desired number of characters 
    * @param radix the number of allowable values for each character (must be 
    * <= 62) 
    * @return 
    */ 
    public static String uuid(int len, int radix) { 
     if (radix > CHARS.length) { 
      throw new IllegalArgumentException(); 
     } 
     char[] uuid = new char[len]; 
     // Compact form 
     for (int i = 0; i < len; i++) { 
      uuid[i] = CHARS[(int) (Math.random() * radix)]; 
     } 
     return new String(uuid); 
    } 
+1

'SimpleDateFormat' का उपयोग करके आप किसी भी मिलीसेकंड की तुलना में अधिक सटीकता के प्रारूप में सक्षम नहीं होंगे, क्योंकि यह 'java.util.Date' की सटीकता है। इसके अलावा, आपको सिस्टम घड़ी की सटीकता पर विचार करने के लिए मिला है, जो कुछ मामलों में 15ms के हिस्सों के लिए समान मूल्य लौटा सकता है। मूल रूप से, यदि यह लूप जल्दी से चल रहा है, तो आपको विशिष्टता के लिए सिस्टम घड़ी पर भरोसा नहीं करना चाहिए। –

+0

@ जोनस्केट सही है कि मैं अपने अनुशंसित अभ्यास की जांच दोनों का उपयोग क्यों करता हूं, 3) मैं यादृच्छिक स्ट्रिंग जांच के साथ यादृच्छिक नैनो दोनों का उपयोग करता हूं, नीचे कुछ यादृच्छिक स्ट्रिंग उत्पन्न करता है और मुझे आपकी फ़ीड वापस देता है, मैं इसकी सराहना करता हूं। – shareef

+1

@JonSkeet पहले से ही क्या कहा गया है, प्रारूप पैटर्न स्ट्रिंग में 6 या 7 पूंजी 'एस' का उपयोग करके मिलीसेकंड के गलत प्रतिपादन की ओर जाता है।आपका उदाहरण '58.073' और' 58.000073' दोनों के रूप में मुद्रित है, यह वही संख्या नहीं है। पूर्व सही है, बाद वाला गलत है। विशिष्टता के लिए इससे कोई फर्क नहीं पड़ता, लेकिन संभवतः कोई इसे किसी टाइमस्टैम्प के रूप में समझ जाएगा। –

3

java.time

आधुनिक दृष्टिकोण जावा.टाइम कक्षाओं का उपयोग करता है।

Instant कक्षा नैनोसेकंड के संकल्प के साथ समयरेखा पर एक बिंदु का प्रतिनिधित्व करती है। Instant.now कमांड जावा 8 में मिलीसेकंड में वर्तमान पल और जावा 9 (या शायद बेहतर) में माइक्रोसेकंड में कैप्चर करता है।

मैकोज़ संगतता के लिए कोलन वर्ण बदलें।

String filename = Instant.now().toString().replace(":" , "-") + ".jpeg" ; 

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

UUID

आप बस वास्तव में नाम में वर्तमान क्षण का प्रतिनिधित्व करने के लिए, तो एक तारीख समय एक UUID मान का उपयोग नहीं बल्कि जरूरत के बिना अद्वितीय फ़ाइल नाम चाहते हैं।

UUID वर्ग इस तरह के संस्करण 4 (ज्यादातर यादृच्छिक) के रूप में कुछ संस्करणों उत्पन्न कर सकते हैं:

String filename = UUID.randomUUID() + ".jpeg" ; 
संबंधित मुद्दे