Script ou fonction pour retourner le nombre de jours à partir de maintenant jusqu'à une date donnée

26

J'aimerais écrire un script ou une fonction pour me dire combien de jours à compter de maintenant jusqu'à une date donnée dans le futur. Ce que j'ai du mal à comprendre, c'est comment traiter la date donnée et la comparer à la date actuelle ... J'imagine quelque chose comme

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

Et puis je suppose que j'ai une chaîne qui n'a pas de sens pour le shell et je dois faire des évaluations comme ... ?? (Ceci est juste un exemple; je suppose que bc serait nécessaire)

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

Et puis je ne sais pas quoi faire avec ces chiffres ... ??

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

Je le fais sûrement trop dur pour moi-même; il existe probablement un outil de traitement de texte qui comprend les dates et peut les comparer.

Comment puis-je faire cela?

    
posée Zanna 07.12.2016 - 21:09
la source

6 réponses

27

époque de l'époque

En général, les calculs de temps sont plus faciles si nous convertissons d'abord le temps en (Unix) temps epoch (secondes de 1-1-1970). En python, nous disposons d’outils permettant de convertir l’heure en heure d’une époque, puis de revenir au format de date de notre choix.

Nous pouvons simplement définir un format, tel que:

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

... et définir aujourd'hui:

today = "2016-12-07"

et écrivez ensuite une fonction pour faire le travail:

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

Ensuite, la sortie de:

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

> 1481065200

... qui est, comme mentionné, le nombre de secondes depuis le 1-1-1970

Calculer le nombre de jours entre deux dates

Si nous faisons cela à la fois aujourd'hui et à l'avenir, calculons ensuite la différence:

#!/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))

La sortie sera calculée par date , car nous utilisons le format %Y-%m-%d . Arrondir sur secondes donnerait peut-être une différence de date incorrecte, si nous approchons de 24 heures par exemple.

Version du terminal

#!/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))

...Etl'optionZenity

#!/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)) ])

Etjustepourleplaisir...

Unepetiteapplication.Ajoutez-leàunraccourcisivousl'utilisezsouvent.

Lescript:

#!/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()
  • Copiez-le dans un fichier vide, enregistrez-le sous orangedays.py
  • Lancez-le:

    python3 /path/to/orangedays.py
    

Pour envelopper

À utiliser pour le petit script d'application situé au-dessus du fichier .desktop suivant:

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

  • Copiez le code dans un fichier vide, enregistrez-le sous orangedays.desktop dans ~/.local/share/applications
  • Dans la ligne

    Exec=/path/to/orangedays.py
    

    définir le chemin d'accès réel au script ...

réponse donnée Jacob Vlijm 07.12.2016 - 22:29
la source
21

L’utilitaire Utilitaire GNU date est assez performant chose. Il est capable d’analyser une grande variété de formats de date, puis de le sortir dans un autre format. Ici, nous utilisons %s pour afficher le nombre de secondes depuis l'époque. C’est alors une simple question d’arithmétique que de soustraire $now au $future et de le diviser par 86400 secondes / jour:

#!/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"
    
réponse donnée Digital Trauma 08.12.2016 - 01:39
la source
10

Voici une version Ruby

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!"

Exemple d'exécution:

Un exemple d'exécution du script ruby ./day-difference.rb est donné ci-dessous (en supposant que vous l'avez enregistré sous day-difference.rb )

Avec une date future

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

Avec une date passée

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

Une fois la date du jour passée

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

Voici un site Web intéressant pour vérifier les différences de date link

    
réponse donnée Anwar 08.12.2016 - 16:17
la source
9

Vous pouvez essayer de faire quelque chose dans awk , en utilisant la fonction mktime

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

L'awk s'attend à lire la date à partir de l'entrée standard au format "AAAA MM JJ HH MM SS", puis imprime la différence entre l'heure spécifiée et l'heure actuelle en jours.

mktime convertit simplement une heure (au format spécifié) en nombre de secondes à partir d'une heure de référence (1970-01-01 00:00:00 UTC); systime simple spécifie l'heure actuelle dans le même format. Soustrayez les uns des autres et vous obtenez leur distance en quelques secondes. Divisez par 86400 (24 * 60 * 60) pour convertir en jours.

    
réponse donnée Nick Sillito 07.12.2016 - 21:51
la source
4

Il existe un package dateutils qui est très pratique pour traiter les dates. En savoir plus sur ce sujet ici github: dateutils

Installez-le par

sudo apt install dateutils

Pour votre problème, simplement,

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

où la sortie peut être choisie en secondes, minutes, heures, jours, semaines, mois ou années. Il peut être facilement utilisé dans des scripts où la sortie peut être utilisée pour d'autres tâches.

Par exemple,

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
    
réponse donnée ankit7540 26.12.2016 - 08:19
la source
3

Vous pouvez utiliser la bibliothèque Velour awk :

.
$ velour -n 'print t_secday(t_utc(2018, 7, 1) - t_now())'
7.16478

Ou:

$ velour -n 'print t_secday(t_utc(ARGV[1], ARGV[2], ARGV[3]) - t_now())' 2018 7 1
7.16477
    
réponse donnée Steven Penny 26.12.2016 - 07:45
la source

Lire d'autres questions sur les étiquettes