স্ক্রিপ্ট বা ফাংশন একটি নির্দিষ্ট তারিখ থেকে এখন থেকে কত দিন ফিরে আসবে


28

ভবিষ্যতে প্রদত্ত তারিখ হতে এখন থেকে কত দিন আছে তা আমাকে জানাতে আমি কোনও স্ক্রিপ্ট লিখতে চাই বা ফাংশন লিখতে চাই। আমি যে কাজটি করার জন্য সংগ্রাম করছি তা হ'ল কীভাবে প্রদত্ত তারিখটি প্রক্রিয়া করা যায় এবং এটি বর্তমান তারিখের সাথে তুলনা করা যায় ... আমি এরকম কিছু কল্পনা করছি

read -p "enter the date in the format YYYY-MM-DD "

এবং তারপরে আমি ধরে নিচ্ছি আমার কাছে একটি স্ট্রিং রয়েছে যা শেলের অর্থহীন এবং আমাকে কিছু মূল্যায়ন করতে হবে যেমন ... ?? (এটি কেবল একটি উদাহরণ; আমি অনুমান করি bcযে এটি প্রয়োজন হবে)

i=$(($(date +%Y)-${REPLY%%-*}))
j=$(($(date +%m)-${REPLY:5:2}))
k=$(($(date +%d)-${REPLY##*-}))

এবং তারপরে আমি জানি না যে এই সংখ্যাগুলি দিয়ে কী করব ... ??

if $i > 1 then assign l=$((i*365)) and else what?? # what about leap years?
Using $j somehow assign m   # confused before I've started
Using $k somehow assign n   # just as bad
echo $((l+m+n))   

আমি অবশ্যই এটি নিজের জন্য খুব কঠিন করে তুলছি; সম্ভবত একটি পাঠ্য প্রক্রিয়াকরণ সরঞ্জাম রয়েছে যা তারিখগুলি বোঝে এবং তাদের সাথে তুলনা করতে পারে।

কিভাবে আমি এটি করতে পারব?


সম্ভবত অজগর নেই? যাইহোক, সময়কে যুগের সময় রূপান্তর করুন (যে কোনও বিন্যাসে হতে পারে), তবে এটি সহজ :)
জ্যাকব ভ্লিজম

@ জ্যাকবভিলিজম পাইথনের সমাধানটি সম্পূর্ণরূপে স্বাগত - এটি যখন আমাকে অবশেষে অজগর এক্সডি শিখতে উঠতে সাহায্য করবে এবং আমি এটিও কাজ করতে চাই :)
জান্না

উত্তর:


29

যুগের সময়

সাধারণভাবে, সময়কে গণনা করা সবচেয়ে সহজ তবে যদি আমরা প্রথমে সময়কে (ইউনিক্স) যুগে রূপান্তর করি সময়কে (1-1-1970 থেকে সেকেন্ড । পাইথনে, আমাদের কাছে সময়কে সময়কে রূপান্তর করার সরঞ্জাম রয়েছে এবং আমরা যে কোনও তারিখের ফর্ম্যাটে পছন্দ করি।

আমরা কেবল একটি ফর্ম্যাট সেট করতে পারি, যেমন:

pattern = "%Y-%m-%d"

... এবং আজ সংজ্ঞা দিন:

today = "2016-12-07"

এবং পরবর্তীকালে কাজটি করার জন্য একটি ফাংশন লিখুন:

def convert_toepoch(pattern, stamp):
    return int(time.mktime(time.strptime(stamp, pattern)))

তারপরে আউটপুট:

nowepoch = convert_toepoch(pattern, today)
print(nowepoch)

> 1481065200

... যা উল্লেখ করা হয়েছে, 1-1-1970 সাল থেকে সেকেন্ডের সংখ্যা

দুটি তারিখের মধ্যে দিন গণনা করা

আমরা যদি আজ এবং আমাদের ভবিষ্যতের তারিখ উভয় ক্ষেত্রে এটি করি তবে পরবর্তীকালে পার্থক্যটি গণনা করুন:

#!/usr/bin/env python3
import time

# set our date pattern
pattern = "%Y-%m-%d" 

def convert_toepoch(pattern, stamp):
    return int(time.mktime(time.strptime(stamp, pattern)))

# automatically get today's date 
today = time.strftime(pattern); future = "2016-12-28"

nowepoch = convert_toepoch(pattern, today)
future_epoch = convert_toepoch(pattern, future)

print(int((future_epoch - nowepoch)/86400))

ফলাফলটি তারিখ অনুসারে গণনা করা হবে , যেহেতু আমরা ফর্ম্যাটটি ব্যবহার করি %Y-%m-%dসেকেন্ডে গোল হয় সম্ভবত একটি ভুল তারিখের পার্থক্য দিতে পারে, যদি আমরা উদাহরণস্বরূপ 24 ঘন্টা এর কাছাকাছি থাকি।

টার্মিনাল সংস্করণ

#!/usr/bin/env python3
import time

# set our date pattern
pattern = "%Y-%m-%d" 

def convert_toepoch(pattern, stamp):
    return int(time.mktime(time.strptime(stamp, pattern)))

# automatically get today's date 
today = time.strftime(pattern)
# set future date
future = input("Please enter the future date (yyyy-mm-dd): ")
nowepoch = convert_toepoch(pattern, today)
future_epoch = convert_toepoch(pattern, future)
print(int((future_epoch - nowepoch)/86400))

এখানে চিত্র বর্ণনা লিখুন

... এবং Zenity বিকল্প

#!/usr/bin/env python3
import time
import subprocess

# set our date pattern
pattern = "%Y-%m-%d" 

def convert_toepoch(pattern, stamp):
    return int(time.mktime(time.strptime(stamp, pattern)))

# automatically get today's date 
today = time.strftime(pattern)
# set future date
try:
    future = subprocess.check_output(
        ["zenity", "--entry", "--text=Enter a date (yyyy-mm-dd)"]
        ).decode("utf-8").strip()
except subprocess.CalledProcessError:
    pass
else:     
    nowepoch = convert_toepoch(pattern, today)
    future_epoch = convert_toepoch(pattern, future)
    subprocess.call(
        ["zenity", "--info",
         "--text="+str(int((future_epoch - nowepoch)/86400))
         ])

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

এবং শুধু মজা করার জন্য ...

একটি ছোট অ্যাপ্লিকেশন। আপনি যদি প্রায়শই এটি ব্যবহার করেন তবে এটি একটি শর্টকাটে যুক্ত করুন।

এখানে চিত্র বর্ণনা লিখুন

এই পান্ডুলিপি:

#!/usr/bin/env python3
import time
import subprocess
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango, Gdk

class OrangDays(Gtk.Window):

    def __init__(self):

        self.pattern = "%Y-%m-%d" 
        self.currdate = time.strftime(self.pattern)
        big_font = "Ubuntu bold 45"
        self.firstchar = True

        Gtk.Window.__init__(self, title="OrangeDays")
        maingrid = Gtk.Grid()
        maingrid.set_border_width(10)
        self.add(maingrid)

        datelabel = Gtk.Label("Enter date")
        maingrid.attach(datelabel, 0, 0, 1, 1)

        self.datentry = Gtk.Entry()
        self.datentry.set_max_width_chars(12)
        self.datentry.set_width_chars(12)
        self.datentry.set_placeholder_text("yyyy-mm-dd")
        maingrid.attach(self.datentry, 2, 0, 1, 1)

        sep1 = Gtk.Grid()
        sep1.set_border_width(10)
        maingrid.attach(sep1, 0, 1, 3, 1)

        buttongrid = Gtk.Grid()
        buttongrid.set_column_homogeneous(True)
        maingrid.attach(buttongrid, 0, 2, 3, 1)

        fakebutton = Gtk.Grid()
        buttongrid.attach(fakebutton, 0, 0, 1, 1)

        calcbutton = Gtk.Button("Calculate")
        calcbutton.connect("clicked", self.showtime)
        calcbutton.set_size_request(80,10)
        buttongrid.attach(calcbutton, 1, 0, 1, 1)

        fakebutton2 = Gtk.Grid()
        buttongrid.attach(fakebutton2, 2, 0, 1, 1)

        sep2 = Gtk.Grid()
        sep2.set_border_width(5)
        buttongrid.attach(sep2, 0, 1, 1, 1)

        self.span = Gtk.Label("0")
        self.span.modify_font(Pango.FontDescription(big_font))
        self.span.set_alignment(xalign=0.5, yalign=0.5)
        self.span.modify_fg(Gtk.StateFlags.NORMAL, Gdk.color_parse("#FF7F2A"))
        maingrid.attach(self.span, 0, 4, 100, 1)

        sep3 = Gtk.Grid()
        sep3.set_border_width(5)
        maingrid.attach(sep3, 0, 5, 1, 1)

        buttonbox = Gtk.Box()
        maingrid.attach(buttonbox, 0, 6, 3, 1)
        quitbutton = Gtk.Button("Quit")
        quitbutton.connect("clicked", Gtk.main_quit)
        quitbutton.set_size_request(80,10)
        buttonbox.pack_end(quitbutton, False, False, 0)

    def convert_toepoch(self, pattern, stamp):
        return int(time.mktime(time.strptime(stamp, self.pattern)))

    def showtime(self, button):
        otherday = self.datentry.get_text()
        try:
            nextepoch = self.convert_toepoch(self.pattern, otherday)
        except ValueError:
            self.span.set_text("?")
        else:
            todayepoch = self.convert_toepoch(self.pattern, self.currdate)
            days = str(int(round((nextepoch-todayepoch)/86400)))
            self.span.set_text(days)


def run_gui():
    window = OrangDays()
    window.connect("delete-event", Gtk.main_quit)
    window.set_resizable(True)
    window.show_all()
    Gtk.main()

run_gui()
  • এটি একটি খালি ফাইলে অনুলিপি করুন, এটি সংরক্ষণ করুন orangedays.py
  • চালাও এটা:

    python3 /path/to/orangedays.py

এটি গুটিয়ে রাখা

নিম্নলিখিত .desktopফাইলের উপরে ক্ষুদ্র অ্যাপ্লিকেশন স্ক্রিপ্টের জন্য ব্যবহার করুন:

[Desktop Entry]
Exec=/path/to/orangedays.py
Type=Application
Name=Orange Days
Icon=org.gnome.Calendar

এখানে চিত্র বর্ণনা লিখুন

  • একটি খালি ফাইলে কোড কপি করুন, যেমন এটি সংরক্ষণ orangedays.desktopমধ্যে~/.local/share/applications
  • লাইনের মাঝে

    Exec=/path/to/orangedays.py

    স্ক্রিপ্টের আসল পথ নির্ধারণ করুন ...


23

গনুহ dateইউটিলিটি জিনিস এই সাজানোর বেশ ভাল। এটি একটি ভাল বিভিন্ন তারিখের ফর্ম্যাটগুলি পার্স করতে সক্ষম হয় এবং তারপরে অন্য ফর্ম্যাটে আউটপুট দেয়। এখানে আমরা %sযুগের পর থেকে কয়েক সেকেন্ডের আউটপুট ব্যবহার করি । এরপরে বিয়োগ করে 86400 সেকেন্ড / দিন দ্বারা ভাগ করা $nowএটি পাটিগণিতের সাধারণ বিষয় is$future

#!/bin/bash

read -p "enter the date in the format YYYY-MM-DD "

future=$(date -d "$REPLY" "+%s")
now=$(date "+%s")
echo "$(( ( $future / 86400 ) - ( $now / 86400 ) )) days"

ভুল রাউন্ডিং বাদে (মনে হয়) এটি ভালভাবে কাজ করে! জিএনইউ তারিখের ক্ষমতাগুলিকে সন্দেহ করার জন্য আমি নির্বোধ অনুভব করছি :) ধন্যবাদ :)
Zanna

1
@ জাংনা - আমি মনে করি যে গোলটি সমস্যাটির সমাধানটি পার্থক্য নেওয়ার আগে কেবল 86400 দ্বারা উভয় টাইমস্ট্যাম্পগুলিকে পূর্ণসংখ্যা-ভাগ করে নেওয়া। তবে এখানে কিছু বিশদ থাকতে পারে যা আমি এখানে মিস করছি। এছাড়াও আপনি কি চান যে প্রবেশের তারিখটি স্থানীয় সময় বা ইউটিসি হোক? যদি এটির ইউটিসি হয়, তবে এতে -uপ্যারামিটার যুক্ত করুন date
ডিজিটাল ট্রমা

যে দিনগুলিতে সাধারণ সময় এবং দিবালোক সংরক্ষণের সময়ের মধ্যে স্যুইচ হয়, সেগুলি +/- 1 ঘন্টা আলাদা হতে পারে এবং খুব কম সময়েই সংশোধন সেকেন্ড নির্দিষ্ট দিনগুলিতে রাখা হয়। তবে বাস্তবে, বেশিরভাগ ক্ষেত্রে এটি গুরুত্বহীন হতে পারে।
ব্যবহারকারী অজানা

10

আপনি ফাংশনটি awkব্যবহার করে কিছু করার চেষ্টা করতে পারেনmktime

awk '{print (mktime($0) - systime())/86400}'

সপ্তাহটি "YYYY এমএম ডিডি এইচএইচ এমএম এসএস" ফর্ম্যাটে স্ট্যান্ডার্ড ইনপুট থেকে তারিখটি পড়ার প্রত্যাশা করে এবং তারপরে নির্দিষ্ট সময় এবং দিনের মধ্যে বর্তমান সময়ের পার্থক্য মুদ্রণ করে।

mktimeকেবল একটি সময়কে (নির্দিষ্ট বিন্যাসে) একটি রেফারেন্স সময় থেকে সেকেন্ডের সংখ্যায় রূপান্তর করে (1970-01-01 00:00:00 ইউটিসি); সিসটাইম সরল বর্তমান ফর্ম্যাটটিকে একই ফর্ম্যাটে উল্লেখ করে। একে অপরের থেকে বিয়োগ করুন এবং আপনি সেকেন্ডের মধ্যে কতটা দূরে। দিনগুলিতে রূপান্তর করতে 86400 (24 * 60 * 60) দিয়ে ভাগ করুন।


1
ভাল, তবে একটি সমস্যা আছে: আমি অনুমান করি যে আপনি ভাসমান হিসাবে দিনের সংখ্যা চান না, তবে কেবল 86400 দ্বারা ভাগ করা কার্যকর হবে না, সমাধান হিসাবে সম্ভাব্য
গোলাকারটি

দ্রষ্টব্য অবাক সময় ফাংশনগুলি পসিক্স নয়
স্টিভেন পেনি

10

এখানে একটি রুবি সংস্করণ

require 'date'

puts "Enter a future date in format YYYY-MM-DD"
answer = gets.chomp

difference = (Date.parse(answer) - Date.today).numerator

puts difference > 1 ? "That day will come after #{difference} days" :
  (difference < 0) ? "That day passed #{difference.abs} days ago" :
 "Hey! That is today!"

উদাহরণ রান:

স্ক্রিপ্ট চালানোর উদাহরণ ruby ./day-difference.rbনীচে দেওয়া হয়েছে (ধরে নিলেন আপনি এটি সংরক্ষণ করেছেন day-difference.rb)

ভবিষ্যতের তারিখ সহ

$ ruby day-difference.rb
Enter a future date in format YYYY-MM-DD
2021-12-30
That day will come after 1848 days

পাশের তারিখ সহ

$ ruby day-difference.rb
Enter a future date in format YYYY-MM-DD
2007-11-12
That day passed 3314 days ago

আজকের তারিখটি কখন পাস হয়েছে

$ ruby day-difference.rb
Enter a future date in format YYYY-MM-DD
2016-12-8
Hey! That is today!

তারিখের পার্থক্যগুলি পরীক্ষা করার জন্য এখানে একটি সুন্দর ওয়েবসাইট ww http://www.timeanddate.com/date/duration.html


অসাধারণ! তাই সহজ এবং পরিষ্কার।
রুবিটিকে

Greatgreat! রুবিকে স্বাগতম
জ্যাকব ভিলিজম

1
@ জান্না ধন্যবাদ। বকঝ. আপনি যদি 15 টি টাকাপয়সা পেয়ে থাকেন তবে ট্রাইবুবি এখানে আছে। :)
আনোয়ার

@ জ্যাকবভিলিজম উত্সাহের জন্য আপনাকে ধন্যবাদ। যদিও আমি এখনও ছাত্র আছি :)
আনোয়ার

6

একটি dateutilsপ্যাকেজ রয়েছে যা খেজুর মোকাবেলার জন্য খুব সুবিধাজনক। এটি সম্পর্কে এখানে আরও পড়ুন গিথুব: ডেটুটিলস

এটি দ্বারা ইনস্টল করুন

sudo apt install dateutils

আপনার সমস্যার জন্য, সহজভাবে,

dateutils.ddiff <start date> <end date> -f "%d days"

যেখানে আউটপুটটি সেকেন্ড, মিনিট, ঘন্টা, দিন, সপ্তাহ, মাস বা বছর হিসাবে বেছে নেওয়া যেতে পারে। এটি স্ক্রিপ্টগুলিতে সুবিধাজনকভাবে ব্যবহার করা যেতে পারে যেখানে আউটপুট অন্যান্য কাজের জন্য ব্যবহার করা যেতে পারে।


উদাহরণ স্বরূপ,

dateutils.ddiff 2016-12-26  2017-05-12 -f "%m month and %d days"
4 month and 16 days

dateutils.ddiff 2016-12-26  2017-05-12 -f "%d days"
137 days

দুর্দান্ত :) এই প্যাকেজটি সম্পর্কে জানতে পেরে ভাল।
জান্না


0

একটি সংক্ষিপ্ত সমাধান, যদি উভয় তারিখ একই বছরের হয় তবে তা হ'ল:

echo $((1$(date -d 2019-04-14 +%j) - 1$(date +%j)))

"% j" - ফর্ম্যাট ব্যবহার করে, যা বছরের বিভিন্ন দিনে তারিখের অবস্থান প্রত্যাবর্তন করে, বর্তমান তারিখের জন্য 135 5 এটি বৃত্তাকার সমস্যাগুলি এড়িয়ে যায় এবং অতীতে তারিখগুলি পরিচালনা করে, নেতিবাচক ফলাফল দেয়।

তবে বছরের সীমানা অতিক্রম করে, এটি ব্যর্থ হবে। আপনি প্রতি বছরের জন্য ম্যানুয়ালি 365 বা প্রতিটি লিপ বছরের জন্য 366 যোগ করতে পারেন (বা বিয়োগ), ফেব্রুয়ারির শেষটি পার হয়ে গেলে, তবে এটি অন্যান্য সমাধানগুলির মতো প্রায় ভার্জোজ হবে।

খাঁটি বাশ সমাধান এখানে:

#!/bin/bash
#
# Input sanitizing and asking for user input, if no date was given, is left as an exercise
# Suitable only for dates from 1.1.1970 to 31.12.9999
#
# Get date as parameter (in format yyyy-MM-dd
#
date2=$1
# for testing, more convenient:
# date2=2019-04-14
#
year2=${date2:0:4}
year1=$(date +%Y)
#
# difference in days, ignoring years:
# since %j may lead to values like 080..099, 
# which get interpreted as invalid octal numbers, 
# I prefix them with "1" each (leads to 1080..1099) 
daydiff=$((1$(date -d 1$date2 +%j)- $(date +%j)))
#
yeardiff=$((year2-year1))
# echo yeardiff $yeardiff
#
#
# summarize days per year, except for the last year:
#
daysPerYearFromTo () {
    year1=$1
    year2=$2
    days=0
    for y in $(seq $year1 $((year2-1)))
    do
        ((days+=$(date -d $y-12-31 +"%j")))
    done
    echo $days
}
# summarize days per year in the past, except for the last year:
#
daysPerYearReverse () {
    year1=$1
    year2=$2
    days=0
    for y in $(seq $((year1-1)) -1 $year2)
    do
        ((days+=$(date -d $y-12-31 +"%j")))
    done
    echo $days
}

case $yeardiff in
    0) echo $daydiff
        ;;
    # date in one of previous years:
    -[0-9]*) echo $((daydiff-$(daysPerYearReverse $year1 $year2)))
        ;;
    # date in one of future years:
    [0-9]*) echo $((daydiff+$(daysPerYearFromTo $year1 $year2)))
        ;;
esac

শেলচেক অনেকগুলি ডাবল কোটিংয়ের পরামর্শ দেয়, তবে 9999 বছরের বেশি দিনের জন্য আপনার আলাদা পদ্ধতির বিষয়টি বিবেচনা করা উচিত। অতীতের জন্য, এটি 1970.01.01 এর আগে তারিখগুলির জন্য নিঃশব্দে ব্যর্থ হবে। স্যানিটাইজিং ব্যবহারকারী ইনপুটটি ব্যবহারকারীর জন্য অনুশীলন হিসাবে রেখে দেওয়া হয়েছে।

দুটি ফাংশন একটিতে রিফ্যাক্টর করা যেতে পারে তবে এটি বুঝতে অসুবিধা হতে পারে।

দয়া করে মনে রাখবেন, অতীতে লিপ বছরগুলি সঠিকভাবে পরিচালনা করার জন্য স্ক্রিপ্টটির সম্পূর্ণ পরীক্ষার প্রয়োজন। আমি বাজি ধরব না এটা ঠিক।

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