יום שבת, 15 בספטמבר 2012

שנה טובה

שלום,

כמנהגנו לקראת ראש השנה גם בפוסט זה נעסוק בנושא התאריכים ב – SAS. הפעם נתחיל מההתחלה וננסה להסביר נושא זה אשר מעורר פחד ויראה בקרב לא מעט משתמשי SAS, גם המנוסים שבהם.

SAS מייצגת תאריך או נקודה כלשהי בזמן ע"י ערך נומרי כלשהו. ערך זה הוא מספר ככל מספר אחר. ההבדל היחיד בינו לבין "סתם" מספר הוא ההחלטה שלנו להתייחס לערך שלו כמייצג יחידת זמן. הבחירה היא אומנם שלנו אבל אם החלטנו להתייחס למספר מסוים כמייצג יחידת זמן כלשהי אז עלינו לזרום עם ההגדרות המובנות במערכת ה – SAS בנוגע לייצוג וטיפול בזמן.

מפתחי מערכת ה – SAS החליטו על שלוש דרכים לייצג נקודה בזמן – תאריך (date), שעה (time) ותאריך-שעה (datetime). תאריך מיוצג ע"י מספר הימים שעברו מה – 1/1/1960, זמן מיוצג ע"י מספר השניות שעברו מחצות הלילה ואילו תאריך-שעה מיוצג ע"י מספר השניות שעברו מה – 1/1/1960 בחצות הלילה. הטבלה הבאה מסכמת את הנושא:
סוג
יחידות
נקודת האפס
ערך לדוגמא
הזמן אותו הוא מייצג
תאריך
ימים
1/1/1960
19251
15/09/2012
שעה
שניות
00:00:00
74889
20:48:09
תאריך-שעה
שניות
1/1/1960:00:00:00
1663361341
15/09/2012 20:49:01

כמובן שאם אנחנו רוצים לכתוב בתוכנית ה – SAS שלנו תאריך מסוים לא נרוץ ללוח השנה ונתחיל לספור כמה ימים עברו מאז ה – 1/1/1960 ועד לתאריך אותו אנחנו רוצים להזין. SAS מאפשרת לנו לכתוב תאריך או שעה בצורה נוחה לבני אדם אבל כדי ש – SAS תצליח להבין לבד למה אנחנו מתכוונים אנחנו צריכים לכתוב אותו בצורה מסוימת:
סוג
פורמט כתיבה
לדוגמא
תאריך
"ddmmmyy"d
"15SEP2012"d (*), (**)
שעה
"hh:mm:ss"t
"21:12:54"t
תאריך-שעה
"ddmmmyy:hh:mm:ss"dt
"15SEP2012:21:12:54"dt
(*) מבחינת SAS אין הבדל בין אותיות גדולות לקטנות כך שגם "15sep2012"d יתקבל בברכה.
(**) במקרה של תאריכים אין הבדל בין מרכאות כפולות לבודדות ולכן גם '15sep2012'd הוא תקין לחלוטין.

כאמור, ההחלטה שערך מסוים מייצג יחידת זמן מסוימת היא שלנו בלבד. שום דבר לא מונע מאיתנו להחליט ש – 19251 מהטבלה שלמעלה דווקא מייצג שעה ביום ולא תאריך. במקרה שכזה מספר זה ייצג את השעה 05:20:51 (חמש, עשרים דקות וחמישים ואחת שניות לפנות בוקר).

שיטה זו לייצוג זמן במערכות ממוחשבות אינה ייחודית ל – SAS. לדוגמא, אקסל של חברת מיקרוסופט עושה שימוש באותו מנגנון לייצוג זמן.  ההבדל הוא שבאקסל נקודת האפס היא 1/1/1900 והשעה ביום מיוצגת ע"י שבר עשרוני.

SAS מאפשרת לנו גם להמיר בין שלושת דרכי ייצוג אלו בעזרת פונקציות ייעודיות:
מ -
ל -
נשתמש בפונקציה
לדוגמא
תאריך
תאריך-שעה
mydttm=dhms(mydt,0,0,0)
תאריך-שעה
תאריך
mydt=datepart(mydttm)
תאריך-שעה
שעה
mytm=timepart(mydttm)

מבחינת המחשב הכל פשוט מאוד. תאריכים הם מספרים ומחשבים טובים מאוד בעבודה עם מספרים. הבעיות נוצרות בחיבור שבין המחשב לבני האדם. מרבית האנשים יעדיפו לקבל 15/09/2012 על פני 19251 כתשובה לשאלה מה התאריך היום. למעשה, אנשים בארה"ב דווקא יעדיפו לקבל כתשובה 9/15/2012 ואילו אנשים ביפן יצפו ל - 2012/09/15.

בעיה נוספת נובעת מהמורכבות של לוח השנה עצמו. לדוגמא, אם יש לנו תאריך ביד ונרצה להוסיף לו שבוע פשוט נוסיף למספר המייצג את התאריך את הערך 7. אבל, מה אם נרצה להמיר את התאריך שלנו לאותו יום בחודש הקודם? מספר הימים שנצטרך להחסיר יכול להיות 31, 30, 29 או 28 תלוי בחודש ובשנה הספציפים.

כדי לפתור את הבעיה הראשונה SAS מכילה מגוון רחב מאוד של format-ים ו – informat-ים המאפשרים לנו להציג תאריך בצורה הנוחה ביותר. לכל אחד משלושת סוגי הייצוג של יחידות הזמן יש את ה – format-ים וה – informat-ים המתאימים לו.

הקטע הטריקי הוא שאנחנו בתור המשתמשים צריכים לוודא שבחרנו את ה – format המתאים ליחידת הזמן שלנו. כאמור, מבחינת SAS כל תאריך מכל סוג שהוא הוא רק מספר ואין לה שום דרך לדעת מה מספר זה מייצג בפועל. לדוגמא, אם החלטנו שהמספר 19251 מייצג תאריך אזי נציג אותו באחד מה – format-ים של התאריכים – למשל ddmmyy10. – ונקבל 15/09/2012. אנחנו יכולים באותה מידה להחליט שמספר זה מייצג שעה ביום ואם נפעיל עליו אחד מה – format-ים של שעה – למשל time. – נקבל 5:20:51:
data _null_;
      x=19251;
      put x ddmmyy10.;
      put x time.;
      put x datetime.;
run;

15/09/2012
 5:20:51
01JAN60:05:20:51
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


כדי לפתור את הבעיה השניה SAS מכילה גם מספר פונקציות שכל ייעודן הוא טיפול בתאריכים. שתי פונקציות שימושיות במיוחד הן intnx המשמשת להוספה או החסרה של יחידות זמן מתאריך ו – intck המאפשרת לחשב כמה יחידות זמן יש בין שני תאריכים. לפונקציות אלו מגוון רחב של פרמטרים ואפשרויות שימוש והטבלה הבאה מציגה רק מספר שימושים נפוצים. הקטע החשוב בפונקציות אלו הוא לבחור את יחידת הזמן המתאימה למה שאנחנו רוצים להשיג ולסוג התאריך שלנו (תאריך, שעה או תאריך-שעה).
מה רוצים לעשות
מה כותבים
מה מקבלים
להוסיף 15 ימים לתאריך
intnx('day', "15sep2012"d, 15)
"30sep2012"d
להוסיף 15 ימים לתאריך-שעה
intnx('dtday', "15sep2012:00:00:00"dt, 15) (*)
"30sep2012:00:00:00"dt
להוריד שבוע מתאריך
intnx('week', "15sep2012"d, -1)
"08sep2012"d
להוסיף 50 דקות לשעה
intnx('minute',"13:45:12"t, 50, 's')
"14:35"12"t
מה היום האחרון בחודש של תאריך
intnx('month', "15sep2012"d, 0, 'e')
"30sep2012"d
למצוא כמה ימים יש בין שני תאריכים
intck('day', "22aug2012"d, "15sep2012"d)
24
למצוא כמה שעות יש בין שני תאריך-שעה
intck('hour', "22aug2012:00:45:12"dt, "15sep2012:13:34:00"dt)
589
למצוא כמה רבעונים יש בין שני תאריך-שעה
intck('dtqtr', "22aug2012:00:45:12"dt, "15sep2010:13:34:00"dt) (*)
8- (**)
(*) שימו לב שאם מטפלים בתאריך-שעה יש להוסיף "dt" לפני יחידת הזמן ("dtday" או "dtqtr").
(**) קיבלנו ערך שלילי מכיוון שהתאריך-שעה הראשון הוא מאוחר יותר מתאריך-השעה השני.

מקווה שפוסט זה סייע מעט להסביר את נושא התאריכים ב – SAS ושנה טובה לכל בית ישראל מאנשי מיה מחשבים וממני.

חגי

אין תגובות:

הוסף רשומת תגובה