LesezeichenAbonnierenRSS-Feed abonnieren
mfab
Quartz | Level 8

Hallo zusammen,

 

ich würde mich wieder über Feedback aus der Community freuen, da ich leider online dazu keine Hinweise finde.

 

Wie wird bei SAS die Breite (width) eines Datetime Feldes gehandhabt?

 

Folgender Hintergrund:

data test;
test = '01JAN2015:07:45:12'dt;

put test datetime18.;
put 18*'-' ' 18';
put test datetime19.;
put 19*'-' ' 19';
put test datetime20.;
put 20*'-' ' 20';
run;

Ergebnis:

  01JAN15:07:45:12
------------------ 18
 01JAN2015:07:45:12
------------------- 19
  01JAN2015:07:45:12
-------------------- 20

 

Das ist auch so bei SAS nachzulesen: Format Reference

 

Mich irritiert hierbei insbesondere, dass bei datetime18. nicht auch schon das Jahr vierstellig ausgeschrieben wird.

Für den vollen Datetime-Wert ohne Sekundenbruchteile sollten 18 Zeichen doch ausreichen?

Und wieso wird - zumindest bei der Ausgabe mit put-Statement - bei datetime18. ein Zeichen und bei datetime19. zwei Zeichen vor dem eigentlichen Wert frei gelassen?

 

Wahrscheinlich gibt es eine recht simple Erklärung, die ich nur gerade nicht finden kann.

 

Herzliche Grüße

Michael

4 ANTWORTEN 4
AndreasBachert
Calcite | Level 5

Hallo mfab,

 

deine Frage müsste eigentlich lauten:

  • Wie wendet SAS Formatierungen bei Datetime-Werten an?

Denn die Breite deines Datetime-Feldes, das den Namen 'test' und in der Tabelle 'test' zu finden ist, ist 8 Bytes.

 

Was dein Programm angeht, so nimmst du ja nur unterschiedliche Formatierungen des Datetime-Wertes vor.

Grundsätzlich gilt dabei, dass du durch die Zahl vor dem Punkt die Gesamtlänge des formatierten Wertes vorgibst und eine evtl. nach dem Punkt angegebene Zahl die Anzahl der Nachkommastellen festlegt.

Die Formatangabe datetime18. ist somit äquivalent zu datetime18.0.

 

Das datetime-Format ist ein Zahlenformat, denn es wird ja ein Zahlenwert formatiert. Wenn ein formatierter Zahlerwert weniger Zeichen benötigt, als du durch deine Gesamtlängenangabe bei der Formatierung mitgibst, werden die übrigen Zeichen als Lerrzeichen vorangestellt. Deshalb siehst du bei der Verwendung von datetime19. ein führendes Leerzeichen und bei der Verwendung von datetime20. eben zwei führende Leerzeichen. Denn für den auszugegebenen Wert werden ja nur 18 Zeichen benötigt.

 

Abschließende Hinweise:

  • Warum SAS bei datetime18. nicht die vierstellige Jahreszahl ausgibt, kann ich nicht sagen
    • Ich würde halt immer datimetime19. verwenden (und davon ggf. das führende Leerzeichen abschneiden)
  • Eine Formatangabe von dateime22.2 bedeutet
    • Gibt mir den Zeitstempel aus in einer Gesamtlänge von 22 Zeichen und zeigen nach den Sekunden noch 2 Stellen an, die die Bedeutung von 1/100 Sekunden haben
    • In den 22 Gesamtzeichen muss der Dezimaltrenner separat mitgezählt werden
    • Wir haben dann also 20 Zeichen zur Darstellung des Zeitstempelwertes bis zu den vollen Sekunden
    • Danach folgt ein Punkt als TRennzeichen vor den 1/100 Sekunden
    • Und dann folgenden die Zeichen 21 und 22 für die Anzeoige der 1/100 Sekunden
    • Man kann Datetime-Werte maximal mit 3 Nachkommastellen (für 1/1000 Sekunden) ausgeben, also dateime<x>.3
  • Bei der Verwendung von Character-Formaten werden überflüssige Zeichen als abschließende Leerzeichen an den formatierten Werte angehängt (und nicht vorangestellt wie bei formatierten Zahlenwerten)

Viele Grüße

Andreas

mfab
Quartz | Level 8

Hallo Andreas,

 

danke für Deine Hinweise.

 

Stimmt, da war ich wahrscheinlich nicht ganz klar in meiner Formulierung. (Kann ich das auf eine anstrengende Woche schieben und die Tatsache, dass heute Freitag ist? Smiley (zwinkernd) )

 

Tatsächlich hatte ich die Ausrichtung nicht bedacht und mit einer linksbündigen Ausrichtung gerechnet. Prima, das erklärt natürlich schonmal die führenden Leerzeichen.

 

Das Thema mit der vierstelligen Jahreszahl ist mir nach wie vor ein Rätsel.

Darauf gestoßen bin ich durch etwas abenteuerlichen Code, den ich entdeckt habe. Dort wurde mit verschiedenen put-/input-Funktionen und datetime18. hantiert. Durch die YEARCUTOFF-Option kam es dann leider zu falschen Ergebnissen.

 

Mit YEARCUTOFF = 1926 wird z.B. folgender Code ein Problem:

 

[...]
test_datum = '01JAN1915:07:45:12'dt;
test_string = put(test_datum, datetime18.);
test_ergebnis = input(test_string, datetime18.);
format test_ergebnis datetime20.;
[...]

 

Beim dritten Statement - dem Input - liest SAS eine zweistellige Jahreszahl "15" und interpretiert dies durch das YEARCUTOFF dann als "2015" statt als "1915". Das ist ja im Grunde die gewünschte Verarbeitungsweise. Nur weshalb wird im zweiten Statement die Jahreszahl mit zwei Ziffern geschrieben?!

 

Den Code habe ich zwischenzeitlich schon bereinigt, aber nach meinem Verständnis (und offensichtlich auch dem des vorherigen Programmierers) müssten doch 4 Jahres-Ziffern in einem 18-stelligen Datetime Platz finden - auch mit Trennzeichen.

Für ein führendes Minus muss bei einem Datetime ja kein Platz gelassen werden, da kleinere Daten als der 1. Januar 1582 nicht möglich sind. Habe ich etwas übersehen, wofür SAS ggf. noch Platz reserviert haben möchte?

(Jahre jenseits von "9999" werden mit "****" dargestellt, also wird wohl auch die Thematik mit mehr als 4-stelligen Jahreszahlen kaum relevant sein.)

 

Schönes Wochenende!

Michael

AndreasBachert
Calcite | Level 5

Hallo Michael,

 

wie gesagt, ich denke auch, dass das mit der nur 2-stelligen Jahreszahl bei datetime18. ein kleiner Bug ist.

Mich stört so etwas nicht weiter, da ich ja, wenn ich den formatierten Wert als Text ohne führende Leerzeichen in einer Dataset-Variablen weiterverwenden will, die führenden Leerzeichen ja entfernen kann.

Meine Variable test_string hat im Gegensatz zu der Variablen test_string aus deinem vorangegangenen Code-Beispiel eine 4-stellige Jahreszahl und keine führenden Leerzeichen. (Dafür hat sie aber 2 abschließende Leerzeichen, da ich ja mit dateime20. formatiert habe.)

 

Der Code ...

data test;
   test_datum = '01JAN1915:07:45:12'dt;
   test_string = strip (put(test_datum, datetime20.));
   test_ergebnis = input(test_string, datetime18.);
   format test_ergebnis datetime20.;
   put test_string=;
   put test_ergebnis=;
run;

 

... ergibt im Log die folgende Ausgabe:

test_string=01JAN1915:07:45:12
test_ergebnis=01JAN1915:07:45:12

 

Viele Grüße

Andreas

mfab
Quartz | Level 8

Hallo Andreas,

 

vielen Dank für Deine Erklärungen.

Ich arbeite nun schon einige Jahre mit SAS, daher ist mir das generelle Vorgehen schon klar und auch die Möglichkeiten der String-Verarbeitung sind mir bekannt.

 

Tatsächlich bin ich allerdings in all den Jahren nie auf die Thematik mit datetime18. gestoßen.

Für mich waren die logischen Schritte zunächst nach der Ursache des Problems zu schauen. Da dies sich offensichtlich auch hier in der Community niemandem bekannt ist, habe ich nun alle unsere Programme auf die Problematik hin untersucht und die Kollegen entsprechend informiert. Somit sollte das in Zukunft keine Probleme machen. Es verbleibt dennoch ein leicht ungutes Gefühl, da man sowas doch gerne definitiv geklärt haben möchte und die Ursache kennen will. (vielleicht starte ich nochmal einen Versuch in der globalen englischen Community)

Das mag an der Stelle auch einer gewissen Detailverliebtheit geschuldet sein ... Smiley (zwinkernd)

 

Herzlichen Dank nochmal für die Anregungen!

Michael

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

Diskussionsstatistiken
  • 4 Antworten
  • 11647 Aufrufe
  • 0 Kudos
  • 2 in Unterhaltung