Datumsberechnung

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Datumsberechnung

Beitrag von roli » 28.04.2006 11:08:16

Hi,

mal wieder ein Problem @work, und damit eigentlich Solaris 5.8.
Ich bin es satt Datumsberechnungen von Hand am Wandkalender durchzuführen. Ich muss oft von einem gegebenen Datum eine bestimmte Anzahl Tage (immer nur ganze Tage) abziehen. Also z.B. welchen Tag hatten wir "Heute vor 90 Tagen". Zu hause wurde ich den Date befehl dazu nutzen, wie z.B.:

Code: Alles auswählen

date -d '1 month ago'
(Ich weiss die Beispiele passen nicht zusammen) Hier auf Solaris geht's nicht :cry: , der kennt kein "-d".

Ich bin also fuer alles zu haben (primaer Shell und/oder Perl) was ich mit Bordmitteln nutzen kann, nachinstallieren ist nicht!
Was groesseres zu Programmieren kann ich auch, ich suche aber nach einer "eleganten Loesung".

Was ich bisher habe waere:

Code: Alles auswählen

TZ=$TZ+(24*$anz_tage)
/usr/bin/date +%m%d%Y
Das ich das 24*$anz_tage noch vorher auswerten muss ist mir auch klar, der Code ist nur dazu da um das Vorgehen zu verdeutlichen.
Hat jemand was "besseres auf der Pfanne?
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
seep
Beiträge: 544
Registriert: 31.10.2004 14:21:08
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: HSK

Re: Datumsberechnung

Beitrag von seep » 28.04.2006 12:39:14

roli hat geschrieben:Was groesseres zu Programmieren kann ich auch, ich suche aber nach einer "eleganten Loesung".
Vor demselben Problem stand ich seinerzeit auch. Dummerweise gibt es unter sunfreeware.com kein fertiges Package. Also ist selbermachen angesagt. Ich habe mir die Sourcen gezogen und GNU date selber gebaut, ging seinerzeit völlig problemlos unter Solaris.

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 28.04.2006 12:59:06

Hi seep,

wie ich aber initial geschrieben habe "nachinstallieren ist nicht".
Ich bin hier was das angeht hoechstens "Hilfsheriff", auf die Disskussion darueberlasse ich mich hier nicht (mehr) ein. Wenn ich Stunden/Tage dafuer braeuchte waer's immer noch schneller und stressfreier, als nachinstallieren. Aber auch darueber brauchen wir nicht diskutieren, ich bin hier nur auf Zeit.
Ich dachte halt, hier waere wer, der mal eben irgedetwas aus dem Hut zaubert, das ich nicht kenne/an das ich nicht gedacht habe, das aber viel eleganter ist als mein Weg ueber das "verbiegen" von TZ, der aber im uebrigen funktioniert.
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

Benutzeravatar
Joghurt
Beiträge: 5244
Registriert: 30.01.2003 15:27:31
Wohnort: Hamburg
Kontaktdaten:

Beitrag von Joghurt » 28.04.2006 13:38:28

Falls Python installiert ist:

Code: Alles auswählen

#!/usr/bin/python
import sys,datetime
print (datetime.date.today()+datetime.timedelta(int(sys.argv[1]))).ctime()
Als Parameter die gewuenschte Differenz in Tagen angeben. z.B. -1 fuer gestern

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 28.04.2006 13:49:16

Mahlzeit Joghurt,

Python gibt's hier nicht.
Ausserdem ist mir eben aufgefallen das meine Loesung nur mit "Basis" heute funktioniert. Ich wollte temporaer mit date das Datum auf die dem Script uebergebene Basis setzten, dann die TZ entsprechend verbiegen, jetzt date erneut aufrufen und viola das Ergebnis steht auf'm Schirm.
Soweit die Theorie, leider kann ich das Datum nicht "mal eben" anpassen, also schon wieder mit Zitronen gehandelt, Mist.
Da ich aber in 15 Minuten in's Wochenende starte habe ich ja noch was Zeit mir eine Loesung zu ueberlegen :wink:
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 28.04.2006 14:03:19

Leicht Verständliches Beispiel wie man es in Perl machen könnte:

Code: Alles auswählen

#!/usr/bin/perl
my $timeback=int(shift(@ARGV));
my $format=lc(shift(@ARGV));

if($format eq 'd')
{
 $timeback*=24;
 $timeback*=60;
 $timeback*=60;
}
elsif($format eq 'h')
{
 $timeback*=60;
 $timeback*=60;
}
elsif($format eq 'm')
{
 $timeback*=60;
}
elsif($format ne 's')
{
 print <<EOF;
 USAGE: $0 <time> d|h|m|s
 Return a date in the past.
EOF
exit();
}
print localtime(time()-$timeback)."\n";

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

Beitrag von roli » 02.05.2006 11:37:34

Hi ToPeG,

danke fuer die Loesung.
Stunden und Minuten brauche ich nicht, es geht definitiv immer nur um ganze Tage, aber der Ansatz ist schon mal gut.
Hier kann ich allerdings auch "nur" aber heute rechnen, und nicht mit einem beliebigen Datum als Basis, soweit bin ich mit meiner Loesung ja auch.

Trotzdem vielen Dank
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 02.05.2006 12:31:48

roli hat geschrieben: Hier kann ich allerdings auch "nur" aber heute rechnen, und nicht mit einem beliebigen Datum als Basis, soweit bin ich mit meiner Loesung ja auch.
Hier kannst du auch eine Basis angeben:

Code: Alles auswählen

use POSIX qw(strftime);
use Time::Local;

my $daydiff=int(defined $ARGV[0] ? $ARGV[0] : 0);
my $basedate = time();

if (defined $ARGV[1]) {
  my @basedatein = split(/-/,$ARGV[1]) ;
  push @basedatein, qw( 0 0 0 0 0 0 );
  $basedate = timelocal(int($basedatein[5]),int($basedatein[4]),int($basedatein[3]),int($basedatein[2]),int($basedatein[1])-1,int($basedatein[0]))
}
printf "%s %s %s = %s\n",
   strftime ("%Y-%m-%d", localtime $basedate),
   $daydiff>0 ? "+" : "-",
   $daydiff > 0 ? $daydiff : -$daydiff,
   strftime("%Y-%m-%d ", localtime $basedate+$daydiff*24*60*60);
Als ersten Parameter die gewünschte Differenz, als zweiten optionalen Parameter ein Basisdatum:

Code: Alles auswählen

root@csxgen4:~# perl x.pl -90
2006-05-02 - 90 = 2006-02-01
root@csxgen4:~# perl x.pl -90 2006-02-01
2006-02-01 - 90 = 2005-11-03
root@csxgen4:~# perl x.pl -180
2006-05-02 - 180 = 2005-11-03
Gruß
gms

[edit]
den Code für das Einlesen des Basisdatums finde ich auch nicht sehr elegant :)
Vielleicht hat da jemand eine bessere Idee
[/edit]

roli
Beiträge: 3174
Registriert: 10.09.2003 17:39:58

[Geloest] Datumsberechnung

Beitrag von roli » 02.05.2006 13:20:38

Hi gms,

wenn's das debianforum nicht geben wuerde, ich wuerd's glatt "erfinden", danke.

"Nu geit dat" :lol:
Roland


"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 02.05.2006 13:52:05

@gms
Ich hätte es wohl so geschrieben:

Code: Alles auswählen

#!/usr/bin/perl
use POSIX qw(strftime);
use Time::Local;

my $daydiff=$ARGV[0];
my $basedate = time();

if ($ARGV[1]=~m|(\d{4})-(\d{1,2})-(\d{1,2})|)
{ $basedate = timelocal(0,0,0,int($3),int($2)-1,int($1)); }

if($daydiff =~ /^[+-]?\d+$/)
{
 my $time=int($basedate)+$daydiff*24*60*60;
 print strftime('%Y %m %d',localtime($time))."\n";
}
else
{ print "USAGE: $0 <daydiff> [<Year>-<Month>-<Day>]\n"; }
 exit();
Dein Parster des "basedate" ist zwar Univreseller, aber meiner ist Kürzer und leichter auf Richtigkeit zu prüfen. :-)

EDIT:
Habe, wie gms es Vorschug, die IF-Abfrage zu "$daydiff" geändert :-)
Zuletzt geändert von ToPeG am 02.05.2006 14:21:57, insgesamt 1-mal geändert.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 02.05.2006 14:11:46

@ToPeG
Aja, dein Vorschlag zum Einlesen des Basisdatums gefällt mir auch besser
nur diese Abfrage gefällt mir nicht:

Code: Alles auswählen

if($daydiff ne "" && $daydiff!~m|\d{4}-\d{1,2}-\d{1,2}|)
würde ich in

Code: Alles auswählen

if($daydiff =~ /^[+-]?\d+$/)
ändern

Gruß
gms

ToPeG
Beiträge: 437
Registriert: 14.04.2004 00:42:06

Beitrag von ToPeG » 02.05.2006 14:19:21

Stimmt wäre besser so. Man sollte nicht überall "copy&paste" nutzen. ;-)

Antworten