Skip to content

elisp: Live von der Front: Datum von "%Y-%m-%d" nach "%d.%m.%Y" (aka "YYYY-mm-dd" nach "dd.mm.YYYY") konvertieren

Federico Cervelli (ehemals zugeschrieben an Pietro Liberi): Diana und Kallisto

Hier mal das Beispiel einer typischen Emacs-Session: Im Rahmen des Beitrages "The Road to Titaneion 3" habe ich die genauen Zahlen der einzelnen Arbeitsschritte aus dem Log meines Git-Repositories rekonstruiert. So weit, so gut. Nur leider erhalte ich in der exportierten Liste ein falsches Datumformat.

Dieses ließe sich bestimmt auch direkt beim Exportieren der Log-Meldungen anpassen (ah ja: z. B. per --date=<format>). Ich nehme dafür aber - allein schon, weil man als Emacs-User, der was auf sich hält, alles mit Emacs erledigt - lieber Emacs:

Der Feind

Gegeben sei eine Liste

2018-03-06: 57191 Wörter
2018-03-05: 55747 Wörter
2018-03-04: 54561 Wörter
2018-02-28: 52054 Wörter
2018-02-27: 49403 Wörter
etc.

In dieser Liste soll das führende Datum im Format "YYYY-mm-dd" in das Format "dd.mm.YYYY" konvertiert werden. Die Liste sollte danach also so aussehen:

06.03.2018: 57191 Wörter
03.05.2018: 55747 Wörter
04.03.2018: 54561 Wörter
28.02.2018: 52054 Wörter
27.02.2018: 49403 Wörter
etc.

Seek ...

Da wir keine Ahnung haben, nach welchen Begriffen und Funktionen wir innerhalb der Emacs-Doku suchen sollen, googeln wir nach irgendwas a la "emacs format date" oder "emacs convert date format" ("emacs parse date" macht sich auch immer gut) und wenn wir damit nicht wirklich weiter kommen, packen wir noch ein "elisp" mit rein in unsere Suchbegriffe.

Schreiben einer Funktion

Nach mehr oder weniger langer Suche stoßen wir dann z. B. auf so was hier: emacs.stackexchange.com: Converting plain text to dates. Dort finden wir eine Funktion, die unserer Aufgabe schon ziemlich nahe kommt (vielen Dank, an dieser Stelle, Arthur!):

(defun my-format-time (time-string)
  (let* ((time (parse-time-string time-string))
         (day (nth 3 time))
         (month (nth 4 time))
         (year (nth 5 time)))
    (format-time-string "<%Y-%m-%d>" 
      ;; I would love to do an 'apply here, but the given list to be encoded contains nil which does n
      (encode-time 0 0 0 day month year))))

Umgeschrieben für unsere Zwecke ("2018-05-31" -> "31.05.2018") sieht die Funktion so aus (zusätzlich zum angepassten Datumsformat fügt unsere Version der Funktion das konvertierte Datum noch an der aktuellen Cursor-Position ein):

(defun my-format-time (time-string)
  (let* ((time (parse-time-string time-string))
         (day (nth 3 time))
         (month (nth 4 time))
         (year (nth 5 time)))
    (insert (format-time-string "%d.%m.%Y" 
                (encode-time 0 0 0 day month year)))))

Diese Funktion kopieren wir in den "*scratch*"-Buffer (Ctrl-x b *scratch*) und evaluieren den "*scratch*"-Buffer per M-x eval-buffer. Von nun an lässt sich die Funktion "my-format-time" in jedem Buffer unserer aktuellen Emacs-Sitzung aufrufen.

Testen der Funktion

Wir testen die Funktion natürlich erst einmal: Dazu wechseln wir in einen Test-Buffer (z. B. Ctrl-x b test) und führen unsere Funktion per M-: (my-format-time "2018-05-31") aus. An der aktuellen Cursor-Position sollte jetzt "31.05.2018" (ohne die ") eingefügt werden.

Verwendung als Makro

Wir wechseln anschließend in den Buffer mit unserer Liste, positionieren den Cursor irgendwo im ersten Datum (nicht am Anfang des Datums, da wir ansonsten Gefahr laufen, das Springen an den Zeilenanfang bei jeder neuen Zeile in unserem Makro zu vergessen) und führen die folgenden Schritte aus:

  • Wir starten den Makro-Rekorder per <F3>
  • Wir springen an den Zeilen-Anfang per Ctrl-a
  • Setzen eine Markier-Marke per Ctrl-<SPACE>
  • Markieren das vollständige Datum per M-3 M-f
  • Schneiden es aus per Ctrl-w
  • Beginnen den Aufruf unserer Funktion "my-format-time" per M-: (my-format-time " (WICHTIG: Jetzt nicht <ENTER> drücken!)
  • Fügen per Ctrl-y das ausgeschnittene Datum gefolgt von ") in unseren Funktionsaufruf ein (jetzt dürfen Sie <ENTER> drücken)
  • Hüpfen per Ctrl-n in die nächste Zeile
  • Beenden die Aufnahme des Tastatur-Makros per <F4>

... and destroy

Ab sofort können wir per <F4> jedes Datum am Zeilenanfang in das gewünschte Format konvertieren.

(Wer sich die Arbeit noch leichter möchten, kann das Makro z. B. per M-25 <F4> 25 mal ausführen.)

Mission accomplished!

Wichtig: Bitte achten Sie immer darauf, ob sich wirklich ein zu konvertierendes Datum am Zeilenanfang befindet. Das wird von dem Makro natürlich nicht geprüft. Ansonsten können Sie schnell mal Buchstaben- und Zahlen-Salat erhalten, ohne zu wissen, woher. Man kann sich mit so 'nem Makro nämlich auch ganz schnell ganz viel kaputt machen!

In diesem Sinne: Happy Hacking!

Bildnachweis: Federico Cervelli (ehemals zugeschrieben an Pietro Liberi): Diana und Kallisto (1670er Jahre)

Trackbacks

Keine Trackbacks

Kommentare

Ansicht der Kommentare: Linear | Verschachtelt

Noch keine Kommentare

Kommentar schreiben

Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.
Gravatar, Twitter, Pavatar, Identica, Favatar Autoren-Bilder werden unterstützt.
Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Markdown-Formatierung erlaubt
Formular-Optionen