একটি সাধারণ স্ট্রিং থেকে কীভাবে একটি টাইমডেল্টা অবজেক্ট তৈরি করা যায়


100

আমি একটি ফাংশন লিখছি যা একটি স্ট্রিং হিসাবে পাস করতে একটি টাইমডেল্টা ইনপুট প্রয়োজন। ব্যবহারকারীর অবশ্যই "32 মি" বা "2h32 এম", বা "4:13" বা "5hr34m56s" এর মতো কিছু প্রবেশ করতে হবে ... এমন কোনও গ্রন্থাগার বা এমন কিছু রয়েছে যা ইতিমধ্যে এই ধরণের জিনিসটি প্রয়োগ করা হয়েছে?


মানুষের জন্য মাত্র একটি timedelta বস্তু গঠন করতে খুঁজছি dদিন, hঘন্টা, mমিনিট এবং sসেকেন্ড এক লাইন ব্যবহার (আমদানি পর datetime): datetime.timedelta(days = d, hours = h, minutes=m, seconds=s)
zthomas.nc

উত্তর:


74

প্রথম ফর্ম্যাট (5hr34m56s) এর জন্য, আপনার নিয়মিত এক্সপ্রেশন ব্যবহার করে পার্স করা উচিত

এখানে পুনরায় ভিত্তিক সমাধান:

import re
from datetime import timedelta


regex = re.compile(r'((?P<hours>\d+?)hr)?((?P<minutes>\d+?)m)?((?P<seconds>\d+?)s)?')


def parse_time(time_str):
    parts = regex.match(time_str)
    if not parts:
        return
    parts = parts.groupdict()
    time_params = {}
    for (name, param) in parts.iteritems():
        if param:
            time_params[name] = int(param)
    return timedelta(**time_params)


>>> from parse_time import parse_time
>>> parse_time('12hr')
datetime.timedelta(0, 43200)
>>> parse_time('12hr5m10s')
datetime.timedelta(0, 43510)
>>> parse_time('12hr10s')
datetime.timedelta(0, 43210)
>>> parse_time('10s')
datetime.timedelta(0, 10)
>>> 

4
আমি এমন একধরণের ফাংশনের কথা ভাবছিলাম যা আপনি এতে ফেলে আসা যে কোনও কিছু নিতে পারেন এবং এখনও টাইমডেল্টায় রূপান্তর করতে সক্ষম হবেন।
পুরোহিত

4
আমি পুনরায় ভিত্তিক সমাধানের উদাহরণ যুক্ত করেছি :)
কুমিলি

4
আমি দেখতে পাই না যে ডেটুটি.টি. পার্সার.পারস কীভাবে সময়সীমা পার্স করতে পারে, মনে হয় এটি সর্বদা একটি তারিখের সময় দেয়। আমি কী মিস করছি?
নিকোলে

7
dateutil.parser.parsetimedeltaবস্তু বিশ্লেষণ করবে না । এটি একটি দেয় datetime, এবং এটি স্ট্রিংগুলির মতো একটি ব্যতিক্রম ট্রিগার করবে '28:32:11.10'
স্পষ্টভাবে

99

আমার কাছে সবচেয়ে মার্জিত সমাধান, যেমন বাহ্যিক লাইব্রেরি অবলম্বন না করেও dateutil অথবা নিজে ইনপুট পার্স, ব্যবহার করা হয় DATETIME এর শক্তিশালী strptimeস্ট্রিং পার্সিং পদ্ধতি।

from datetime import datetime, timedelta
# we specify the input and the format...
t = datetime.strptime("05:20:25","%H:%M:%S")
# ...and use datetime's hour, min and sec properties to build a timedelta
delta = timedelta(hours=t.hour, minutes=t.minute, seconds=t.second)

এর পরে আপনি আপনার টাইমডেল্টা অবজেক্টটি স্বাভাবিক হিসাবে ব্যবহার করতে পারেন, এটি সঠিকভাবে করা হয়েছে তা নিশ্চিত করার জন্য এটি সেকেন্ডে রূপান্তর করুন etc.

print(delta)
assert(5*60*60+20*60+25 == delta.total_seconds())

33
নোট করুন এই পদ্ধতিটি কেবল তখনই কাজ করে যদি টাইমস্প্যানটি 24 ঘন্টাের চেয়ে কম হয় ( datetime.strptime("32:20:25","%H:%M:%S")কাজ করে না) এবং আপনাকে সঠিক ইনপুট ফর্ম্যাটটি জানতে হবে।
রায়সামারাল্ড

এটি ওপি'র প্রশ্নেরও উত্তর দেয় answers যদি ফাংশনটির একাধিক ফর্ম্যাটগুলির সাথে ডিল করতে হয় - আপনার এখনও অতিরিক্ত ফর্ম্যাট পরিদর্শন প্রয়োজন (1 কোলন বা 2?)।
ড্যানি স্ট্যাপল

4
@verdesmarald সুতরাং, অজগর 3.5 হিসাবে, কি বাহ্যিক লাইব্রেরি ব্যবহার না করে এবং টাইমস্প্যানটি 24 ঘন্টারও কম অনুমান না করে একটি দুর্দান্ত সমাধান রয়েছে?
সর্বাধিক

4
আমি timedeltaখুব বিরক্তিকর প্যারামিটারের জন্য নামকরণকৃত প্যারামিটারগুলি ম্যানুয়ালি নির্দিষ্ট করার প্রয়োজনটি পেয়েছি , তবে এটি এড়াতে আমি যে সেরাটি সামনে আসতে পারি তা হ'ল: delta = t - datetime.combine(t.date(), time.min)যা ভয়ঙ্কর।
কাইল স্ট্র্যান্ড

4
এই পদ্ধতির একটি গুরুতর সমস্যা হ'ল যদি আপনি দিনগুলি অন্তর্ভুক্ত করেন তবে% d কে স্ট্রপটাইমে প্রেরণ করা আপনাকে দিন 0 ইনপুট করতে সক্ষম করবে না, কারণ কেবল = = 1 এর দিনগুলি একটি তারিখের জন্য বৈধ।
ব্যবহারকারী 1581390

77

আমি আমার হাতে গতকাল সময় একটি বিট ছিল, তাই আমি বিকশিত @virhilo এর উত্তর একটি পাইথন মডিউল মধ্যে, সমস্ত অনুরোধ সহ আরো কয়েকটি সময় অভিব্যক্তি ফরম্যাটের যোগ @priestc

সোর্স কোড যে কেউ চায় তার জন্য গিথুব (এমআইটি লাইসেন্স) রয়েছে। এটি পিপিআইতেও রয়েছে:

pip install pytimeparse

সেকেন্ডের সংখ্যা হিসাবে সময়টি ফেরত দেয়:

>>> from pytimeparse.timeparse import timeparse
>>> timeparse('32m')
1920
>>> timeparse('2h32m')
9120
>>> timeparse('4:13')
253
>>> timeparse('5hr34m56s')
20096
>>> timeparse('1.2 minutes')
72

একটি জাভা / স্কাল সমতুল্য আছে?
luca.giovagnoli

অসাধারণ! অনেক অনেক ধন্যবাদ
বাউনার

@ luca.giovagnoli স্কালায় আপনি সময়কাল শ্রেণি ব্যবহার করতে পারেন। সময়কাল '15 সেকেন্ড ',' 4 মিনিট 'ইত্যাদির মতো স্ট্রিং থেকে তৈরি করা যেতে পারে
কোনারাদ মালিক

14

আমি মাত্র একটি সময় ইনপুট করতে চেয়েছিলাম এবং তারপরে এটি বিভিন্ন তারিখে যুক্ত করতে চেয়েছিলাম যাতে এটি আমার পক্ষে কাজ করে:

from datetime import datetime as dtt

time_only = dtt.strptime('15:30', "%H:%M") - dtt.strptime("00:00", "%H:%M")

dtt.strptime(myduration, "%H:%M:%S") - dtt(1900, 1, 1)এছাড়াও কাজ করে ...
576i

8

আমি সংশোধন করেছি কয়েকটি আপগ্রেড সহ ভারিলোর দুর্দান্ত উত্তরটি :

  • একটি জোড় যুক্ত করেছে যে স্ট্রিংটি একটি বৈধ সময় স্ট্রিং
  • "এইচ" সাথে "এইচ" ঘন্টা ঘন্টা সূচকটি প্রতিস্থাপন করুন
  • একটি "ডি" - দিন সূচক জন্য অনুমতি দিন
  • অ-পূর্ণসংখ্যার সময়গুলিকে অনুমতি দিন (উদাহরণস্বরূপ 3m0.25s3 মিনিট, 0.25 সেকেন্ড)

import re
from datetime import timedelta


regex = re.compile(r'^((?P<days>[\.\d]+?)d)?((?P<hours>[\.\d]+?)h)?((?P<minutes>[\.\d]+?)m)?((?P<seconds>[\.\d]+?)s)?$')


def parse_time(time_str):
    """
    Parse a time string e.g. (2h13m) into a timedelta object.

    Modified from virhilo's answer at https://stackoverflow.com/a/4628148/851699

    :param time_str: A string identifying a duration.  (eg. 2h13m)
    :return datetime.timedelta: A datetime.timedelta object
    """
    parts = regex.match(time_str)
    assert parts is not None, "Could not parse any time information from '{}'.  Examples of valid strings: '8h', '2d8h5m20s', '2m4s'".format(time_str)
    time_params = {name: float(param) for name, param in parts.groupdict().items() if param}
    return timedelta(**time_params)

4
দুর্দান্ত! আমি উপাদানগুলিতে "* 3" 5 মি "" এর অনুমতি দেওয়ার জন্য যুক্ত করেছিলাম
মার্সেল ওয়াল্ডভোগেল

@ মার্সেলওয়ালডভোগেল চমৎকার, আপনি যদি নতুন রেজেক্সের লেখাটি অনুলিপি করেন তবে আমি আপনার উত্তরটি যুক্ত করব
পিটার

@ ভাইহিলো এবং পিটার: আপনার কোড সম্পর্কে আমার সামান্য বিবর্তন এখানে: github.com/zeitgitter/zeitgitterd/blob/master/zeitgitter/… । আমার ধারণা আপনার কোডটি ব্যবহার করা ঠিক আছে। লাইসেন্সের জন্য আপনার কি কোনও পছন্দ আছে? এমআইটি, আপাচি, জিপিএল,…?
মার্সেল ওয়াল্ডভোগেল

4
মার্সেল, আপনি কি আমাকে আপনার ঠিকানা পাঠাতে পারেন যাতে আমি মামলা করতে পারি? জে কে এগিয়ে যান যে কোনও লাইসেন্স ঠিক আছে।
পিটার

এখানে নতুন রেজেক্স; পার্থক্যটি হ'ল "*" s: regex = re.compile (r '^ ((? পি <দিন>> [\। \ d] +?) ডি)? *' আর '((? পি <ঘন্টা / পূর্ব> \ । \ d] +?) জ)? * 'আর' ((? পি <মিনেটস> [\। \ d] +?) মি)? * 'আর' ((? পি <সেকেন্ডস> [\। \ d]) +?) গুলি)?) ')
মার্সেল ওয়াল্ডভোগেল

3

জাজানো ইউটিলিটি ফাংশন নিয়ে আসে parse_duration()ডকুমেন্টেশন থেকে :

একটি স্ট্রিং পার্স করে এবং a প্রদান করে datetime.timedelta

ফর্ম্যাটে "DD HH:MM:SS.uuuuuu"বা আইএসও 8601 (যেমন P4DT1H15M20Sসমতুল্য 4 1:15:20) বা পোস্টগ্রিসএসকিউএল-এর ডে-টাইম ইন্টারভাল ফর্ম্যাট (যেমন 3 days 04:05:06) দ্বারা নির্দিষ্ট করা ডেটা আশা করে ।


আরও তথ্যের জন্য: জ্যাঙ্গোর parse_duration()ফাংশনটি হুডের নীচে রেজেক্স ম্যাচ ব্যবহার করে।
oদ 95

2

আপনি যদি পাইথন 3 ব্যবহার করেন তবে হরি শঙ্করের সমাধানের জন্য এখানে আপডেট হওয়া সংস্করণ, যা আমি ব্যবহার করেছি:

from datetime import timedelta
import re

regex = re.compile(r'(?P<hours>\d+?)/'
                   r'(?P<minutes>\d+?)/'
                   r'(?P<seconds>\d+?)$')

def parse_time(time_str):
    parts = regex.match(time_str)
    if not parts:
        return
    parts = parts.groupdict()
    print(parts)
    time_params = {}
    for name, param in parts.items():
        if param:
            time_params[name] = int(param)
    return timedelta(**time_params)

0

আইএসও 8601 সময়কাল স্ট্রিং পার্স করতে আইসোডেট লাইব্রেরি ব্যবহার করুন । উদাহরণ স্বরূপ:

isodate.parse_duration('PT1H5M26S')

এছাড়াও দেখুন কি আইএসও 8601 সময়কালকে সময়সীমাতে রূপান্তর করার কোনও সহজ উপায় আছে?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.