PostgreSQL এ টাইমস্ট্যাম্পগুলির সাথে টাইম জোনের সাথে / ছাড়াই পার্থক্য


186

ডেটা টাইপ WITH TIME ZONEবনাম যখন টাইমস্ট্যাম্প মানগুলি PostgreSQL এ আলাদাভাবে সংরক্ষণ করা হয় WITHOUT TIME ZONE? পার্থক্যগুলি কি সাধারণ পরীক্ষার ক্ষেত্রে চিত্রিত করা যেতে পারে?


উত্তর:


155

পার্থক্যগুলি পোস্টগ্রিএসকিউএল ডকুমেন্টেশনে তারিখ / সময় ধরণের জন্য আচ্ছাদিত । হ্যাঁ, এক বা এর মধ্যে চিকিত্সা TIMEবা TIMESTAMPতারতম্য । এটি মানগুলি কীভাবে সংরক্ষণ করা হয় তা প্রভাবিত করে না; এটি তাদের ব্যাখ্যা কীভাবে প্রভাবিত করে।WITH TIME ZONEWITHOUT TIME ZONE

এই ডেটা ধরণের টাইম জোনের প্রভাবগুলি ডক্সগুলিতে বিশেষভাবে আবৃত । সিস্টেমটি যুক্তিযুক্তভাবে মূল্য সম্পর্কে কী জানতে পারে তার থেকে তফাতটি দেখা দেয়:

  • মান অংশ হিসাবে একটি সময় অঞ্চল সঙ্গে, মান ক্লায়েন্ট একটি স্থানীয় সময় হিসাবে রেন্ডার করা যেতে পারে।

  • মানের অংশ হিসাবে একটি সময় অঞ্চল ছাড়া, সুস্পষ্ট ডিফল্ট টাইম অঞ্চলটি ইউটিসি, তাই এটি সময় অঞ্চলটির জন্য রেন্ডার করা হয়।

কমপক্ষে তিনটি কারণের উপর নির্ভর করে আচরণটি পৃথক হয়:

  • ক্লায়েন্টে সময় অঞ্চল নির্ধারণ setting
  • মানটির ডেটা টাইপ (যেমন WITH TIME ZONEবা WITHOUT TIME ZONE)।
  • নির্দিষ্ট সময় অঞ্চল সহ মান নির্দিষ্ট করা আছে কিনা।

এখানে সেই কারণগুলির সংমিশ্রণের উদাহরণ রয়েছে:

foo=> SET TIMEZONE TO 'Japan';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 00:00:00+09
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 06:00:00+09
(1 row)

foo=> SET TIMEZONE TO 'Australia/Melbourne';
SET
foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 00:00:00+11
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
      timestamp      
---------------------
 2011-01-01 00:00:00
(1 row)

foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
      timestamptz       
------------------------
 2011-01-01 08:00:00+11
(1 row)

88
মান সন্নিবেশ / পুনরুদ্ধার প্রক্রিয়া উল্লেখ করে শুধুমাত্র সঠিক। তবে পাঠকদের বুঝতে হবে যে উভয় ডেটা টাইপ, timestamp with time zoneএবং timestamp without time zoneপোস্টগ্রিসে * আসলে টাইম জোন তথ্য সংরক্ষণ করে না । আপনি ডেটা টাইপ ডক পৃষ্ঠায় এক নজরে এটি নিশ্চিত করতে পারেন: উভয় প্রকারের একই সংখ্যক অক্টেট থাকে এবং মানগুলির সংরক্ষণের পরিসীমা থাকে, সুতরাং টাইম জোন তথ্য সংরক্ষণের কোনও স্থান নেই। পৃষ্ঠার পাঠ্য এটি নিশ্চিত করে। একটি মিসনোমারের কিছু: "টিজেবিহীন" এর অর্থ "ডেটা whenোকানোর সময় অফসেট উপেক্ষা করুন" এবং "টিজেড সহ উইথ" অর্থ "ইউটিসিতে সামঞ্জস্য করতে অফসেট ব্যবহার করুন"।
বাসিল বাউর্ক

41
ডেটা টাইপগুলি একটি দ্বিতীয় উপায়ে একটি ভুলের নাম: তারা "সময় অঞ্চল" বলে তবে বাস্তবে আমরা ইউটিসি / জিএমটি থেকে অফসেটের কথা বলছি। একটি টাইম জোন আসলে ডাইটলাইট সেভিং টাইম (ডিএসটি) এবং অন্যান্য অসঙ্গতি সম্পর্কে অফসেট প্লাস বিধি / ইতিহাস।
বাসিল বাউর্ক

4
আমি বরং বলব যে অফসেটটি ডিএসটি-র জন্য একটি সময় অঞ্চল প্লাস rules অফসেট দেওয়া সময় অঞ্চলটি আপনি আবিষ্কার করতে পারবেন না, তবে সময় অঞ্চল এবং ডিএসটি নিয়মের ভিত্তিতে আপনি অফসেটটি আবিষ্কার করতে পারেন।
igorsantos07

3
অফিসিয়াল ডকের উদ্ধৃতি দিয়ে : সমস্ত টাইমজোন-সচেতন তারিখ এবং সময়গুলি ইউটিসিতে অভ্যন্তরীণভাবে সংরক্ষণ করা হয়। ক্লায়েন্টের কাছে প্রদর্শিত হওয়ার আগে টাইমজোন কনফিগারেশন প্যারামিটার দ্বারা নির্দিষ্ট জোনে এগুলি স্থানীয় সময়ে রূপান্তরিত হয়।
গিলিয়াম হুস্তা

2
@ igorsantos07 একটি সময় অঞ্চল হ'ল ডিএসটি পরিবর্তন এবং অন্যান্য পরিবর্তনগুলি সম্পর্কে নিয়ম / ইতিহাসের সেট। আপনার শব্দটি অতিরিক্তহীন বলে মনে হচ্ছে। এবং আপনার বক্তব্য যে "অফসেটটি টাইম জোন এবং ডিএসটি-র জন্য নিয়মাবলী" কেবল ভুল: একটি অফসেটটি কেবল কয়েক ঘন্টা, মিনিট এবং সেকেন্ড হয় - এর চেয়ে বেশি কিছুই নয়।
বাসিল বাউরক

34

উল্লেখ করা পোস্টগ্রিসএসকিউএল ডকুমেন্টেশনের চেয়ে আমি এটি আরও বোধগম্যভাবে ব্যাখ্যা করার চেষ্টা করি।

TIMESTAMPনামগুলি যা বলে তা সত্ত্বেও কোনও রূপগুলি টাইম জোন (বা একটি অফসেট) সঞ্চয় করে না। পার্থক্যটি স্টোরেজ ফরম্যাটে নয়, সঞ্চিত ডেটার ব্যাখ্যায় (এবং অভিযুক্ত প্রয়োগে) is

  • TIMESTAMP WITHOUT TIME ZONEসঞ্চয় করে স্থানীয় তারিখ-সময় (ওরফে। প্রাচীর ক্যালেন্ডার তারিখ এবং দেওয়াল ঘড়ি সময়)। পোস্টগ্রিএসকিউএল যতক্ষণ বলতে পারে তার টাইম অঞ্চলটি অনির্ধারিত (যদিও আপনার অ্যাপ্লিকেশনটি এটি কী তা জানে)। সুতরাং, পোস্টগ্রাইএসকিউএল ইনপুট বা আউটপুটে কোনও সময় অঞ্চল সম্পর্কিত রূপান্তর করে না। যদি মানটি ডাটাবেসে প্রবেশ করানো হয় '2011-07-01 06:30:30'তবে আপনি কোন সময় অঞ্চলটি পরে প্রদর্শিত হবে তা নিয়ে কোনও ম্যাটার নেই, তবে এটি ২০১১, মাস 07, দিন 01, 06 ঘন্টা, 30 মিনিট এবং 30 সেকেন্ড (কিছু ফর্ম্যাটে) বলবে। এছাড়াও, আপনি ইনপুটটিতে নির্দিষ্ট করা কোনও অফসেট বা টাইম জোন পোস্টগ্র্রেএসকিউএল দ্বারা উপেক্ষা করা হয়, তাই '2011-07-01 06:30:30+00'এবং '2011-07-01 06:30:30+05'ঠিক হিসাবে একই '2011-07-01 06:30:30'। জাভা বিকাশকারীদের জন্য: এটি অনুরূপ java.time.LocalDateTime

  • TIMESTAMP WITH TIME ZONEইউটিসি সময় লাইনে একটি পয়েন্ট সঞ্চয় করে। এটি কীভাবে দেখায় (কত ঘন্টা, মিনিট ইত্যাদি time) আপনার সময় অঞ্চলের উপর নির্ভর করে তবে এটি সর্বদা একই "শারীরিক" তাত্ক্ষণিক (প্রকৃত শারীরিক ঘটনার মুহুর্তের মতো) বোঝায়। ইনপুটটি অভ্যন্তরীণভাবে ইউটিসিতে রূপান্তরিত হয় এবং এটি সেভাবে সঞ্চিত থাকে। তার জন্য, ইনপুটটির অফসেটটি অবশ্যই জানা উচিত, সুতরাং যখন ইনপুটটিতে স্পষ্টত অফসেট বা টাইম অঞ্চল (যেমন '2011-07-01 06:30:30') থাকে না তখন এটি পোস্টগ্র্যাসকিউএল সেশনের বর্তমান টাইম জোনে বলে ধরে নেওয়া হয়, অন্যথায় স্পষ্টভাবে নির্দিষ্ট অফসেট বা টাইম অঞ্চল ব্যবহার করা হয় (হিসাবে হিসাবে '2011-07-01 06:30:30+05') আউটপুট পোস্টগ্রিজ এসকিউএল সেশনের বর্তমান টাইম জোনে রূপান্তরিত প্রদর্শিত হয়। জাভা বিকাশকারীদের জন্য: এটি java.time.Instant(যদিও কম রেজোলিউশনের সাথে) সমতুল্য , তবে জেডিবিসি এবং জেপিএ ২.২ এর সাথে আপনার এটি মানচিত্র করা উচিত java.time.OffsetDateTime(অথবা java.util.Dateঅথবা বাjava.sql.Timestamp অবশ্যই).

কেউ কেউ বলে যে উভয় TIMESTAMPপ্রকারভেদ ইউটিসি তারিখের সময় সংরক্ষণ করে। ধরনের, কিন্তু এটি আমার মতে সেভাবে রাখা বিভ্রান্তিকর। TIMESTAMP WITHOUT TIME ZONEএকটি হিসাবে সংরক্ষণ TIMESTAMP WITH TIME ZONEকরা হয়, যা ইউটিসি টাইম জোনের সাথে রেন্ডার করা একই বছর, মাস, দিন, ঘন্টা, মিনিট, সেকেন্ড এবং মাইক্রোসেকেন্ডগুলি স্থানীয় তারিখের সময় হিসাবে দেয়। তবে এটি ইউটিসি ব্যাখ্যায় যে সময়রেখার উপরের বিন্দুটি প্রতিনিধিত্ব করে তা বোঝানো হয়নি, এটি কেবল স্থানীয় তারিখ-সময় ক্ষেত্রগুলি এনকোড করা। (এটি টাইম লাইনের বিন্দুগুলির কিছু গুচ্ছ, আসল সময় অঞ্চলটি ইউটিসি নয়; আমরা এটি জানি না don't)


TIMESTAMP WITH TIME ZONEহিসাবে একটি পুনরুদ্ধার করে কোন ভুল নেই Instant। উভয়ই ইউটিসিতে সময়রেখার একটি পয়েন্ট উপস্থাপন করে। Instantআমার মতে OffsetDateTimeএটি বেশি স্ব-ডকুমেন্টিং হিসাবে পছন্দ করা হয়: TIMESTAMP WITH TIME ZONEএটিকে ইউটিসি হিসাবে ডেটাবেস থেকে সর্বদা পুনরুদ্ধার করা হয় এবং একটি Instantসর্বদা ইউটিসি-তে থাকে তাই প্রাকৃতিক ম্যাচ, OffsetDateTimeঅন্যটি অফসেট বহন করতে পারে।
বাসিল বার্ক

@ বাসিলবার্ক দুর্ভাগ্যক্রমে, বর্তমান জেডিবিসি স্পেসিফিকেশন, জেপিএ ২.২ স্পেসিফিকেশন, এবং পোস্টগ্রিসকিউএল জেডিবিসি ডকুমেন্টেশনগুলিতে কেবল ম্যাপযুক্ত OffsetDateTimeজাভা টাইপ হিসাবে উল্লেখ করা হয়েছে। আমি নিশ্চিত না Instanceএখনও অন্য কোথাও অনানুষ্ঠানিকভাবে সমর্থিত কিনা ।
ddekany

প্রশ্ন, আপনি বলেন যে কোনও ইনসেট যেমন আমি ইনপুটটিতে নির্দিষ্ট করি '2011-07-01 06:30:30+00'এবং '2011-07-01 06:30:30+05'তা উপেক্ষা করা হয় তবে আমি insert into test_table (date) values ('2018-03-24T00:00:00-05:00'::timestamptz);তা করতে সক্ষম এবং এটি এটি সঠিকভাবে ইউটিসিতে রূপান্তরিত করে। যেখানে তারিখটি টাইমজোন ছাড়াই টাইমস্ট্যাম্প। টাইমজোন সহ টাইমস্ট্যাম্পের মূল মূল্যটি কী এবং সমস্যা হচ্ছে তা বোঝার চেষ্টা করছি।
pk1m

@ pk1m আপনি এই বিষয়টিকে জটিল করে তোলেন ::timestamptz। এর সাথে আপনি স্ট্রিংটিকে রূপান্তর করেন TIMESTAMP WITH TIME ZONEএবং যখন এটি আরও রূপান্তরিত হবে WITHOUT TIME ZONE, এটি আপনার সেশন সময় অঞ্চল (যা সম্ভবত ইউটিসি হতে পারে) থেকে দেখা যায় "তাত্ক্ষণিক দিন" এবং সেই তাত্ক্ষণিকের প্রাচীর ঘড়ির সময় সংরক্ষণ করবে। এটি এখনও কেবলমাত্র অনির্ধারিত অফসেট (কোনও অঞ্চল নয়) সহ একটি স্থানীয় টাইমস্ট্যাম্প হবে।
ddekany

আমি অজগর নিয়ে কাজ করছি এবং টাইমস্ট্যাম্প সচেতন ডেটটাইম অবজেক্টটি সন্নিবেশ করানো হলে যা sertedোকানো হয় তা ঠিক। এটি আমার কাছে টাইম জ্যামের সাথে টাইমস্ট্যাম্প ব্যবহারের মূল্য রয়েছে বলে মনে হয় তবে সময় অঞ্চলগুলি হ্যান্ডেল করার জন্য এটি প্রয়োজনীয় নয়।
pk1m

12

এখানে একটি উদাহরণ যা সাহায্য করা উচিত। আপনার যদি টাইমজোন সহ টাইমস্ট্যাম্প থাকে তবে আপনি সেই টাইমস্ট্যাম্পকে অন্য কোনও টাইমজোনতে রূপান্তর করতে পারেন। আপনি যদি বেস টাইমজোন না পেয়ে থাকেন তবে এটি সঠিকভাবে রূপান্তরিত হবে না।

SELECT now(),
   now()::timestamp,
   now() AT TIME ZONE 'CST',
   now()::timestamp AT TIME ZONE 'CST'

আউটপুট:

-[ RECORD 1 ]---------------------------
now      | 2018-09-15 17:01:36.399357+03
now      | 2018-09-15 17:01:36.399357
timezone | 2018-09-15 08:01:36.399357
timezone | 2018-09-16 02:01:36.399357+03

5
"সঠিকভাবে রূপান্তরিত হবে না" বিবৃতিটি কেবল সত্য নয়। আপনি বুঝতে timestampএবং কি timestamptzবোঝাতে হবে। timestamptzসময়ের একটি নিখুঁত পয়েন্ট (ইউটিসি) এর timestampঅর্থ যেখানে নির্দিষ্ট সময় অঞ্চলে ঘড়িটি কী দেখায় তা বোঝায়। সুতরাং, timestamptzটাইম জোনে রূপান্তর করার সময় আপনি জিজ্ঞাসা করছেন যে সময়টির এই পরম মুহূর্তে নিউ ইয়র্কের ক্লকটি কী দেখায়? অন্যদিকে "রূপান্তর" করার সময় timestamp, আপনি যখন জিজ্ঞাসা করছেন যে নিউ ইয়র্কের ঘড়িটি এক্স দেখিয়েছিল তখন সময়টির পরম পয়েন্টটি কী ছিল?
ফিলিপাইপ

AT TIME ZONEএমনকি যদি আপনি ইতিমধ্যে বুঝতে কনস্ট্রাক্ট নিজস্ব টিজার একটি মস্তিষ্ক WITHবনাম WITHOUT TIME ZONEধরনের। সুতরাং তাদের ব্যাখ্যা করার জন্য এটি একটি আগ্রহী পছন্দ choice (: ( AT TIME ZONEএকটি WITH TIME ZONEটাইমস্ট্যাম্পকে একটি টাইমস্ট্যাম্পে রূপান্তর করে WITHOUT TIME ZONEএবং তদ্বিপরীত ... একেবারে সুস্পষ্ট নয়))
ডিডেকানি

now()::timestamp AT TIME ZONE 'CST'জাজান 'সিএসটি' জন্য তাত্ক্ষণিক সময়ে আপনার স্থানীয় ঘড়িটি যে সময় প্রদর্শিত হচ্ছে তা আপনি যদি না দেখেন না
জেসেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.