2010-04-05 15 views
82
$date1 = $date2 = new DateTime(); 
$date2->add(new DateInterval('P3Y')); 

अब $date1 और $date2 में एक ही तिथि है - अब से तीन साल। मैं दो अलग-अलग डेटाटाइम बनाना चाहता हूं, जिसे एक स्ट्रिंग से पार्स किया गया है और इसमें तीन साल शामिल हैं। वर्तमान में मैंने इसे इस तरह से हैक किया है:मैं डेटटाइम ऑब्जेक्ट की गहरी प्रतिलिपि कैसे करूं?

$date2 = new DateTime($date1->format(DateTime::ISO8601)); 

लेकिन यह एक भयानक हैक की तरह लगता है। क्या डेटटाइम ऑब्जेक्ट की गहरी प्रतिलिपि बनाने का कोई "सही" तरीका है?

उत्तर

112
$date1 = new DateTime(); 
$date2 = new DateTime(); 
$date2->add(new DateInterval('P3Y')); 

अद्यतन:

आप के बजाय नकल एक मौजूदा डीटी वस्तु को संदर्भित करने के clone, नहीं = का उपयोग करें।

+10

मैं बिंदु प्रदर्शित करने के लिए उदाहरण में एक नया दिनांक समय इस्तेमाल किया , लेकिन अब मान लें कि डेटटाइम कुछ अपारदर्शी एपीआई से वापस आ गया है कि मैं फिर से कॉल नहीं कर सकता। उदाहरण के लिए, मेरे पास एक ऐसा फ़ंक्शन है जो ऑर्डर को नियंत्रित करता है जो डेटटाइम देता है, जब ग्राहक अगली जगह ऑर्डर कर सकता है। एक प्रतिलिपि बनाने के लिए फ़ंक्शन को कॉल करना साइड इफेक्ट्स उत्पन्न करता है जो मैं नहीं चाहता हूं। –

+0

मैंने वास्तव में इसका परीक्षण नहीं किया है, लेकिन इसका उल्लेख php.net पर किया गया है कि यह केवल PHP 5.3 और अधिक के लिए उपलब्ध है। –

+0

@ हूगो: हां, डेटटाइम क्लास को PHP 5.3 की आवश्यकता है। –

74

क्लोन clone ऑपरेटर के साथ तारीख:

$date1 = new DateTime(); 
$date2 = clone $date1; 
$date2->add(new DateInterval('P3Y')); 

क्लोन डिफ़ॉल्ट रूप से उथले, लेकिन दिनांक समय के लिए काफी गहरी हैं। अपनी खुद की वस्तुओं में, आप गुणों को क्लोन करने के लिए __clone() जादू विधि को परिभाषित कर सकते हैं (यानी बच्चे ऑब्जेक्ट्स) जो माता-पिता ऑब्जेक्ट में परिवर्तन करते समय क्लोन होने के लिए समझ में आता है।

(मुझे यकीन है कि क्यों प्रलेखन सोचता है कि एक वस्तु क्लोन करने के लिए की आवश्यकता होगी, का एक अच्छा उदाहरण जीटीके। कौन PHP में जीटीके का उपयोग करता है नहीं कर रहा हूँ?)

+1

उत्तर के लिए धन्यवाद, लेकिन आप कैसे जानते हैं कि यह डेटटाइम के लिए पर्याप्त गहरा है? कौन से गुण संदर्भ रहते हैं और जो मूल्य द्वारा प्रतिलिपि बनाई जाती हैं? उदाहरण के लिए, मैं समय और समय क्षेत्र बदल सकता हूं और यह क्लोन को प्रभावित नहीं करेगा? – David

+1

@ डेविड: मुझे पता है कि यह डेटटाइम के लिए काफी गहरा है क्योंकि मैंने कोशिश की, और यह मेरे लिए काम किया। मैंने टाइमज़ोन या किसी अन्य चीज को बदलने की कोशिश नहीं की, केवल बुनियादी समय और तारीख। – rjmunro

+3

Xdebug का उपयोग करके, var_dump ($ date1) रिपोर्ट करता है कि इसमें 'दिनांक' => स्ट्रिंग, 'timezone_type' => int और 'timezone' => स्ट्रिंग शामिल है। चूंकि इसमें कोई सरणी या वस्तुएं नहीं दिखती हैं, केवल बुनियादी स्केलर, एक उथले क्लोन ठीक होना चाहिए। –

30

पीएचपी 5.5.0 शुरू की DateImmutableadd और modify इस वर्ग के तरीके नई वस्तुओं को वापस कर देते हैं।

$date1 = new DateTimeImmutable(); 
$date2 = $date1->add(new DateInterval('P3Y')); 
अपने DateTime DateTimeImmutable-
+3

ध्यान दें कि दुर्भाग्य से आप 'डेटटाइम' के साथ 'डेटटाइम' को केवल स्वैप नहीं कर सकते हैं।कम से कम 'IntlDateFormatter :: formatObject' है जो अपरिवर्तनीय पसंद नहीं करता है (स्वरूपित स्ट्रिंग के बजाय 'false' लौटाता है)। – user276648

+1

ओह! मैं किसी भी तरह से यह अस्तित्व में कभी नहीं जानता था, हालांकि मैंने इसका सपना देखा है। और सभी तरह से 5.5 में वापस ... – Ben

+2

कुछ नोब की तरह मुझे बस एक लूप में मेरी 'डेटटाइम' ऑब्जेक्ट को संशोधित करके ऑब्जेक्ट ओरिएंटेड पिटफॉल का सामना करना पड़ा: डी ने इसे अच्छी तरह से हल किया ... – Wilt

0

आप बदलना चाहिए

// from date time 
$date = \DateTimeImmutable::createFromMutable($mutableDate) 

तो आप इसके बारे में चिंता किए बिना DateTime पर किसी भी विधि कॉल कर सकते हैं बदलने के

+0

यह वास्तव में एक अलग प्रश्न का उत्तर है। –

+0

@ बिलीओनेल मैंने शायद पूरी तरह से समझाया नहीं है, लेकिन यह इस समस्या का समाधान है क्योंकि इस समस्या का स्रोत यह है कि 'date2' पर विधि' add' को कॉल करने से 'date1' का मान बदल जाता है और इसका कोई तरीका नहीं है जब तक आपके पास 'डेटटाइम Immutable' नहीं है तब तक' डेटटाइम 'चर के मान की प्रतिलिपि बनाएँ –

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