অফসেট-নিষ্পাপ এবং অফসেট-সচেতন তারিখের সময়গুলি বিয়োগ করতে পারে না


305

timestamptzপোস্টগ্র্রেএসকিউএল-তে আমার একটি টাইমজোন সচেতন ক্ষেত্র রয়েছে। আমি যখন টেবিল থেকে ডেটা টানছি, আমি তখনই এখনই সময়টি বিয়োগ করতে চাই যাতে আমি এটির বয়স পেতে পারি।

আমার যে সমস্যাটি হচ্ছে তা হ'ল উভয়ই datetime.datetime.now()এবং datetime.datetime.utcnow()টাইমজোনকে অজান্ত টাইমস্ট্যাম্পগুলি ফেরত দেওয়ার জন্য বলে মনে হচ্ছে, যার ফলে আমার এই ত্রুটিটি পেয়েছে:

TypeError: can't subtract offset-naive and offset-aware datetimes 

এটি এড়ানোর কোনও উপায় আছে (তৃতীয় পক্ষের মডিউলটি ব্যবহার না করা)।

সম্পাদনা: পরামর্শগুলির জন্য ধন্যবাদ, যদিও টাইমজোনটি সামঞ্জস্য করার চেষ্টা করলে মনে হয় ত্রুটি হয়েছে .. সুতরাং আমি কেবল পিজিতে টাইমজোনকে অজানা টাইমস্ট্যাম্পগুলি ব্যবহার করতে যাচ্ছি এবং সর্বদা এটি ব্যবহার করে সন্নিবেশ করবো:

NOW() AT TIME ZONE 'UTC'

এইভাবে আমার সমস্ত টাইমস্ট্যাম্পগুলি ডিফল্টরূপে ইউটিসি (যদিও এটি করা আরও বিরক্তিকর)।

উত্তর:


316

আপনি কি টাইমজোন সচেতনতা অপসারণ করার চেষ্টা করেছেন?

http://pytz.sourceforge.net/ থেকে

naive = dt.replace(tzinfo=None)

পাশাপাশি সময় অঞ্চল রূপান্তর যুক্ত করতে পারে।

সম্পাদনা করুন: দয়া করে এই উত্তরটির বয়সটি সচেতন হন। পাইথন 3 এর উত্তর নীচে।


32
এটি এটি করার একমাত্র উপায় বলে মনে হচ্ছে। বেশ লম্পট দেখে মনে হচ্ছে যে টাইমজোনগুলির জন্য অজগরটির এমন কৃপণ সমর্থন পেয়েছে যে টাইমস্ট্যাম্পগুলি সঠিকভাবে কাজ করার জন্য এটি একটি তৃতীয় পক্ষের মডিউল প্রয়োজন ..
ইয়ান

33
: (জাস্ট রেকর্ডের জন্য) বাস্তবিক সময় অঞ্চল সম্পর্কে তথ্য যোগ করার সময় একটি ভালো ধারণা হতে পারে stackoverflow.com/a/4530166/548696
Tadeck

7
নিষ্পাপ ডেটটাইম অবজেক্টগুলি অন্তর্নিহিত অস্পষ্ট এবং তাই এগুলি এড়ানো উচিত। পরিবর্তে tzinfo যুক্ত
jfs

1
@ কাইলোটান: ইউটিসি এই প্রসঙ্গে একটি টাইমজোন (যেমন টিজিনফো শ্রেণি দ্বারা উপস্থাপিত)। তাকান datetime.timezone.utcবা pytz.utc। উদাহরণস্বরূপ, 1970-01-01 00:00:00দ্ব্যর্থক এবং আপনি দুর্বোধ্য করার জন্য একটি সময় অঞ্চল যোগ আছে: 1970-01-01 00:00:00 UTC। আপনি দেখুন, আপনি নতুন তথ্য যোগ করতে হবে ; টাইমস্ট্যাম্প নিজেই অস্পষ্ট।
jfs

1
@ জেএসএবেস্টিয়ান: সমস্যাটি হ'ল utcnowটাইমজোন ছাড়াই কোনও নিষ্পাপ বস্তু বা টাইমস্ট্যাম্প ফিরিয়ে দেওয়া উচিত নয়। দস্তাবেজগুলি থেকে, "একটি সচেতন অবজেক্ট সময় নির্দিষ্ট মুহুর্তের জন্য ব্যাবহার করা হয় যা ব্যাখ্যার জন্য উন্মুক্ত নয়"। ইউটিসিতে যে কোনও সময় সংজ্ঞা অনুসারে এই মানদণ্ডটি পূরণ করে।
কাইলোটন

213

সঠিক সমাধান হয় যোগ টাইমজোন তথ্য যেমন, পাইথন 3 একটি সচেতন DATETIME অবজেক্ট হিসেবে বর্তমান সময় পেতে:

from datetime import datetime, timezone

now = datetime.now(timezone.utc)

পুরানো পাইথন সংস্করণগুলিতে আপনি utctzinfo অবজেক্টটি নিজেরাই সংজ্ঞায়িত করতে পারেন (ডেটটাইম ডক্স থেকে উদাহরণ):

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)

class UTC(tzinfo):
  def utcoffset(self, dt):
    return ZERO
  def tzname(self, dt):
    return "UTC"
  def dst(self, dt):
    return ZERO

utc = UTC()

তারপর:

now = datetime.now(utc)

10
গৃহীত উত্তর আইএমএইচওর পক্ষে পরামর্শ হিসাবে tz অপসারণ করার চেয়ে ভাল।
শওটিহ

3
: এখানে পাইথন সময়ের অঞ্চলগুলোকে একটি তালিকা রয়েছে stackoverflow.com/questions/13866926/...
comfytoday

61

আমি জানি কিছু লোক এই জাতীয় ডাটাবেস ইন্টারঅ্যাকশনকে বিমূর্ত করতে বিশেষভাবে ইন্টারফেস হিসাবে জ্যাঙ্গো ব্যবহার করেন। জ্যাঙ্গো এমন ইউটিলিটি সরবরাহ করে যা এর জন্য ব্যবহার করা যেতে পারে:

from django.utils import timezone
now_aware = timezone.now()

আপনি কেবল এই ধরণের ইন্টারফেস ব্যবহার করে থাকলেও (সেটিংগুলিতে USE_TZ=Trueএকটি সচেতন ডেটটাইম পাওয়ার জন্য আপনাকে অন্তর্ভুক্ত করতে হবে) এমনকি আপনি একটি বেসিক জ্যাঙ্গো সেটিংস অবকাঠামো স্থাপন করতে হবে না ।

নিজেই, এটি সম্ভবত আপনাকে ইন্টারফেস হিসাবে জ্যাঙ্গো ব্যবহার করতে উদ্বুদ্ধ করার মতো পর্যাপ্ত জায়গা নয়, তবে আরও অনেকগুলি সুবিধা রয়েছে। অন্যদিকে, আপনি যদি এখানে হোঁচট খাচ্ছেন কারণ আপনি নিজের জ্যাঙ্গো অ্যাপ্লিকেশনটি ম্যাঙ্গাল করছেন (যেমনটি আমি করেছি) তবে সম্ভবত এটি সহায়তা করে ...


1
আপনার প্রয়োজন USE_TZ=True, একটি সচেতন তারিখের সময় এখানে পেতে।
jfs

2
হ্যাঁ - আমি উল্লেখ করতে ভুলে গেছি যে জেএফএসবেস্টিয়ান বর্ণনা করার সাথে সাথে আপনাকে আপনার সেটিংস সেট করতে হবে pyপি (আমার ধারণা এটি 'সেট এবং ভুলে যাওয়ার' উদাহরণ ছিল)।
ঋষি

এবং এটি সহজেই অন্যান্য + timedelta(hours=5, minutes=30)
টাইমজোনগুলিতেও

25

এটি একটি খুব সহজ এবং স্পষ্ট সমাধান
দুটি লাইনের কোড

# First we obtain de timezone info o some datatime variable    

tz_info = your_timezone_aware_variable.tzinfo

# Now we can subtract two variables using the same time zone info
# For instance
# Lets obtain the Now() datetime but for the tz_info we got before

diff = datetime.datetime.now(tz_info)-your_timezone_aware_variable

উপসংহার: আপনার একই সময় তথ্যের সাথে আপনার ডেটটাইম ভেরিয়েবলগুলি পরিচালনা করতে হবে


ত্রুটিপূর্ণ? আমার লেখা কোডটি পরীক্ষা করা হয়েছিল এবং আমি এটি জ্যাঙ্গো প্রকল্পে ব্যবহার করছি। এটি অনেক বেশি পরিষ্কার এবং সহজ
ePi272314

"ভুল" আপনার উত্তরের শেষ বাক্যটিকে বোঝায়: "... অবশ্যই যুক্ত করতে হবে ... ইউটিসি নয়" - ইউটিসি টাইমজোন এখানে কাজ করে এবং তাই বিবৃতিটি ভুল।
jfs

হতে স্পষ্ট আমি বোঝানো: diff = datetime.now(timezone.utc) - your_timezone_aware_variableকাজ (এবং (a - b)সূত্র ব্যাখ্যা কেন উপরে (a - b)এমনকি কাজ করতে পারেন যদি a.tzinfoনয় b.tzinfo)।
jfs

6

সাইকোপজি 2 মডিউলের নিজস্ব টাইমজোন সংজ্ঞা রয়েছে, সুতরাং আমি নিজের ক্যাপচারটি প্রায় শেষের দিকে লিখে লিখলাম:

def pg_utcnow():
    import psycopg2
    return datetime.utcnow().replace(
        tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=0, name=None))

এবং pg_utcnowপোস্টগ্র্রেএসকিউএল এর সাথে তুলনা করার জন্য যখনই আপনার বর্তমান সময়ের প্রয়োজন তখনই ব্যবহার করুনtimestamptz


যে কোনও tzinfo অবজেক্ট যে শূন্য utc অফসেটটি দেয় তা করবে, উদাহরণস্বরূপ
jfs

6

আমিও একই সমস্যার মুখোমুখি হয়েছি। তারপরে আমি অনেক সন্ধানের পরে একটি সমাধান পেয়েছি।

সমস্যাটি হ'ল আমরা যখন মডেল বা ফর্ম থেকে ডেটটাইম অবজেক্টটি পাই তখন তা অফসেট থাকে এবং আমরা যদি সিস্টেমের মাধ্যমে সময় পাই তবে তা অফসেট অফ স্পষ্ট ।

তাই আমি কি আমি বর্তমান সময় ব্যবহার পেয়েছিলাম timezone.now () দ্বারা টাইমজোন আমদানি django.utils আমদানি সময় অঞ্চল থেকে এবং করা USE_TZ = true আপনার প্রকল্পের সেটিংস ফাইলে।


2

আমি একটি অতি-সহজ সমাধান নিয়ে এসেছি:

import datetime

def calcEpochSec(dt):
    epochZero = datetime.datetime(1970,1,1,tzinfo = dt.tzinfo)
    return (dt - epochZero).total_seconds()

এটি টাইমজোন-সচেতন এবং টাইমজোন-নিষ্পাপ ডেটটাইম মানগুলির সাথে কাজ করে। এবং কোনও অতিরিক্ত লাইব্রেরি বা ডাটাবেস ওয়ার্কআরউন্ডের প্রয়োজন নেই।


1

আমি খুঁজে পেয়েছি timezone.make_aware(datetime.datetime.now())জাঙ্গোতে সহায়ক (আমি 1.9.1 এ আছি)। দুর্ভাগ্যক্রমে আপনি কেবল কোনও datetimeঅবজেক্টকে অফসেট-সচেতন করতে পারবেন না , তবে timetz()এটি। আপনাকে এর datetimeভিত্তিতে তুলনা করতে হবে।


1

আপনি পোস্টগ্রিজএসকিউএল এ বয়সের গণনাটি পরিচালনা করতে পারবেন না এমন কোন চাপ দেওয়ার কারণ আছে? কিছুটা এইরকম

select *, age(timeStampField) as timeStampAge from myTable

2
হ্যাঁ আছে .. তবে আমি বেশিরভাগই জিজ্ঞাসা করছিলাম কারণ আমি পোস্টগ্রিতে সমস্ত গণনা করা এড়াতে চাই।
আয়ান

0

আমি জানি এটি পুরানো, তবে কেবল ভেবেছিলাম যে কেউ যদি এটির কাজে লাগে তবে আমি আমার সমাধানটি যুক্ত করব।

আমি স্থানীয় নিষ্পাপ ডেটটাইমকে একটি টাইমসারকের একটি সচেতন ডেটটাইমের সাথে তুলনা করতে চেয়েছিলাম। আমি সচেতন ডেটটাইম অবজেক্টটি ব্যবহার করে মূলত একটি নতুন নিষ্পাপ ডেটটাইম অবজেক্ট তৈরি করেছি। এটি কিছুটা হ্যাক এবং দেখতে খুব সুন্দর লাগে না তবে কাজটি হয়ে যায়।

import ntplib
import datetime
from datetime import timezone

def utc_to_local(utc_dt):
    return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)    

try:
    ntpt = ntplib.NTPClient()
    response = ntpt.request('pool.ntp.org')
    date = utc_to_local(datetime.datetime.utcfromtimestamp(response.tx_time))
    sysdate = datetime.datetime.now()

... এখানে আসল ...

    temp_date = datetime.datetime(int(str(date)[:4]),int(str(date)[5:7]),int(str(date)[8:10]),int(str(date)[11:13]),int(str(date)[14:16]),int(str(date)[17:19]))
    dt_delta = temp_date-sysdate
except Exception:
    print('Something went wrong :-(')

এফওয়াইআই, utc_to_local()আমার উত্তর থেকে স্থানীয় সময় সচেতন তারিখের অবজেক্ট হিসাবে ফিরে আসে (এটি পাইথন 3.3+ কোড)
জেফএস

আপনার কোডটি কী করার চেষ্টা করছে তা পরিষ্কার নয়। আপনি এটি দিয়ে প্রতিস্থাপন করতে পারে delta = response.tx_time - time.time()
jfs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.