मैं एक डेटटाइम ऑब्जेक्ट की गहरी प्रतिलिपि कैसे बना सकता हूं?


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

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

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

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

जवाबों:


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

अपडेट करें:

यदि आप किसी मौजूदा DT ऑब्जेक्ट के संदर्भ के बजाय कॉपी करना चाहते हैं, तो उपयोग करें clone, नहीं =

$a = clone $b;


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

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

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

11
बस जब मैंने सोचा कि मेरे पास PHP पर एक पकड़ है तो मैं एक नए ऑपरेटर के बारे में सीखता हूं।
kr094

एक मौजूदा कार्बन ऑब्जेक्ट को दूसरे वेरिएबल में कॉपी करने के लिए ऐसा करना पड़ा। यह काम किया।
racl101

111

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

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

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

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


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

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

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

46

PHP 5.5.0 ने DateTimeImmutable पेश किया । जोड़नाइस वर्ग के तरीकों को और संशोधित करें नई वस्तुओं को लौटाएं।

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

4
ध्यान दें कि दुर्भाग्य से आप सिर्फ एक के DateTimeसाथ स्वैप नहीं कर सकते DateTimeImmutable। कम से कम IntlDateFormatter::formatObjectऐसा नहीं है जो अपरिवर्तनीयों ( falseस्वरूपित स्ट्रिंग के बजाय रिटर्न ) को पसंद नहीं करता है ।
user276648

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

2
कुछ नोब की तरह मुझे बस एक वस्तु DateTimeको लूप में बदलने के लिए एक वस्तु उन्मुख नुकसान का सामना करना पड़ा : D यह अच्छी तरह से हल किया ...
विल्ट

3
@ user276648 यह बग अब php 7.1.5 php.net/ChangeLog-7.php#7.1.5
jontro

11

TLDR:

$date1 = new DateTime();
$date2 = (clone $date1)->modify('+3 years');

(Shallow copy is enaugh - डीप कॉपी-इंग डेटटाइम बनाता है (वर्तमान में कोई मतलब नहीं )

इतना ही आसान :)

स्पष्टीकरण "php एक अन्य डेटाटाइम से डेटाइम ऑब्जेक्ट बनाएँ":

  1. cloneकीवर्ड नियमित बनाता उथले (क्यों => नीचे देखें) इस मामले के लिए enaugh - प्रतिलिपि
  2. इसके साथ लपेटकर ()नव निर्मित वस्तु को वापस करके अभिव्यक्ति का मूल्यांकन करता हैclone
  3. ->modify() इसलिए कहा जाता है और नई वस्तु को संशोधित करता है
  4. DateTime::modify(...) डॉक्स:

    विफलता के लिए विधि जंजीर या FALSE के लिए DateTime ऑब्जेक्ट देता है।

  5. $date2अब नव निर्मित और संशोधित क्लोन / कॉपी शामिल है, जबकि $date1अपरिवर्तित रहता है

आपको यहां गहरी प्रतिलिपि की आवश्यकता क्यों नहीं है:

दीप प्रतिलिपि / क्लोन केवल आवश्यक है, जब आपको उन संपत्तियों के लक्ष्यों को कॉपी करने की आवश्यकता होती है जो संदर्भ हैं , लेकिन यह:

class TestDateTime extends DateTime{
  public function test(){
   //*this* way also outputs private variables if any...
   var_dump( get_object_vars($this) );    
  }
}
$test = (new TestDateTime())->test();

आउटपुट:

array(3) {
  ["date"]=>
  string(26) "2019-08-21 11:38:48.760390"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(3) "UTC"
}

इसलिए कोई संदर्भ नहीं हैं, बस सरल प्रकार => गहरी प्रतिलिपि की आवश्यकता नहीं है।


1

आप अपने बदलना चाहिए DateTimeकरने के लिएDateTimeImmutable

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

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


यह वास्तव में एक अलग सवाल का जवाब है।
बिली ओपल

मैं पूरी तरह से कैसे नहीं समझाया हो सकता है @BillyONeal, लेकिन यह इस समस्या के स्रोत के रूप में इस समस्या का समाधान है कैसे विधि बुला है addपर date2बदलाव की मूल्य date1और वहाँ के मान की प्रतिलिपि करने के लिए कोई रास्ता नहीं है DateTimeचर जब तक आप एक हैDateTimeImmutable
होसैन शाहदोस्तो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.