Ein paar Worte vorabHome   Letzte MeldungenNews   Index der Kapitel und der besprochenen FunktionenIndex   Wer ich bin, warum ich diese Seiten mache, KontaktImpressum   Ich freue mich über jeden Eintrag im Gästebuch!Gästebuch   Einige Links zu anderen AutoLisp-SeitenLinks   Copyrights und DisclaimerRechts
Hier können die kompletten Seiten als ZIP-File heruntergeladen werden!

Funktionen für komfortables Arbeiten mit Zeichenketten String-Tango
Noch mehr Funktionen für komfortableres Arbeiten mit Zeichenketten Kettenhunde
strtok zerlegt Zeichenketten anhand eines Trennzeichens Tock-Tock
Arbeiten mit Datum und Zeit in AutoLisp Zeitlos...
Dotted pairs - wie man den Programmabbruch verhindert Gepunktet?
Neue Funktionen für die Listenbearbeitung Strukturtapete
Weitere neue Funktionen für die Listenbearbeitung Listen to me!
Lambda expressions - dasSalz in der Suppe Lambada
Lambda expressions anhand eines Praxisbeispiels Unter der Erde
Where und whereever erleichtern den Umgang mit Listen Quo vadis?
Rekursion - Funktionen, die sich selbst aufrufen Katzenschwanz
Ein äusserst wichtiger Prototyp für Funktionen Nix passiert
Wo das lineare mapcar am Ende ist Tiefer rein!
Über Effekte und Neben(Seiten-)Effekte von Funktionen Seitensprünge
Die Namensräume (Sichtbarkeit) von Variablen Raumwunder
Let dient zur Schaffung kleinerer Namensräume Lass mal...
Sukzessive Verarbeitung von Listenresten mit mapcdr Der Bruder
Was in AutoLisp einfach nicht machbar ist (Teil I) Beschränkt
Was in AutoLisp einfach nicht machbar ist (Teil II) Limited Edition
Nicht mit Effekten arbeiten, sondern direkter Daten-Änderung Destruktiv
Sequenzielles vs. paralleles Abarbeiten von Argumenten Parallelwelten
Über den Umgang mit Funktionsschablonen Erwachet!
Ein Praxiskapitel über Auswahlsätze, Attribute, wcmatch und mehr Durch die Brust
Die Farben des AutoCAD Color Index und ihre RGB-Werte Alles so schön
Hier laufen die Fäden zusammen: Viele Konzepte vereint Lapsus Lispuli
Ein Spiel als Beispiel für lernfähige Funktionen Zug um Zug
Errorhandling in AutoLisp - Teil 1 Alles valsch!
Errorhandling in AutoLisp - Teil 2 Und foll Feler!


Zum Einsteiger-Tutorial

Zu den ActiveX-Seiten

Meine Private HP mit Fotos, Gedichten, Musik und Postkartenversand

Mein Online-Lexikon der Fotografie

Mein völlig abgedrehtes Reisebüro










Wenig Komfort bietet AutoLisp, was den Umgang mit Datum und Zeit angeht - wobei wenig noch stark übertrieben ist: Es gibt nichts! Die Systemvariablen DATE und CDATE können ausgelesen werden, und das war's schon. Zum Handwerkszeug eines Programmierers gehören aber Funktionen, mit denen man beispielsweise
  • Datum und/oder Zeit als String ausgeben kann
  • Mit Datum und Zeit rechnen kann
  • steuern und messen kann, z.B. Pausen oder die Laufzeit von Programmen/Funktionen
  • Zufallszahlen erzeugen kann
Die ersten drei dieser Punkte werden in diesem Kapitel behandelt.

CDATE enthält das aktuelle Datum und die Zeit in einer Realzahl, in der Datum und Zeit durch das Komma getrennt vorliegen. In eine Zeichenkette umgewandelt, sieht das wie im folgenden Beispiel aus. Mit (substr ...) kann man sich die einzelnen Werte extrahieheren.
(rtos(getvar"cdate")2 6) => "20020129.205906"

(substr(getvar"cdate")2 6)1 4) => "2002" ; Jahr
(substr(getvar"cdate")2 6)5 2) => "01"   ; Monat usw.
                  
Wir benötigen also die folgenden Funktionen, um auf Datum und Zeit zugreifen zu können. Diese Funktionen greifen auf einige der in den Kapiteln über Zeichenkettenbearbeitung vorgestellten String-Funktionen zurück. Sollten Unklarheiten bestehen, bitte erst in diesen Kapiteln nachlesen. Die erste Funktion gibt das aktuelle Datum, die zweite die aktuelle Uhrzeit als formatierten String zurück. Über das Flag secs kann gesteuert werden, ob die Sekunden mit ausgegeben werden oder nicht:
(defun date-string( / cd)
  (setq cd(rtos(getvar"cdate")2 6))
  (strcat
    (str-lpadz(substr cd 7 2)2)
    "."
    (str-lpadz(substr cd 5 2)2)
    "."
    (substr cd 1 4)
  )
)

(date-string) => "29.01.2002"

(defun time-string(secs / cd)
  (setq cd(rtos(getvar"cdate")2 6))
  (if secs
    (strcat
      (str-lpadz(substr cd 10 2)2)
      ":"
      (str-lpadz(substr cd 12 2)2)
      ":"
      (str-lpadz(substr cd 14 2)2)
    )
    (strcat
      (str-lpadz(substr cd 10 2)2)
      ":"
      (str-lpadz(substr cd 12 2)2)
    )
  )
)

(time-string nil) = > "20:59"
(time-string  'T) = > "20:59:06"
                  
Die Kombination von beidem ist ganz einfach implementiert, das Flag wird einfach weitergegeben:
(defun timedate-string(secs / )
  (strcat (date-string) " "(time-string secs))
)

(timedate-string 'T) => "29.01.2002 20:59:06"
                  
Diese Funktionen sind schon mal ein Ansatz, um Datum und Zeit als Zeichenketten in eine Zeichnung oder Datei auszugeben.

Werfen wir nun einen Blick auf zwei Funktionen, die das aktuelle Datum bzw. die Uhrzeit als Liste in der Form (Jahr Monat Tag) bzw. (Stunden Minuten Sekunden) zurückgeben. Auf das Sekunden-Flag wird hier verzichtet:
(defun date-list( / cd)
  (setq cd(rtos(getvar"cdate")2 6))
  (append
    (list(atoi(substr cd 1 4)))
    (list(atoi(substr cd 5 2)))
    (list(atoi(substr cd 7 2)))
  )
)

(date-list) => (2002 1 29)

(defun time-list( / cd)
  (setq cd(rtos(getvar"cdate")2 6))
  (append
    (list(atoi(substr cd 10 2)))
    (list(atoi(substr cd 12 2)))
    (list(atoi(substr cd 14 2)))
  )
)

(time-list) => (20 59 6)
                  
Diese beiden Funktionen ermöglichen es uns, mit den Angaben als Zahlen zu rechnen oder z.B. eine Formatierung zu implementieren, bei der der Monat ausgeschrieben wird. Das könnte etwa so aussehen:
(defun date-xstring( / d)
  (setq d(date-list))
  (strcat
    (itoa(caddr d))
    ". "
    (nth(1-(cadr d))'("Januar"
                      "Februar"
                      "März"
                      "April"
                      "Mai"
                      "Juni"
                      "Juli"
                      "August"
                      "September"
                      "Oktober"
                      "November"
                      "Dezember"
                    )
    )
    " "
    (itoa(car d))
  )
)

(date-xstring) => "20. Januar 2002"
                  
Richtiges Rechnen mit diesen Listen ist natürlich ein bisschen ungewohnt, da die Stunde nun mal 60 Minuten hat. Es lässt sich aber leicht hinkriegen, indem man zuerst alles in Sekunden umrechnet und hinterher wieder eine Liste bildet.
(defun time-add(t1 t2 / r)
  (setq r
    (apply'+
      (mapcar
      '(lambda(tn / )
          (+(* 3600(car tn))
            (* 60(cadr tn))
            (caddr tn)
          )
        )
      (list t1 t2)
      )
    )
  )
  (list
    (/ r 3600)
    (/ (rem r 3600) 60)
    (rem r 60)
  )
)

(time-add '(9 50 42) '(4 14 31))
    => (15 5 13)
                  
Wenig Sinn macht eine Funktion, die grundsätzlich eine Subtraktion in bestimmter Reihenfolge vornimmt, da wir hier evtl. negative Zeiten erhalten würden. Die nachfolgende Funktion umgeht das Problem, indem immer eine (positive) Zeitdifferenz ausgegeben wird:
(defun time-diff(t1 t2 / r)
  (setq r
    (abs
      (apply'-
        (mapcar
        '(lambda(tn / )
            (+(* 3600(car tn))
              (* 60(cadr tn))
              (caddr tn)
            )
          )
        (list t1 t2)
        )
      )
    )
  )
  (list
    (/ r 3600)
    (/ (rem r 3600) 60)
    (rem r 60)
  )
)

(time-diff '(4 14 31) '(9 50 42) )
    => (5 36 11)
                  
Die Funktion (time-diff ...) lässt sich sehr schön verwenden, um das Laufzeitverhalten von Funktionen abzuschätzen. Da hier eine zusätzliche Aspekte bedacht werden müssen, habe ich dieser Angelegenheit ein eigenes Kapitel gewidmet.