আমি কীভাবে ডেটটাইম অবজেক্টটি গভীরভাবে অনুলিপি করব?


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'));

হালনাগাদ:

আপনি রেফারেন্স বদলে কপি করতে একটি বিদ্যমান মোর্চা বস্তুর চান, ব্যবহার clone, না =

$a = clone $b;


12
আমি উদাহরণটিতে একটি নতুন ডেটটাইম ব্যবহার করেছি পয়েন্টটি প্রদর্শন করার জন্য, তবে আপাতত ধরে নিন যে ডেটটাইমটি কিছু অস্বচ্ছ API থেকে ফিরে এসেছে যা আমি কেবল আবার কল করতে পারি না। উদাহরণস্বরূপ, আমার একটি ফাংশন রয়েছে যা অর্ডার পরিচালনা করে যা একটি ডেটটাইম দেয় যা গ্রাহক পরবর্তী সময়ে অর্ডার দিতে পারে। একটি অনুলিপি তৈরি করতে ফাংশনটিতে কল করা আমার পার্শ্ব প্রতিক্রিয়া তৈরি করে।
বিলি ওনিল

আমি এটি প্রকৃতপক্ষে পরীক্ষা করে দেখিনি, তবে এটি পিএইচপি.এন. তে উল্লেখ করা হয়েছে যে এটি কেবলমাত্র পিএইচপি 5.3 এবং এর চেয়ে বেশির জন্য উপলব্ধ।
হুগো ডের হাঞ্জিজে

@ হুগো: হ্যাঁ, ডেটটাইম ক্লাসের জন্য পিএইচপি 5.3 প্রয়োজন।
বিলি ওনিল

11
ঠিক যখনই আমি ভাবলাম পিএইচপি-র উপরে আমার উপলব্ধি রয়েছে তখন আমি একজন নতুন অপারেটর সম্পর্কে জানব।
kr094

বিদ্যমান কার্বন অবজেক্টটিকে অন্য ভেরিয়েবলের অনুলিপি করতে এটি করতে হয়েছিল। এটি কাজ করে।
racl101

111

ক্লোন অপারেটরের সাথে তারিখটি ক্লোন করুন :

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

ক্লোনগুলি ডিফল্টরূপে অগভীর, তবে ডেটটাইমের জন্য যথেষ্ট গভীর। আপনার নিজস্ব অবজেক্টগুলিতে, আপনি __clone()প্যারেন্ট অবজেক্ট পরিবর্তিত হলে ক্লোন করার বৈশিষ্ট্যগুলি (অর্থাত্ শিশু সামগ্রী) ক্লোন করার জন্য যাদু পদ্ধতিটি সংজ্ঞায়িত করতে পারেন ।

(আমি নিশ্চিত নই কেন ডকুমেন্টেশনটি কোনও বিষয়টিকে ক্লোন করার প্রয়োজনের একটি ভাল উদাহরণটি জিটিকে বলে। পিএইচপি-তে কে জিটিকে ব্যবহার করে?)


1
উত্তরের জন্য আপনাকে ধন্যবাদ, তবে আপনি কীভাবে জানবেন যে এটি ডেটটাইমের জন্য যথেষ্ট গভীর? কোন বৈশিষ্ট্যগুলি রেফারেন্স থেকে যায় এবং কোনটি মান দ্বারা অনুলিপি করা হয়? উদাহরণস্বরূপ, আমি সময় এবং সময় অঞ্চল পরিবর্তন করতে পারি এবং এটি ক্লোনকে প্রভাবিত করবে না?
ডেভিড

1
@ ডেভিড: আমি জানি এটি ডেটটাইমের পক্ষে যথেষ্ট গভীর কারণ আমি এটি চেষ্টা করেছিলাম এবং এটি আমার পক্ষে কাজ করে। আমি টাইমজোন বা অন্য কোনও জিনিস পরিবর্তনের চেষ্টা করিনি, কেবলমাত্র বেসিক সময় এবং তারিখ।
rjmunro

3
এক্সডিবুগ ব্যবহার করে, var_dump ($ তারিখ 1) রিপোর্ট করে যে এতে 'তারিখ' => স্ট্রিং রয়েছে, 'টাইমজোন_ টাইপ' => অন্তর্ & 'টাইমজোন' => স্ট্রিং রয়েছে। যেহেতু এটিতে কোনও অ্যারে বা অবজেক্ট থাকে না, কেবলমাত্র বেসিক স্কেলার, একটি অগভীর ক্লোনটি ভাল হওয়া উচিত।
সিজে ডেনিস

46

পিএইচপি 5.5.0 প্রবর্তিত তারিখের সময়ঘটিত । এই শ্রেণীর পদ্ধতি যুক্ত এবং সংশোধন করুন নতুন বস্তুগুলি ফেরত দেয়।

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

4
মনে রাখবেন যে দুর্ভাগ্যক্রমে আপনি কেবল একটি DateTimeদিয়ে একটি অদলবদল করতে পারবেন না DateTimeImmutable। অন্তত IntlDateFormatter::formatObjectএমনটি রয়েছে যা অপরিবর্তনীয় পছন্দ করে না ( falseফর্ম্যাট স্ট্রিংয়ের পরিবর্তে রিটার্ন দেয় )।
ব্যবহারকারী 276648

1
উহু! আমি একরকম কখনই জানতাম না যে এর অস্তিত্ব ছিল, যদিও আমি এটির অনেক আগে থেকেই স্বপ্ন দেখেছি। এবং সমস্ত পথে ফিরে 5.5 ...
বেন

2
কিছু নুবির মতো আমি কেবলমাত্র DateTimeএকটি লুপের জন্য আমার অবজেক্টটি সংশোধন করে একটি অবজেক্ট ওরিয়েন্টেড সমস্যার মুখোমুখি হয়েছি : ডি এটি সুন্দরভাবে সমাধান করেছে ...
উইল্ট

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');

(অগভীর অনুলিপি হ'ল - অনুলিপি অনুলিপি তারিখটাইম (বর্তমানে) কোনও বুদ্ধি নেই )

যে হিসাবে সহজ :)

ব্যাখ্যা "পিএইচপি অন্য একটি ডেটটাইম থেকে ডেটটাইম অবজেক্ট তৈরি করে":

  1. cloneশব্দ নিয়মিত তোলে অগভীর (কেন => নিচে দেখুন) এই ক্ষেত্রে জন্য enaugh - কপি
  2. এটি দিয়ে মোড়ানো ()নতুন সৃজিত বস্তু দ্বারা প্রকাশিত অভিব্যক্তিটিকে মূল্যায়ন করেclone
  3. ->modify() সুতরাং বলা হয় এবং নতুন অবজেক্টটি সংশোধন করে
  4. DateTime::modify(...) দস্তাবেজ:

    পদ্ধতিতে শৃঙ্খলাবদ্ধতার জন্য বা ব্যর্থতায় মিথ্যা বলার জন্য ডেটটাইম অবজেক্টটি দেয়।

  5. $date2 এখন সদ্য নির্মিত এবং পরিবর্তিত ক্লোন / অনুলিপি সহ রয়েছে while $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
হোসেইন শাহদুস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.