The Essential Guide to SAS® Dates and...
Transcript of The Essential Guide to SAS® Dates and...
TheEssentialGuidetoSAS®DatesandTimesSecond
Edition
DerekP.Morgan
support.sas.com/bookstore
Thecorrectbibliographiccitationforthismanualisasfollows:Morgan,DerekP.2014.TheEssentialGuidetoSAS®DatesandTimes,SecondEdition.Cary,NC:SASInstituteInc.
TheEssentialGuidetoSAS®DatesandTimes,SecondEdition
Copyright©2014,SASInstituteInc.,Cary,NC,USA
ISBN978-1-62959-066-0
(Hardcopy)ISBN978-1-62959-489-7(EPUB)ISBN978-1-62959-490-3(MOBI)ISBN978-1-62959-491-0(PDF)
Allrightsreserved.ProducedintheUnitedStatesofAmerica.
Forahard-copybook:Nopartofthispublicationmaybereproduced,storedinaretrievalsystem,ortransmitted,inanyformorbyanymeans,electronic,mechanical,
photocopying,orotherwise,withoutthepriorwrittenpermissionofthepublisher,SASInstituteInc.
Forawebdownloadore-book:Youruseofthispublicationshallbegovernedbythetermsestablishedbythevendoratthetimeyouacquirethispublication.
Thescanning,uploading,anddistributionofthisbookviatheInternetoranyothermeanswithoutthepermissionofthe
publisherisillegalandpunishablebylaw.Pleasepurchaseonlyauthorizedelectroniceditionsanddonotparticipateinorencourageelectronicpiracyofcopyrightedmaterials.Yoursupportofothers’rightsisappreciated.
U.S.GovernmentLicenseRights;RestrictedRights:TheSoftwareanditsdocumentationiscommercialcomputersoftwaredevelopedatprivateexpenseandisprovidedwithRESTRICTEDRIGHTStothe
UnitedStatesGovernment.Use,duplicationordisclosureoftheSoftwarebytheUnitedStatesGovernmentissubjecttothelicensetermsofthisAgreementpursuantto,asapplicable,FAR12.212,DFAR227.7202-1(a),DFAR227.7202-3(a)andDFAR227.7202-4and,totheextentrequiredunderU.S.federallaw,theminimumrestrictedrightsassetoutinFAR52.227-19(DEC2007).IfFAR52.227-19isapplicable,thisprovisionservesasnoticeunderclause(c)thereofandnoothernotice
isrequiredtobeaffixedtotheSoftwareordocumentation.TheGovernment'srightsinSoftwareanddocumentationshallbeonlythosesetforthinthisAgreement.
SASInstituteInc.,SASCampusDrive,Cary,NorthCarolina27513-2414.
December2014
SASprovidesacompleteselectionofbooksandelectronicproductstohelp
customersuseSAS®softwaretoitsfullestpotential.Formoreinformationaboutourofferings,visitsas.com/store/booksorcall1-800-727-0025.
SAS®andallotherSASInstituteInc.productorservicenamesareregisteredtrademarksortrademarksofSASInstituteInc.intheUSAandothercountries.®indicatesUSAregistration.
Otherbrandandproductnames
aretrademarksoftheirrespectivecompanies.
Contents
AboutThisBookAcknowledgmentsChapter1:Introductionto
DatesandTimesinSAS1.1HowDoesItWork?(January1,1960,andMidnightasZero)1.2InternalRepresentation1.3ExternalRepresentation(BasicFORMATConcepts)1.4DateandTimeas
NumericConstantsinSAS1.5LengthandNumericRequirementsforDate,Time,andDatetime1.6GeneralSASOptionsforDates
Chapter2:DisplayingSASDate,Time,andDatetimeValuesas
DatesandTimesasWeKnowThem2.1HowDoIUseaFormat?2.2HowManyBuilt-InFormatsAreThereforDatesandTimes?2.3DateFormats,Justification,andODS2.4DetailedDiscussionofEachFormat
2.4.1DateFormats2.4.2TimeFormats2.4.3DatetimeFormats
2.5CreatingCustomDateFormatsUsingtheVALUEStatementofPROCFORMAT2.6CreatingCustomDateFormatsUsingthePICTUREStatementofPROCFORMAT
2.7CreatingCustomFormatsUsingPROCFCMPforProcessing2.8ThePUT()FunctionandFormats
Chapter3:ConvertingDatesandTimesintoSASDate,Time,andDatetimeValues
3.1AvoidingtheTwo-DigitYearTrap3.2UsingInformats3.3TheINFORMATStatement3.3.1UsingInformatswiththeINPUTStatement3.3.2InformatswiththeINPUT()Function3.3.3WhentheInformatDoesNot
MatchtheDataBeingRead
3.4ListingandDiscussionofInformats3.4.1DateInformats3.4.2TimeInformats3.4.3DatetimeInformats3.4.4The"ANYDATE"SeriesofInformats3.4.5SoWhyNotJustUsethe"ANYDATE"
SeriesofInformats?
Chapter4:ISO8601Dates,Times,Datetimes,Durations,andFunctions4.1WhatIsISO8601?4.2ISO8601Formats4.2.1ISODateFormats
4.2.2ISOTimeFormats4.2.3ISODatetimeFormats
4.3ISO8601Informats4.3.1ISODateInformats4.3.2ISOTimeInformats4.3.3ISODatetimeInformats
4.4TimeZoneFunctions
4.4.1Introduction4.4.2TheTIMEZONE=Option4.4.3ListofTimeZoneFunctions
4.5ISO8601DurationsandIntervals4.5.1ISODurationandIntervalRepresentations4.5.2ISO8601DurationandInterval
Formats4.5.3ISO8601DurationandIntervalInformats4.5.4CALLIS8601_CONVERT
4.6Conclusion
Chapter5:DateandTimeFunctions
5.1CurrentDateandTimeFunctions5.2ExtractingPiecesfromSASDate,Time,andDatetimeValues5.3CreatingDates,Times,andDatetimesfromNumbersorOtherInformation5.3.1Introduction5.3.2ListofFunctionsandTheirDescriptions
5.4CalculatingElapsedTime,andtheHOLIDAY()Function5.4.1CalculatingElapsedTimewithDATDIF()andYRDIF()
5.5TheBasicsofSASIntervals5.5.1TheIntervalCalculationFunctions:INTCK()andINTNX()
5.6ModifyingSAS
Intervals5.7CreatingYourOwnSASIntervals5.8IntervalFunctionsaboutIntervals5.8.1INTFIT(argument-1,argument-2,type)5.8.2INTFMT('interval','size')5.8.3INTGET(argument1,argument2,argument3)
5.8.4INTSHIFT('interval')5.8.5INTTEST('interval')
5.9RetailCalendarIntervalsandSeasonality5.9.1RetailCalendarIntervals5.9.2SeasonalityFunctions
Chapter6Deeper
intoDatesandTimeswithSAS6.1MacroVariablesandDates6.1.1AutomaticMacroVariables6.1.2PuttingDatesintoTitles6.1.3Using%SYSFUNC()toCreateDates,Times,and
DatetimesinMacroVariables6.1.4UsingDatesinMacros
6.2GraphingDatesJohnny'sSavingsAccount
6.3TheBasicsofPROCEXPAND6.3.1CapabilitiesofPROCEXPAND6.3.2UsingPROC
EXPANDtoConverttoaHigherFrequency6.3.3UsingPROCEXPANDtoConverttoaLowerFrequency6.3.4UsingPROCEXPANDtoInterpolateMissingValues6.3.5TheOBSERVED=OptionfortheCONVERTStatementinPROC
EXPAND6.4InternationalDate,Time,andDatetimeFormatsandInformats6.4.1"EUR"FormatsandInformats6.4.2NLSFormats
6.5NLSDate,Time,andDatetimeConversionFunctions6.6DateFormatsandInformatsforOther
Calendars6.6.1HebrewDateFormats6.6.2JapaneseandTaiwaneseDateFormats6.6.3JapaneseandTaiwaneseDateInformats
6.7OtherSoftwareandTheirDates(Excel,Oracle,DB2)
6.7.1TheSASDATEFMT=SystemOption
6.8Conclusion
AppendixA:AQuickReferenceGuidetoSASDate,Time,andDatetimeFormatsAppendixB:A
QuickReferenceGuidetoNLSDate,Time,andDatetimeFormatsAppendixC:TroubleshootingDates101Index
AboutThisBook
PurposeThisbookisdesignedtoprovideadetailedlookathowtheSASdatefacilityworks,includinganin-depthlookatintervalsand
theintervalfunctions,ISO8601dateanddatetimehandling,andtheNLSformatsandinformats.Itisintendedtoserveasbothareferenceandateachingtool.Ultimately,thisbookwillallowthereadertobecomemoreconfidentintheirdailyworkwithdates,times,and
datetimesinSAS.
IsThisBookforYou?ThisbookisaimedatbeginningtointermediateSASprogrammers,orthosewhoworkwithISO8601data,intervals,and/orreportingin
multiplelanguages.
What’sNewinThisEditionThisneweditionincludesupdatedinformationtoreflectthechangesinversion9ofSAS;anexpandeddiscussionofintervals,includingtheabilityto
defineyourownintervals;asectiononhowSASworkswiththeISO8601datestandards;andatroubleshootingappendixforbeginners.
ScopeofThisBookThisbookdoesnotcovertheSAS/ETSproduct,exceptforan
overviewoftheEXPANDprocedure.
AbouttheExamplesSoftwareUsedtoDeveloptheBook'sContentSASversion9.4(TSlevel1M0)wasusedto
producealltheexamplesinthisbook.
ExampleCodeandDataManyoftheexamplesusedinthisbookhaveaccompanyingcodeanddata.
Youcanaccesstheexamplecodeanddata
forthisbookbylinkingtoitsauthorpageathttp://support.sas.com/publishing/authorsSelectthenameoftheauthor.Then,lookforthecoverthumbnailofthisbook,andselectExampleCodeandDatatodisplaytheSASprogramsthatareincludedinthisbook.
Foranalphabetical
listingofallbooksforwhichexamplecodeanddataisavailable,seehttp://support.sas.com/bookcodeSelectatitletodisplaythebook’sexamplecode.
Ifyouareunabletoaccessthecodethroughthewebsite,sende-mailto
OutputandGraphicsUsedinThisBookTablesinthisbookweregeneratedusingODSRTF,whilegraphicsweregeneratedasPNGfilesdirectlyinSASusingtheGPLOTand
SGPLOTprocedures.ScreencaptureswereusedtoshowtheVIEWTABLEdisplays.
AdditionalHelpAlthoughthisbookillustratesmanyanalysesregularlyperformedinbusinessesacrossindustries,questions
specifictoyouraimsandissuesmayarise.Tofullysupportyou,SASInstituteandSASPressofferyouthefollowinghelpresources:
•Forquestionsabouttopicscoveredinthisbook,contacttheauthorthrough
SASPress:◦Sendquestionsbyemailtosaspress@sas.comincludethebooktitleinyourcorrespondence.
◦Submitfeedbackontheauthor’spageathttp://support.sas.com/author_feedback
•Forquestionsabouttopicsinorbeyondthescopeofthisbook,postqueriestotherelevantSASSupportCommunitiesathttps://communities.sas.com/welcome•SASInstitutemaintainsacomprehensivewebsitewithup-to-
dateinformation.OnepagethatisparticularlyusefultoboththenoviceandtheseasonedSASuserisitsKnowledgeBase.Searchforrelevantnotesinthe“SamplesandSASNotes”sectionoftheKnowledgeBaseat
http://support.sas.com/resources•RegisteredSASusersortheirorganizationscanaccessSASCustomerSupportathttp://support.sas.comHereyoucanposespecificquestionstoSASCustomerSupport;underSupport,click
SubmitaProblem.Youwillneedtoprovideanemailaddresstowhichrepliescanbesent,identifyyourorganization,andprovideacustomersitenumberorlicenseinformation.ThisinformationcanbefoundinyourSAS
logs.
MeettheAuthor
DerekMorganisaseniorSASprogrammer
inthepharmaceuticalindustrywhohasbeenprogrammingprofessionallyinSASforover27years.Hespent23ofthoseyearsatWashingtonUniversityinSt.Louis,wherehereceivedanA.B.inbiologyin1985andhisfirstintroductiontoSASasastudent.Duringhis
careerhehasusedSAStocreateinteractivedataentryandmanagementsystemsandtobuildandmaintainresearchdatabasesforanalysis.Inthelate1980s,hecreatedamacrolibrarytoallowtheuseofnonproportionalfontsintablesandlistingsonPostScriptprinters.He
hastaughtintroductorySASprogrammingandhaspresentedmanypapersatlocal,regional,andnationalSASUsersGroupconferences.Derekismarriedandhasoneson,andinhissparetimeheplayselectricbassaroundtheSt.Louisarea.
Learnmoreaboutthisauthorbyvisitinghisauthorpageathttp://support.sas.com/publishing/authors/morgan.htmlThereyoucandownloadfreebookexcerpts,accessexamplecodeanddata,readthelatestreviews,getupdates,andmore.
KeepinTouch
Welookforwardtohearingfromyou.Weinvitequestions,comments,andconcerns.Ifyouwanttocontactusaboutaspecificbook,pleaseincludethebooktitleinyourcorrespondence.
Contactthe
AuthorthroughSASPress•Bye-mail:[email protected]
•ViatheWeb:http://support.sas.com/author_feedback
PurchaseSASBooksForacompletelistofbooksavailable
throughSAS,visitsas.com/store/books.
•Phone:1-800-727-0025
•E-mail:[email protected]
SubscribetotheSASTrainingandBookReportReceiveup-to-date
informationaboutSAStraining,certification,andpublicationsviaemailbysubscribingtotheSASTraining&BookReportmonthlyeNewsletter.Readthearchivesandsubscribetodayathttp://support.sas.com/community/newsletters/training
Publishwith
SASSASisrecruitingauthors!Areyouinterestedinwritingabook?Visithttp://support.sas.com/saspressformoreinformation.
Acknowledgments
Abookisalwaysateameffort,andIcanhonestlysaythatIhavehadagreatone.StartingwiththepeopleatSASPresswhoseeffortsandpatienceonmybehalfhaveresultedinthis
secondedition,IwouldliketothankJuliePlatt,ShelleySessoms,andStaceyHamiltonbutmostespeciallymydevelopmentaleditor,StephenieJoyner,whokeptmeontaskandmovingforward.SASguruArtCarpenterhasbeenmorethanjustaneditor;hehasbeenamentor,andeverytime
Irunintohim,IfindmyselfknowinghowtodosomethingbetterthanIdidbefore.Thissecondeditionwouldnotexistwithouthissupport.AnotherbigthankyougoestoDeniseT.Jones,StacySuggs,andRobertHarris,allfromSASPress,whoareresponsiblefor
producingthisbookfrommymanuscript.
ThankstoAndrewKarpforintroducingmetotheworldofPROCEXPAND,andtoMikeFornoofSASInstituteforansweringmyquestionsonit.IgreatlyappreciatetheAmericanPublicTransportation
Association(http://www.apta.com),whichallowedmetousedatacompiledfromitsmembertransitagenciesforthePROCEXPANDexamples.ThetechnicalsupportgroupatSASInstitutedeservesspecialmention;after27yearsofworkingasacomputerprogrammer,
Ihavecometotheconclusionthatyouare,withoutadoubt,thebestinthebusiness.ThankyouforallofyourhelpthroughoutmySAScareer.
I’dalsoliketothankthetechnicalreviewersfromSASInstitute—RichardBell,ChrisDeHart,Johnny
Johnson,RickLangston,andKimWilson—fortheirthoughtfulcommentsandcorrections.Inaddition,PaulRowlanddeservesabigthankyouforhiswillingnesstoprovideaSASuser’sperspective.
Ultimately,thisprojectwouldnothavebeen
possiblewithoutthesupportofmyfamily,pastandpresent.Tomyson,Terec,thankyouforunderstandingmydistractionduringFormulaIseason,andthankyouforthephoto.Tomywife,Billie,thankyouforlettingmeworkonourweekendsandagoodnumberofour
evenings,andforcontributingyourknowledgeofMicrosoftWordtohelpmewritethemanuscript.
Chapter1:IntroductiontoDatesandTimesinSAS
1.1HowDoesItWork?(January1,1960,and
MidnightasZero)1.2InternalRepresentation1.3ExternalRepresentation(BasicFORMATConcepts)1.4DateandTimeasNumeric
ConstantsinSAS1.5LengthandNumericRequirementsforDate,Time,andDatetime1.6GeneralSASOptionsforDates
IntheyearsthatI've
beenworkingwithSASandteachingstudentshowtouseit,IfindthattwothingsconsistentlyconfusethosewhoarenewtoSAS.FirstisthedefaultwaythattheDATAstepworks.ItsimpliedDO-until-end-of-datageneratesmany"HowdoItellithowmuchdatatoreadandwhen
tostop?"questions.ThesecondmostconfusingconceptinSASisthatofhowdates(andtimes)workwithinthesoftware.I'veseenmanymisusesofcharacterstringsmasqueradingasdatesand/ortimesovertheyears,aswellasunexpectedresultsduetoafailureto
understandthisfundamentalpartofSAS.
However,thewaythatSASreads,stores,anddisplaysdatesandtimesisonlythetipoftheicebergwhenitcomestothepowerandflexibilityofSASinhandlingthisinformation.Thereisso
muchmorethanjusthavingnumbersrepresentdateandtimevalues.We'llstartwiththebasicsinthefirstthreechapters,andthenprogresstosomemoreadvancedusesofthosedateandtimevalues,takingadvantageofmanyofthefeaturesavailableinSASforthatpurpose.
1.1HowDoesItWork?(January1,1960,andMidnightasZero)SAScountsdates,times,anddatetimevaluesseparately.ThedatecounterstartedatzeroonJanuary1,1960.AnydaybeforeJanuary1,1960,isa
negativenumber,andanydayafterthatisapositivenumber.Everydayatmidnight,thedatecounterisincreasedbyone.Thetimecounterismeasuredinsecondsandrunsfromzero(atmidnight)to86,400(thenumberofsecondsinaday),whenitresetstozero.SAS
calculatesdatetimesasthenumberofsecondssincemidnight,January1,1960.WhyJanuary1,1960?ThefoundersofSASwantedtousetheapproximatebirthdateoftheIBM370systemtorepresentthebeginningofthemoderncomputingera,andtheychoseJanuary1,1960,asaneasy-to-
rememberapproximation.
Indecidingwhethertouseadate,atime,oradatetime,youshouldconsiderhowyouaregoingtouseit.Datetimesarealwaysdateandtimecombined;therefore,ifyouwillnotalwayshaveatimeavailable
foreachdate,youshouldstronglyconsiderusingseparatedateandtimevariablesandthencalculateadatetimevariablefromthetwocomponentswhenneeded.Normally,attemptingtocreateadatetimewithoutbothadateandatimewillcauseanerror,andtheresult
willbeamissingvalueforthedatetime.However,inspecificcircumstances,itispossibletocreateadatetimevaluefromadateandamissingtime(seeSection4.3.3,"ISODatetimeInformats,"foranexample).Inthesecases,thetimewillbesetautomaticallyto
midnight(0secondsofthegivendate).Youmaywantyourdatetimevaluetobemissingwhenthereisadatebutnotimeavailable.Inthesespecificcircumstances,itisimportanttokeeptrackofdateandtimeseparately.Manyprogramsthathandledates(suchas
databasesandspreadsheets)maintaintheirdatesandtimesasanumericvaluerelativetosomefixedpointintime,althoughthedatethatrepresentszeroisdifferentacrosseachpackage,andpackagesmayvaryinhowtheykeeptrackoftimeofday.Ultimately,thismakescalculating
durationseasy,andworkingwithdatesandtimesstoredinthisfashionbecomesamatterofaddition,subtraction,multiplication,anddivision.
1.2InternalRepresentation
SASstoresdatesasintegers,whilethedatetimeandtimecountersarestoredasrealnumberstoaccountforfractionalseconds.TheoriginofthealgorithmusedforSASdateprocessingcomesfromaJanuary14,1980,ComputerworldarticlebyDr.BhairavJoshiof
SUNY-Geneseo.TheearliestdatethatSAScanhandlewiththisalgorithmisJanuary1,1582(essentiallytheimplementationdateofthecurrentGregoriancalendarsystem).Thelatestdateisfarenoughintothefuturethatatleastfivedigitswillberequiredtodisplaytheyear.
DatesasstoredbySASdon'tdousmuchgoodintherealworld.Thestatement"Iwasbornon-242"won'tmeanmuchtoanyoneelse.However,"IwasbornonMay4,1959,"caneasilybetranslatedintosomethingthatmostpeoplecanunderstand,oritcanbeusedasis.Fortunately,
SAShasanumberofbuilt-infacilitiestoperformautomatictranslationbetweentheinternalnumbersstoredinSASanddatesandtimesandtheirrepresentationasunderstoodbytherestoftheworld.Thesebuilt-intoolsincludeformatsandinformats(introducedinSection
1.3andcoveredextensivelyinChapters2,3,and4),dateandtimeconstants(Section1.4),andfunctions(Chapter5).
1.3ExternalRepresentation(BasicFORMAT
Concepts)Formatsperformanautomatictranslationbetweentheactualvalueandthevaluetobedisplayed.Formatsdisplaythedate,time,anddatetimevaluesinafashionthatismuchmoreeasilyunderstood.Formatsdonotchangethevalues
themselves;theyarejustawaytodisplaythevaluesinanyoutput.
WhenyouhavedatesortimesandwanttotranslatethemintoSASdateandtimevalues,youwilluseinformats.Althoughyouwillneedastatement,procedure,orafunctionto
actuallycreatetheSASvalues,informatsdescribewhatthedatalooklikesothatSAScantranslateitcorrectlyforstorage.WewilldiscussformatsandinformatsindetailinChapters2,3,and4becausetherearedozensofthem.Threeofthemostcommonlyusedformatsthatwork
withSASdate,time,anddatetimevaluesareusedinthefollowingsection.
1.4DateandTimeasNumericConstantsinSASWe'vetalkedaboutinternalandexternal
representationofdatesandtimes.Howdoyouputaspecificdateintoaprogramasaconstant?Formatsonlychangethewaythevaluesaredisplayedinoutput,soyoucan'tusethem.InformatsneedafunctionoraSASstatementtotranslatethecharacterstheyaregiven,soyoucoulduse
them,butthenyouwouldalwaysneedtousetheINPUT()functiontocreateaSASdateinaDATAsteporPROCSQL.TheINPUTfunctiontakesaseriesofcharactersthatyougiveitandtranslatesitusingtheinformatthatdescribeswhattheseriesofcharacterslooklike.
That'sveryinefficientifyoujustwantonespecificdate.
date=INPUT("04AUG2013",DATE9.);
LookattheprograminExample1.1toseehowdate,time,anddatetimeconstantsarewrittenintoaSASprogram.Takenoteof
thequotationmarksaroundthevaluesfordate,time,anddatetimeandthelettersthatfolloweachclosingquote.
Example1.1:DateConstants
DATAdate_constants;
date='04aug2013'd;/*Thisisadateconstant*/
time='07:15:00't;/*Thisisatimeconstant*/datetime='07aug1904:21:31:00'dt;/*Thisisadatetimeconstant*/RUN;
TITLE"UnformattedConstants";PROCPRINTDATA=date_constants;VARdatetimedatetime;RUN;
TITLE"FormattedConstants";PROCPRINTDATA=date_constants;VARdatetimedatetime;FORMATdateworddate32.timetimeampm9.datetimedatetime19.;/*Formattheconstants*/RUN;
Thequotesareusedtocreatealiteralvalue.Youmayuseapairofsingleordoublequotes
tospecifytheliteralvalue.Dateshavetobewrittenasddmonyyyy;timesashh:mm:ss(addadecimalpointandmoredigitstorepresentfractionalsecondsifnecessary);anddatetimesasthedateddmonyyyy,followedbyaseparator(frequentlyseenasacolon[:])andthenthe
time(hh:mm:ss).Asidefromthecorrectformattingoftheseliteralvalues,themostimportantpartofadate/time/datetimeconstantistheletterthatimmediatelyfollowsthelastquote.Theletter"D"standsfordate,"T"fortime,and"DT"fordatetime.Upperorlowercaseis
valid.Ifyouputoneofthesestringsinquoteswithouttheletterattheend,youwillcreateacharactervariable,notanumericvariablewithadate,time,ordatetimevalue.Thedifferencemightnotbecomeapparentuntilyoutrytodosomethingwiththevariableyoucreated
thatinvolvesacalculation.Don'tforgetyour"D,""T,"or"DT"!ThisexampledemonstrateshowtheseconstantsaredefinedandthenautomaticallyconvertedtotheirequivalentSASvalues.
ThefirstPROCPRINTstatementdisplaysthe
date,time,anddatetimevalueswecreatedwithourconstantswithoutformats,sowecanseethevaluesastheyarestoredinthedataset.
UnformattedConstants
date time datetime
19574 26100 -1748226540
ThesecondPROCPRINTshowstheeffectofassociatingthevariableDATEwiththeWORDDATE.format,thevariableTIMEwiththeTIMEAMPM.format,andthevariableDATETIMEwiththeDATETIME.format.
FormattedConstants
date time datetime
August4,2013
7:15AM
07AUG1904:21:31:00
Withouttheformats,youcanseethatthedateconstantsweusedtocreatethevaluesstoredinthedataset
aredisplayedastheiractualSASdate,time,anddatetimevalues.Theydon'tmakemuchsensetousuntilaformatisassociatedwiththevariable.
Whathappensifyouforgettoputthe"D,""T,"or"DT"afteryourdateconstant?InExample1.2,the"D,"
"T,"and"DT"havebeenremovedfromthesamedate,time,anddatetimeinExample1.1.
Example1.2:IncorrectDateConstants
DATAbad_date_constants;
date='04aug2013';/*ThisisNOTadateconstant*/time='07:15:00';/*
ThisisNOTatimeconstant*/datetime='07aug1904:21:31:00';/*ThisisNOTadatetimeconstant*/RUN;
TITLE"UnformattedConstants";PROCPRINTDATA=bad_date_constants;VARdatetimedatetime;RUN;
Nowweprintoutthevalueswithoutformats.Whiletheproblemmaynotbeapparentatfirstglance,thisresultdoesnotlookliketheunformattedSASdate,time,anddatetimevaluesinthepreviousexample.
Unformattedconstants
date time
04aug2013 07:15:00
Nowlet'strytoaddonedaytothedate,andaminute(60seconds)toboththetimeanddatetime.HereisapartiallogofwhathappenswhenwetrythiswiththecodeinExample1.2.
12DATAbad_date_constants;13date='04aug2013'+1;14time='07:15:00'+60;15datetime='07aug1904:21:31:00'+60;16RUN;
NOTE:Charactervalueshavebeenconvertedtonumericvaluesattheplacesgivenby:(Line):(Column).
13:814:815:12NOTE:Invalidnumericdata,'04aug2013',atline13column8.NOTE:Invalidnumericdata,'07:15:00',atline14column8.NOTE:Invalidnumericdata,'07aug1904:21:31:00',atline15column12.
❶date=.time=.datetime=._ERROR_=1_N_=1
The"invalidnumericdata"noteinthelogtellsyouthatyoutriedtouseacharactervaluetodosomethingthatrequiresanumericvalue.Theboldfacelastlinetellsyouthatyouhavemissingvaluesforallthreevariables,becauseyouweretryingtodomathwithacharactervalue.
RememberthatSASdates,times,anddatetimesarealwaysstoredasnumbers.Whenyousee"invalidnumericdata"whereyouintendedtouseadateconstant,itishighlyprobablethatyourdateconstantismissingitsidentifying"D,""T,"or"DT."
1.5LengthandNumericRequirementsforDate,Time,andDatetimeYoucantakeadvantageofthefactthatdatesarestoredasintegerstosavespacewhenyoucreatevariablestostorethem.Insteadofusing
thedefaultlengthof8fornumericvariables,setthelengthofthenumericvariableswhereyouarestoringdatesto4.ThiswillsafelystoredatesfromJanuary1,1582(theearliestdateSAScanhandle),toOctober23,7701.Alengthof5isoverkill,althoughthatwouldextendthe
endingdateanother534,773,760days!Alengthof3willnotaccuratelystoredatesoutsidetherangeofJanuary1,1960,andSeptember13,1960.Ifyoudeclareyourdatevariablestobealengthof4,youwillbeabletostoretwodatesinthespaceitwouldtaketostoreoneifyouwere
usingtheSASdefaultlengthfornumericvariables.Thiscansaveyouagreatdealofstoragespaceinalargedatawarehouse.
Timesmaypresentabitofaproblem,becauseyoumayneedtostorefractionalseconds.Theruleissimpleenough:Ifyou
wanttostoretimevalueswithfractionalseconds,youmustusealengthof8tostorethemaccurately.Otherwise,thelengthof4islongenoughtostoreeverypossibletimevaluefrommidnighttomidnightdowntothesecond.Inthesecases,notusingthedefaultlengthwill
allowyoutostoretwotimesinthesameamountofspaceasone.
Datetimevaluesrequiremorespace,becausealengthof4willnotstoreadatetimevaluewithaccuracy,regardlessofwhetheryouwantfractionalseconds.Thenumberis
justtoobig.Aslongasyouarenotstoringfractionalseconds,alengthof6willstoredatetimesthataccuratelyrepresentvaluesfrommidnightonJanuary1,1582,to3:04:31p.m.onApril9,6315.Changingtherangefromthedefaultof8to6fordatetimevaluesresultsina25
percentsavingsinspace,whichstillmaybesignificantdependingonhowmuchdatayouhave.Ofcourse,ifyouaregoingtomaintaindecimalplacesinyourdatetimevalues,youmustusethedefaultlengthof8.
Ihavejustprovidedthe
absoluteminimumlengthsrequiredforaccuracy.DONOTattempttosaveadditionalspacebyshrinkingthevariablelengthsbeyond4,6,or8aslisted.Youwillloseprecision,whichcouldleadtounexpectedresults.Example1.3showswhatcanhappenifyou
donotuseenoughbytestostoreyourdatevalues.Thisexampleusesthevalue19941,whichrepresentsthedateofAugust6,2014,anditisinvariablesoflengths3,4,and5.
Example1.3:TheEffectofLENGTHStatementsonDates
DATAdate_length;
LENGTHlen33len44len55;len3=19941;len4=19941;len5=19941;FORMATlen3len4len5mmddyy10.;RUN;
Asthetablebelowshows,whenyoutrytostoreadateinfewerthan4bytes,youdonotgetthecorrect
value.Usingalengthof4tostoreyourdatesandtimes(withoutfractionalseconds)isstillasignificant(50percent)savingsintheamountofstoragerequired.Youwillcreateinaccuraciesinyourdataifyoutrytosavemorethanthat.Savingadditionalspaceisnotworththeriskof
inaccuratedata.
len3 len4
08/05/2014 08/06/2014
1.6GeneralSASOptionsforDatesTwooptionsinfluencethedefaultdateand
timestampthatSASplacesonpagesofoutputandtheSASlog.TheDATE/NODATEoptioncausesthestartdateandtimeoftheSASjob(orsession)toappearoneachpageoftheSASlogandSASoutput.Thesevaluesareobtainedfromtheoperatingsystemclockandaredisplayedas
24-hourclocktime,followedbythedayoftheweek,month,day,andfour-digityear.IfyouarerunningSASinteractively,thenthedateandtimeareprintedonlyontheoutput,notthelog.Bydefault,theDATEsystemoptionisineffectwhenyoustartSAS.However,ifyou
donotwantthisdefaultdisplay,thenusetheNODATEoption.Youprobablydon'twantSAStodisplayitsdefaultdatestampifyouaregoingtoputyourowndateand/ortimestampinthetitleorinafootnote(seeChapter6).
Asmentionedinthepreviousparagraph,iftheDATEoptionisenabled,SASprintsthedateandtimethatthecurrentSASsessionstartedoneachpage.Ifyouwantamoreexactdateandtimeonthosepages,youcanusetheDTRESETsystemoption,whichwillcauseSAStoretrieve
thedateandtimefromtheoperatingsystemclockeachtimeapageiswritten.ThatdateandtimewillthenbeplacedonthepageinsteadofthetimethattheSASjobstarted.Sincethetimeisdisplayedinhoursandminutes,youwillonlyseeitchangeeveryminute.TheDTRESET
optioncanbeusefulininteractiveapplicationsorSASprogramsthatmayhavebeenrunningfordaysorweeks,whereknowingwhentheoutputwasgeneratedismoreimportantthanknowingwhentheSASsessionbegan.SincetheDTRESEToptionaffectsthedefaultSAS
dateandtimestamp,itworksonlyiftheDATEoptionisenabled.WhenyouusetheNODATEoption,usingDTRESETwillhavenoeffectbecauseyouaren'tusingtheSASdateandtimestamponyouroutput.
Chapter2:DisplayingSASDate,Time,andDatetimeValuesasDatesand
TimesasWeKnowThem
2.1HowDoIUseaFormat?2.2HowManyBuilt-InFormatsAreThereforDates
andTimes?2.3DateFormats,Justification,andODS2.4DetailedDiscussionofEachFormat2.5CreatingCustomDate
FormatsUsingtheVALUEStatementofPROCFORMAT2.6CreatingCustomDateFormatsUsingthePICTUREStatementofPROCFORMAT
2.7CreatingCustomFormatsUsingPROCFCMPforProcessing2.8ThePUT()FunctionandFormats
InSAS,date,time,anddatetimevaluesare
storedasintegers(unlessyouarestoringfractionalpartsofseconds).Theyareallcountedfromafixedreferencepoint.SASdatevaluesincrementby1atmidnightofeachday,whileSASdatetimevaluesincrementby1everysecond.SAStimevaluesstartatzeroat
midnightofeachday,andalsoincrementby1eachsecond.
Thisschememakesiteasytocalculatedurationsindaysandseconds,butitdoesnotdomuchforfiguringoutwhatagivenSASdate,time,ordatetimevaluemeansintermsofhowwetalkabout
them.Therefore,SASprovidesafacilitythatmakesiteasytoperformthetranslationfromSASintothecommonterminologyofmonths,days,years,hours,andseconds.Thetranslationisdonethroughformats.
FormatsarewhatSASusestocontroltheway
datavaluesaredisplayed.Theycanalsobeusedtogroupdatavaluestogetherforanalysis.TheyareessentialtodatesandtimesinSASbecauseSASdoesnotstoredatesandtimesinaneasilyrecognizableform,aswediscussedinChapter1.SAShasmanybuilt-informats
todisplaydates,times,anddatetimevalues.Thischapterprovidesadetailedguidetoallofthedate,time,anddatetimeformatsreadilyavailableinSAS.Inaddition,ifanyofthesebuilt-informatsdon'tfityourneeds,youhavetheabilitytocreate(andstoreforfutureuse)
yourownformats.CreatingyourownformatsiscoveredinSections2.5and2.6.
Ifyouarelookingforaquickreference,youcangotoAppendixA,whichlistsallofthedate,time,anddatetimeformatsandprovidesasampledisplayusingtheir
defaultlengths.Ifthedefaultdoesnotgiveyouwhatyouwant,Section2.4discusseseachdate,time,anddatetimeformatindetail,includinghowtospecifythelengthoftheformatandhowthatlengthaffectsthedisplay.
2.1HowDoIUseaFormat?Formatsareeasytouse.YoucanpermanentlyassociateaformatwithavariablebyusingaFORMATstatementinaDATAstep,asshowninExample2.1.
Example2.1:Permanently
AssociatingaFormatwithaVariable
DATAtest;LENGTHdate1time14;date1=19781;time1=73000;FORMATdate1MMDDYY10.time1TIMEAMPM11.;RUN;
Example2.1createsadatasetcalledTEST,whichhastwovariables:date1and
time1.ByusingtheFORMATstatementhere,youhavespecifiedthatwheneverthevaluesfromthisdatasetaredisplayed,thevaluesstoredinthevariabledate1willalwaysbedisplayedwiththeformatMMDDYY10.,andthosestoredintime1willalwaysbe
displayedusingtheTIMEAMPM11.format.
date1 time1
02/27/20148:16:40PM
Ifyoudon'twanttohaveyourdatavaluespermanentlyassociatedwithaformat,thenyou
canjustapplytheformatwhenyouareactuallywritingthevaluestoyouroutput.ThesameFORMATstatementisused,butthelocationhaschanged,fromtheDATAsteptothePROCstep.Example2.2illustratesthis.
Example2.2:Associatinga
FormatwithaVariablefortheDurationofaProcedure
DATAtest2;LENGTHdate2time24;date2=19781;time2=73000;RUN;
PROCPRINTDATA=test2;FORMATdate2DATE9.time2TIMEAMPM11.;RUN;
date2 time2
02/27/20148:16:40PM
Althoughthereisnoformatassignedtoeitherdate2ortime2intheDATAstep,youhavetoldthePRINTproceduretowritethesevaluesusingthe
twoformatslisted,sothereisnodifferencebetweentheoutputfromExample2.1andthatfromExample2.2.AnotherhandythingaboutusingtheFORMATstatementwithaSASprocedureisthatifyouusetheFORMATstatementinaSASprocedure,itwilloverrideanyformat
thathasbeenpermanentlyassociatedwiththevariablesforthedurationofthatprocedure.Toillustrate,we'lltakethedatasetTESTfromExample2.1.Thevariablesdate1andtime1havebeenassociatedwiththeformatsMMDDYY10.andTIMEAMPM11.,
respectively.Whatifyourreportneedsthedateprintedoutwiththedayoftheweek,alongwiththenameofthemonth,day,andyear,whilethetimeneedstobesecondsaftermidnight?ThePROCPRINTstepwilllooklikethis:
PROCPRINTDATA=test;
FORMATdate1WEEKDATE37.time1;RUN;
date1 time1
Thursday,February27,2014 73000
AllSASprocedureswillusetheformatsspecifiedinthe
FORMATstatementthatispartofthePROCstepinsteadoftheformatsassociatedwiththevariableinthedataset.Therefore,intheaboveexample,date1isprintedusingtheWEEKDATE.format.Whatabouttime1?There'snoformatnamegivenafterthevariablenameintheFORMAT
statement.ThisishowtotellSASnottouseanyformatsthatmightbeassociatedwiththevariable.ToremoveaFORMATfromavariable,makesurethatnoformatnamesofanykindfollowitanywhereintheFORMATstatement.
Example2.3:Removing
AssociatedFormatsinaProcedure
DATAtest3;date3=19067;time3=18479;date4=18833;time4=45187;FORMATdate3date4DATE9.time3time4TIME5.;RUN;
PROCPRINTDATA=test3NOOBS;FORMATdate3date4time3time4;RUN;
Datasettest3withallformatsremoved
date3 time3 date4
19067 18479 18833
Whathappensifthereareformatnamesaftertheonethatyouwanttoremove?Lookatthecodesegmentthatfollowsthisparagraph.
Thegoalistodisplaythevariabledate3withtheMMDDYY10.format,removetheformatfromthevariabledate4,andapplytheTIMEAMPM11.formattothetimevariablestime3andtime4.SotheFORMATstatementhasMMDDYY10.fordate3,nothingfor
date4,andTIMEAMPM11.fortime3andtime4,right?
PROCPRINTDATA=test3NOOBS;FORMATdate3MMDDYY10.date4time3time4TIMEAMPM11.;RUN;
date3 time3
5:07:59
3/15/2012 AM
Whathappened?Thevariabledate4isdisplayedasatime,whenyoudidn'tputaformatnameafterthevariablenameintheFORMATstatement.TheansweristhatyougavealistofthreevariablestoSASand
toldittoapplytheTIMEAMPM11.formattothem(seeboldfacecodebelow):
FORMATdate3MMDDYY10.date4time3time4TIMEAMPM11.;
Howdoyoufixthis?Youhavetomakesurethatdate4isthelastvariablelistedinthe
FORMATstatement.
PROCPRINTDATA=test3NOOBS;FORMATdate3MMDDYY10.time3time4TIMEAMPM11.date4;RUN;
date3 time3
3/15/20125:07:59AM
2.2HowManyBuilt-InFormatsAreThereforDatesandTimes?SAShasmorethan70ready-to-useformatstodisplaydates,times,anddatetimes.WewilldiscusseachoneindetailinSection2.4,butifyou'relookingfor
aquickreferenceguide,seeAppendixA.SAScontinuestodevelopformatsandinformats,soitisalwaysagoodideatocheckthedocumentationthatcamewithyourreleaseofSAS,ortheonlinedocumentationatsupport.sas.com.AllSASformatshavea
commonsyntaxstructure,beginningwiththeformatname,followedbyanoptionalwidthspecification,andendingwithaperiod.Theperiodiscritical.ItiswhatallowsSAStorecognizethewordasaformatandnotsomeotherSASkeywordortext.Thewidthspecification
varieswitheachformat,andallformatshaveadefaultwidththatisusedifthereisnowidthspecificationgiven.ThewidthspecificationisveryimportanttodatesbecauseSASwillabbreviatethedisplayedvalueifyoudonotspecifyenoughcharactersforthe
width,andtheabbreviationthatSASusesmightnotgiveyoutheoutputthatyouwant.ThedefaultwidthisnotedinthedescriptionforeachformatinSection2.4,anditisusuallythewidththatwillaccommodatethelongestvaluetobedisplayed.Forexample,
thedefaultwidthfortheDOWNAME.(day-of-week)formatis9.Thatwillaccommodatethestring“Wednesday”,whichisthelongestEnglishday-of-weekname.
2.3DateFormats,Justification,and
ODSEachdateformathasadefaultjustificationwithrespecttothewidthspecificationthatyougiveit.Sincenumericvaluesareright-justifiedinSAS,mostoftheformatsthatareappliedtodate,time,ordatetimeformatsarealsoright-
justified,withafewexceptions(whichwillbeclearlynotedinthedetailedexplanationsthatfollow).InODSdestinationsotherthanLISTING,valuesarejustifiedwithinatablecolumnbySASproceduredefaultorbyauser-definedODStemplate.Bydefault,SASmakesitscolumns
wideenoughtofitthewidestiteminagivencolumn.Therefore,anyleadingspacescausedbyspecifyingawidththatistoowidetofittheformattedvaluewon'tshowupinODSoutput.
However,priortoODSorversion9.3intheLISTINGdestination,
usingawidthspecificationthatiswiderthantheoutputrequirescausesSAStofilltheemptyspaceswithblanks.Forvaluesthatareright-justified,thismightcausesomeoftheoutputtoshifttotherightbyanumberofspaces.InExample2.4,weusetheMONNAME.format,
whichdisplaysthetextcorrespondingtothemonthofthedate,toillustrate.
Example2.4:HowJustificationWorksintheLISTINGDestination
FormatName Result
MONNAME9. September
MONNAME10. September
MONNAME11. September
MONNAME15. September
Asyoucansee,making
thewidthspecificationlargeronlyaddsleadingspaces,andyoucouldextendthisallthewaytothemaximumwidthfortheformat.
WhyshouldIworryaboutjustification?I'mnotusing
ODSLISTING,andI'musingSAS9.3orhigher.
WhileitistruethatjustificationismoreofaconcerninthetraditionalLISTINGdestinationandonlyapplicable
totraditionalcolumn-basedoutput,leadingspacescanshowupifyouusethePUT()(orPUTN())functiontocreatecharacterstringsfromSASdate,time,ordatetimevalues.Incasessuchasthese,the
leadingspacesarepartoftheoutputandassuchmightbedisplayed.YoucanuseSTRIP()orCOMPRESS()toremovetheleadingspacesexplicitly.Ifyouaregoingtoconcatenatemultipleitems,
usetheCATX(),CATS(),orCATT()functions,allofwhichremoveleadingandtrailingspacesofeachitembeingconcatenated.
Ifyoudonotspecifycolumnalignmentinan
ODStemplateorbyusingSTYLE=directives,certainODSdestinations(suchasRTFandPDF)willjustifyvalueswithinacolumnaccordingtothejustificationoftheformatusedinthecolumn,withoutleadingspaces.
2.4DetailedDiscussionofEachFormatThissectiongivesadetailedexplanationofallthecurrentstandardformatsavailableforSASdate,time,anddatetimevalues.Inadditiontothedisplaythatresultsfromusing
agivenformat,theexplanationincludesinformationaboutthedefaultwidthspecificationanditspossiblevalues,annotatedexamplesofthedisplaywithvaryingwidthspecifications,andusagenotes.Dateformatswillbecoveredfirst,thentimeand
datetimeformats.Eachsubsectionisarrangedalphabetically.
2.4.1DateFormatsAdateformatprovidesasetofinstructionsforhowaSASdateisdisplayedsothatitlookslikeadateinthewaywenormally
expressthem.Youcanspecifythewidth(numberofcharacters)thatthetranslatedtextwilloccupy,buteachformathasitsowndefaultwidthspecification,shownaswinthistext.Thedefaultwidthspecificationisgiveninthedescriptionofeachformat.Some,butnot
all,ofthedateformatsallowyoutospecifythecharacterthatseparateseachelementofthedate.Youmustnotuseadateformattotranslatedatetimevalues.Ifyoutrytotranslateadatetimevaluewithadateformat,youwillgetincorrectoutput.(Foranexample,see
Example2.5.)
DATEw.DATEw.writesdatesasthenumericaldayofthemonthfollowedbythethree-lettermonthabbreviationandtheyear,withoutanyseparatingcharacters.Itisright-justifiedwithinthefield.wcan
befrom5to11,andthedefaultwidthis7.Ifyouwanttodisplayfour-digityears,useDATE9.orDATE11.DATE11.willdisplayfour-digityearswithahyphenbetweentheday,monthabbreviation,andyear.Thefollowingtableshowstheresultwhenthedatevalueis
19715,whichcorrespondstoDecember23,2013.
FormatName Result
DATE. 23DEC13
DATE5. 23DEC
DATE7. 23DEC13
DATE9. 23DEC2013
DATE11. 23-DEC-
2013
ThisformatisanalogoustotheDTDATE.format,whichdisplaysdatetimevaluesinthesamemanner.
DAYw.
DAYw.writesthenumericaldayofthemonth,anditisright-justifiedwithinthefield.wcanbefrom2to32,andthedefaultwidthis2.Specifyinganythinglongerthan2willonlyplacemorespacesinthefieldtotheleftofthenumber,soitisnotnecessarytospecifymorethan2.
Thefollowingtableshowstheresultwhenthedatevalueis16739,whichcorrespondstoOctober30,2005.
FormatName Result Comment
DAY2. 30
DDMMYYw.
DDMMYYw.writesdatesasday/numericalmonth/year,wheretheslash(/)istheseparator,anditisright-justifiedwithinthefield.wcanbefrom2to10,andthedefaultwidthis8.Ifyouspecifyawidthfrom2to5,thedatewillbe
truncatedontheright,asSAStriestofitasmuchofthedayandmonthaspossibleinthespaceallowed.Ifyouuse6,noslasheswillbeprinted.Awidthof8willuseatwo-digityearaftertheslashes.Use10togetafour-digityearwithslashes.Thefollowingtableshowstheresult
whenthedatevalueis19869,whichcorrespondstoMay26,2014.
FormatName Result
DDMMYY5. 26/05
DDMMYY6. 260514
DDMMYY8. 26/05/14
DDMMYY10. 26/05/2014
DDMMYYxw.
DDMMYYxw.issimilartotheDDMMYY.format.Itisalsoright-justified.However,withthisformat,youcanspecifywhatcharacterseparatestheday,numericalmonth,
andyear.Thexintheformatnamerepresentstheseparatorbetweentheday,month,andyear.Thefollowingtablelistswhatxcanbe.
x
CharacterDisplayedinOutput Comment
B blank
C colon(:)
D dash(-)
N noseparator
wisamaximumof8,not10.
P period(.)
S slash(/) EffectivelythesameasusingtheDDMMYY.format.
wcanbefrom2to10,withthedefaultbeing
8.ThisworksthesamewayastheDDMMYY.formatwithrespecttowhatSASfitsinthespacespecified.Again,ifyouspecifyawidthfrom2to5,thedatewillbetruncatedontheright,asSAStriestofitasmuchofthedayandmonthaspossibleinthespaceallowed.Ifyouuse6,
noseparatorwillbeused.At8,SASwillprintatwo-digityear.Use10togetafour-digityearwithyourseparator.Thefollowingtableshowstheresultwhenthedatevalueis19398,whichcorrespondstoFebruary9,2013.
FormatName Result
DDMMYYP5. 09.02
DDMMYYB6. 090213
DDMMYYD8. 09-02-13
DDMMYYD8. 09-02-13
DDMMYYS8. 09/02/13
DDMMYYC10. 09:02:2013
DOWNAMEw.
DOWNAMEw.writesthedateasthenameof
thedayoftheweek.Itisright-justified,soifyougiveittoomuchspace,therewillbeleadingblanks.wcanbefrom1to32,andthedefaultis9.Ifyoudon'tspecifyw,SASwillalwaysprinttheentirenameoftheday.However,ifyouspecifywlessthan9,thenSASwilltruncatethename
ofthedaytofitasnecessary.Thefollowingtableshowstheresultwhenthedatevalueis20280,whichcorrespondstoSaturday,July11,2015.
FormatName Result
DOWNAME3. Sat
DOWNAME6. Saturd
DOWNAME8. Saturday
JULDAYw.JULDAYw.writesthedateastheJuliandayoftheyear,whichisavaluefrom1to366.Itisright-justified.wcan
befrom3to32,andthedefaultis3.NotethattheminimumwidthoftheformatwillcauseleadingspacesiftheJuliandateislessthan100.ThiswouldbecomeobviousifyouarecreatingacharacterstringusingthePUT()orPUTN()functionsanddonotremove
leadingblanks.
FormatName Result Comment
JULDAY3. 9 Thereare2leadingspacesherebecausetherearefewerthan
3digitsinthevaluedisplayed.Thedatevalueusedhereis374,whichcorrespondstoJanuary
9,1961.
JULDAY3. 76 Thereisaleadingspaceherebecausetherearefewerthan3digitsinthevalue
displayed.Thedatevalueusedhereis19068,whichcorrespondstoMarch16,2012.
JULDAY3. 107 Thereisnoleadingspaceherebecausethereare3digitsinthevaluedisplayed.Thedate
valueusedhereis19465,whichcorrespondstoApril17,2013.
JULIANw.
JULIANw.writesyourdatevalueasaJuliandate,withtheyearprecedingtheJulianday.Itisright-justified.wcanbefrom5to7,andthedefaultis5.Ifyouspecifyawidthof5,theyearportionoftheJuliandateistwodigitslong.Ifyouspecifyawidthof7,theyearportionisfour
digitslong.Thefollowingtableshowstheresultwhenthedatevalueis18514,whichcorrespondstoSeptember9,2010.
FormatName Result Comment
JULIAN5. 100252
JULIAN7. 2010252
MMDDYYw.
MMDDYYw.writesthedateasnumericalmonth/day/year,whereaslash(/)istheseparator.Itisright-justifiedwithinthefield.wcanbefrom2to10,andthedefaultis8.Itissimilartothe
DDMMYY.formatinthatifyouspecify2–5forthewidth,thedatewillbetruncatedontheright,asSAStriestofitasmuchofthedayandmonthaspossibleinthespaceallowed.Ifyouuse6,noslasheswillbeprinted,butitwillprintatwo-digityear.Awidthof8willputa
two-digityearaftertheslashes.Useawidthof10togetafour-digityearwithslashes.Thefollowingtableshowstheresultwhenthedatevalueis19655,whichcorrespondstoOctober24,2013.
FormatName Result
MMDDYY2. 10
MMDDYY4. 1024
MMDDYY5. 10/24
MMDDYY6. 102413
MMDDYY8. 10/24/13
MMDDYY10. 10/24/2013
MMDDYYxw.
MMDDYYxw.displaysthedateinthesamewaythattheMMDDYY.formatdoes,exceptthatyoucanspecifytheseparator.Thexintheformatnamespecifiestheseparatorthatyou
wanttouseaccordingtothefollowingtable.
x
CharacterDisplayedinOutput Comment
B blank
C colon(:)
D dash(-)
N noseparator
wisamaximumof8,not10.
P period(.)
S slash(/) Effectivelythesameasusingthe
MMDDYY.format.
Thedatewillberight-justifiedwithinthewidththatyouspecify.wcanbefrom2to10,andthedefaultis8.Ifyouspecify2–5,thedatewillbetruncatedontheright,asSAS
triestofitasmuchofthedayandmonthaspossibleinthespaceallowed.Ifyouuseawidthof6,noseparatorwillbeused.At7,SASwillprintatwo-digityearwithoutaseparator,andwidthsof8or9willputatwo-digityearaftertheseparator.Use10togetafour-digityearwith
separators.Thefollowingtableshowstheresultwhenthedatevalueis19188,whichcorrespondstoJuly,14,2012.
FormatName Result
MMDDYYD5. 07-14
MMDDYYS6. 071412
MMDDYYC8. 07:14:12
MMDDYYP10. 07.14.2012
MMDDYYB10. 07142012
MMYYw.
MMYYw.displaysthezero-filledmonthnumberandyearforthegivendatevalue,separatedbytheletterM.Itisright-justified,andwcanbefrom5to32,withadefault
widthof7.Whenwislessthan7,atwo-digityearisused.Otherwise,afullfour-digityearisdisplayed.Sincethisformatonlyneedsamaximumof7characters,anywidthgreaterthan7willjustaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis19756,
whichcorrespondstoFebruary2,2014.
FormatName Result Comment
MMYY5. 02M14
MMYY7. 02M2014 Four-digityear.
MMYYxw.MMYYxw.displaysthemonthnumberandyearforagivendatevalueinthesamefashionthattheMMYY.formatdoes,exceptthatyoucanspecifytheseparatorwithx,accordingtothetablebelow.Notethattheblankisnotvalidwith
thisformat,whileitisvalidwiththeDDMMYYx.andMMDDYYx.formats.
x
CharacterDisplayedinOutput Comment
C colon(:)
D dash(-)
N noseparator
wcanbefrom4to32,withadefaultof6.
P period(.)
S slash(/)
Thedisplayeddate
valuewillbeisright-justified,andwcanbefrom5to32,withadefaultwidthof7.Whenwisspecifiedas5or6,atwo-digityearisused,unlessyouhavespecified"N,"fornoseparator.Withoutaseparator,thereisenoughspacetodisplaythetwodigitsofthemonth,andfour
digitsfortheyear.Ifwis7ormore,afullfour-digityearisalwaysdisplayed.Sincethisformatwillonlydisplayamaximumof7characters,anyvaluegreaterthan7willjustaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis19628,whichcorrespondsto
September27,2013.
FormatName Result Comment
MMYYD5. 09-13 Two-digityear.
MMYYN6. 092013 Noseparator,four-digit
year.
MMYYS6. 09/13 Two-digityearbecauseofseparatorandleadingspace.
MMYYC7. 09:2013 Four-digityear.
MMYYP7. 09.2013 Four-digityear.
MONNAMEw.
MONNAMEw.displaysthenameofthemonth.
Itisright-justified,andwcanbefrom1to32,withadefaultof9.Usingavaluegreaterthan9willonlyaddleadingspaces.SASwilltruncatethemonthnameasnecessarytofitinthewidth.Thefollowingtableshowstheresultwhenthedatevalueis18336,whichcorrespondsto
September15,2010.
FormatName Result
MONNAME3. Sep
MONNAME4. Sept
MONNAME9. September
MONTHw.
MONTHw.displaysthenumberofthemonthoftheyear.Itisright-justified,andwcanbefrom1to21,withadefaultof2.Usingaw
of1willdisplaythemonthnumberasahexadecimalvalue(1throughC).Thefollowingtableshowstheresultwhenthedatevalueis19341,whichcorrespondstoDecember14,2012.
FormatName Result Comment
MONTH1. C walwaysprintsasinglecharacter,whichisahexadecimaldigit.
MONTH2. 12
MONYYw.
MONYYw.displaysthethree-lettermonthabbreviation,followedbytheyearwithoutanyseparatingcharacters.Itisright-justified,andwcanbefrom5to7,withadefaultof5.Specifyingawidthof5willgiveyouatwo-digityear.A
widthof6givesyouatwo-digityearandoneleadingspaceinthedisplayeddate,while7givesyouafour-digityear.ItisanalogoustotheDTMONYY.format,whichisusedwithdatetimevalues.Thefollowingtableshowstheresultwhenthedatevalueis19718,whichcorrespondsto
December26,2013.
FormatName Result Comment
MONYY5. DEC13
MONYY7. DEC2013
PDJULGw.
PDJULGw.writesa
packedJuliandateinhexadecimalformatforIBMcomputers.Justificationisnotanissue,andwcanrangefrom3to16.Thedefaultwidthis4.TheJuliandateiswrittenasfollows:Thefour-digitGregorianyeariswritteninthefirsttwobytes,andthethree-digitintegerthat
representsthedayoftheyearisinthenextone-and-a-halfbytes.Thelasthalf-bytecontainsallbinary1s,whichindicatesthevalueispositive.
IftheSASdatevaluebeingtranslatedbythisformatisadateconstantwithatwo-digityear,itwillbe
affectedbytheYEARCUTOFFoption.SeethefollowingSASlog.
246OPTIONSYEARCUTOFF=1880;247DATA_NULL_;248date1="15JUN2004"d;249date2="15JUN04"d;/*AffectedbyYEARCUTOFFoption*/250juldate1=put(date1,PDJULG4.);
251juldate2=put(date2,PDJULG4.);252PUTjuldate1=$HEX8.;253PUTjuldate2=$HEX8.;254RUN;
juldate1=2004167Fjuldate2=1904167F
PDJULIw.PDJULIw.writesapackedJuliandateinhexadecimalformatfor
IBMcomputers.ItonlydiffersfromthePDJULG.formatinthatitwritesthecenturyinthefirstbyteasatwo-digitinteger,followedbytwodigitsoftheyearinthesecondbyte.Thenextone-and-a-half-bytesstorethethree-digitintegerthatcorrespondstothedayoftheyear,whilethe
lasthalf-byteisfilledwithhexadecimal1sthatindicateapositivenumber.AswiththePDJULG.format,justificationisnotanissue,andthedefaultwidthis4,withawidthrangeof3to16.
Thecenturyandyeararecalculatedbysubtracting1900from
thefour-digitGregorianyear.Ayearvalueof1980givesacentury/yearvalueof0080(1980-1900=80),while2015gives0115(2015-1900=115).Beawarethatthisformatwillnotproducecorrectresultsforyearspreceding1900.Theexamplebelowdemonstrates.
OPTIONSYEARCUTOFF=2000;DATA_NULL_;date1="15JUN1804"d;date2="15JUN1996"d;date3="15JUN96"d;juldate1=PUT(date1,pdjuli4.);juldate2=PUT(date2,pdjuli4.);juldate3=PUT(date3,pdjuli4.);PUTjuldate1=$hex8.;PUTjuldate2=$hex8.;PUTjuldate3=$hex8.;should_be_date1=INPUT(juldate1,pdjuli4.);
PUTshould_be_date1=mmddyy10.;PUTshould_be_date1=;RUN;
Hereistheresultingoutput:
juldate1=009609DFjuldate2=0096167Fjuldate3=0196167Fshould_be_date1=04/12/1996should_be_date1=13251
Thevalueofdate1
correspondstoadatein1804,causingthePDJULI.representationofdate1(juldate1)tobeincorrect.Whileitshouldbethesamedayoftheyear(167)asdate2anddate3,youcanseethatthedayisincorrectlywrittenas09D,whilethecenturyvalueisalsoincorrect,markedas00when,by
thealgorithm,itshouldbeexpressedasanegativenumber.ThisisverifiedbyusingthePDJULI.informattoreadjuldate1,whichgivesaresultofApril12,1996,whenitshouldbeJune15,1804.(Thisisbecausethereisnosignbitforjulday1toindicatethatthevalueshouldbe
negative.)Thedifferencebetweendate2anddate3iscausedbytheYEARCUTOFFoption.Thetwo-digityear96istranslatedas2096,not1996,becauseoftheoption'svalue.
QTRw.QTRw.writesadate
valueasthequarteroftheyear.Itisright-justified,andwcanrangefrom1to32,withadefaultof1.Sincethisformatwillonlywrite1character,specifyingawidthgreaterthan1willjustaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis18264,
whichcorrespondstoJanuary2,2010.
FormatName Result Comment
QTR1. 1
QTRRw.
QTRRw.alsowritesadatevalueasthe
quarteroftheyear,exceptthatitdisplaysthequarterasaRomannumeral.Itisright-justified,andwcanrangefrom3to32,withadefaultof3.Thisformatwillwriteamaximumof3characters.Awidthspecificationgreaterthan3willaddleadingspaces.
FormatName Result Comment
QTRR3. III Thedatevalueusedis17791(September16,2008).
QTRR3. IV Withadatevalue
of17882(December16,2008),thereis1leadingspace.
QTRR5. III Withadatevalueof17791
(September16,2008),thereare2leadingspaces.
WEEKDATEw.
WEEKDATEw.writesdatevaluesasday-of-
weekname,monthname,day,andyear.Itisright-justified,andwcanrangefrom3to37.Thedefaultis29,whichisthemaximumwidthofadateinthisformat.Specifyinganythinglongerthan29willcauseleadingspacestobeadded.Ifthewidthspecifiedistoosmalltodisplaythe
completedayoftheyearandmonth,SASwillabbreviate.Thefollowingtableshowstheresultwhenthedatevalueis18164,whichcorrespondstoSeptember24,2009.
FormatName Result
WEEKDATE3. Wed
WEEKDATE9. Wednesday
WEEKDATE17. Wed,Sep24,2009
WEEKDATE23. Wednesday,Sep24,2009
WEEKDATE29. Wednesday,September24,2009
WEEKDATXw.WEEKDATXw.writesdatevaluesasday-of-weekname,day,monthname,andyear.
ItdiffersfromtheWEEKDATE.formatinthatthedayofthemonthprecedesthemonthname.Itisright-justified,andwcanrangefrom3to37.Thedefaultis29,whichisthemaximumwidthofadateinthisformat.Specifyinganythinglongerthan29willcauseleadingspacesto
beadded.Ifthewidthspecifiedistoosmalltodisplaythecompletedayoftheyearandmonth,SASwillabbreviate.Thefollowingtableshowstheresultwhenthedatevalueis19260,whichcorrespondstoSeptember24,2012.
FormatName Result
WEEKDATX3. Wed
WEEKDATX9. Wednesday
WEEKDATX17. Wed,24Sep,2012
WEEKDATX23. Wednesday,24Sep,2012
2012
WEEKDATX29. Wednesday,24September,2012
WEEKDAYw.
WEEKDAYw.writesthedatevalueasthenumberofthedayoftheweek,where1=Sunday,2=Monday,andsoon.Itisright-justified,andwcanbefrom1to32.Thedefaultis1.Sincethemaximumwidthofthedisplayisalwaysonecharacter,specifyinganything
longerwilljustcauseleadingspacestobeadded.Thefollowingtableshowstheresultwhenthedatevalueis20569,whichcorrespondstoMonday,April25,2016.
FormatName Result Comment
WEEKDAY1. 2
WEEKUw.WEEKUw.writesthedatevalueasaweeknumberindecimalformatusingtheUalgorithm.Unlikemanyotherdate,time,anddatetimeformats,itisleft-justified.wcanbefrom1to200,andthe
defaultis11.Specifyinganyvaluegreaterthan11willdisplaythesameresultsasifwwere11.TheUalgorithmcalculatesweeksbasedonSundaybeingthefirstdayoftheweek,andtheweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroif
necessary.Thedisplaythatthisformatpresentsvaries,basedonthewidthspecification.Thefollowingtableshowstheresultwhenthedatevalueis20885,whichcorrespondstoMarch7,2017,whichisaTuesdayinthetenthweekoftheyear.
FormatName Result
WEEKU3. W10
WEEKU4. W10
WEEKU5. 17W10
WEEKU6. 17W10
WEEKU7. 17W1003
WEEKU8. 17W1003
WEEKU9. 2017W1003
WEEKU10. 2017W1003
WEEKU11. 2017-W10-03
WEEKU12. 2017-W10-03
WEEKVw.
WEEKVw.writesthedatevalueasaweeknumberindecimalformatusingtheValgorithm,whichisInternationalStandardsOrganization(ISO)compliant.Itisleft-justifiedinthesamefashionastheWEEKU.format.wcanbefrom1to200,andthedefaultis11.
Specifyinganyvaluegreaterthan11willdisplaythesameresultsasifwwere11.TheValgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweek,andtheweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroifnecessary.
ThisalgorithmdefinesthefirstweekoftheyearascontainingbothJanuary4andthefirstThursdayoftheyear.Therefore,ifthefirstMondayoftheyearfallsonJanuary2,3,or4,theprecedingdaysofthecalendaryearareconsideredtobeapartofweek53ofthepreviouscalendaryear.
Thefollowingtableshowstheresultwhenthedatevalueis19723,whichcorrespondstoDecember31,2013.Notethatalthoughthedateisin2013,thealgorithmusedbythisformatplacesthedateintheyear2014.Monday,December30,2013,isconsideredto
bethefirstdayofthefirstweekfortheyear2014.
FormatName Result
WEEKV3. W01
WEEKV4. W01
WEEKV5. 14W01
WEEKV6. 14W01
WEEKV7. 14W0102
WEEKV8. 14W0102
WEEKV9. 2014W0102
WEEKV10. 2014W0102
WEEKV11. 2014-W01-02
WEEKV12. 2014-W01-02
WEEKWw.
WEEKWw.writesthedatevalueasaweeknumberindecimalformatusingtheWalgorithm.AswiththeWEEKU.andWEEKV.formats,itisleft-justified.wcanbefrom1to200,andthedefaultis11.Specifyinganyvalue
greaterthan11willdisplaythesameresultsasifwwere11.TheWalgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweekwithoutanyotherrestriction.Theweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroif
necessary.Thedisplaythatthisformatpresentsvariesbasedonthewidthspecification.Thefollowingtableshowstheresultwhenthedatevalueis19723,whichcorrespondstoDecember31,2013(thesamedateusedintheValgorithmexample).Notethatthe
Walgorithmassignsthedateastheseconddayofthelastweekofthecalendaryear2013.
FormatName Result
WEEKW3. W52
WEEKW4. W52
WEEKW5. 13W52
WEEKW6. 13W52
WEEKW7. 13W5202
WEEKW8. 13W5202
WEEKW9. 2013W5202
WEEKW10. 2013W5202
WEEKW11. 2013-W52-02
WEEKW12. 2013-W52-
02
WORDDATEw.
WORDDATEw.displaysthedatevalueasnameofmonth,day,andyear.Itisright-justified,andwcanrangefrom3to32.Thedefaultis18.Ifthewidthspecifiedisless
than18,SASwillabbreviatethemonthnameandaddleadingspacesasnecessary,regardlessofwhetherthespecificdatetobedisplayedwillfitintheallocatedspacebecauseofitsvalue.ThismighthaveanimpactifyouaregoingtousethePUT()orPUTN()functionstocreatea
characterstringusingthisformat.Thefollowingtableshowstheresultwhenthedatevalueis20328,whichcorrespondstoAugust28,2015.
FormatName Result
WORDDATE3. Aug
WORDDATE12. Aug
28,2015
WORDDATE15. Aug28,2015
WORDDATE18. August28,2015
WORDDATE20. August28,2015
WORDDATXw.
WORDDATXw.displaysthedatevalueasday,nameofmonth,andyear.ItdiffersfromtheWORDDATE.formatinthatthedayprecedesthenameofmonth.Itisright-justified,andwcanrangefrom3to32.Thedefaultis18.Ifthewidthspecifiedisless
than18,SASwillabbreviatethemonthnameandaddleadingspacesasnecessary,evenifthedatetobedisplayedwillfitinthewidthspecified.ThismighthaveanimpactifyouaregoingtousethePUT()orPUTN()functionstocreateacharacterstringusingthisformat.Inthe
followingtable,youseethatMarchisabbreviatedforwidthspecificationslessthan18,eventhoughthereisroomtoprinttheentiredatestring.Thetableshowstheresultwhenthedatevalueis21259,whichcorrespondstoMarch16,2018.
FormatName Result
WORDDATX3. Mar
WORDDATX12. 16Mar2018
WORDDATX14. 16Mar2018
WORDDATX16. 16Mar2018
WORDDATX18. 16March2018
YEARw.
YEARw.displaystheyearforthegivendatevalue.Itisright-justified,andwcanbefrom2to4,withadefaultwidthof4.
Whenwisspecifiedas2or3,atwo-digityearisused.Thefollowingtableshowstheresultwhenthedatevalueis18599,whichcorrespondstoDecember3,2010.
FormatName Result Comment
YEAR2. 10 Two-digityear.
YEAR3. 10 Two-digityearwithaleadingspace.
YEAR4. 2010 Four-digityear.
YYMMw.
YYMMw.displaystheyearandmonthnumberforthegivendatevalue,separatedbytheletterM.Itisright-justified,andwcanbefrom5to32,withadefaultwidthof7.Whenwisspecified
as5or6,atwo-digityearisused.Ifwis7ormore,afullfour-digityearisdisplayed.Sincethisformatcanonlydisplayamaximumof7characters,anythingmorethan7willjustaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis19517,whichcorrespondsto
June8,2013.
FormatName Result Comment
YYMM5. 13M06 Two-digityear.
YYMM6. 13M06 Leadingspace.
YYMM7. 2013M06 Four-
digityear.
YYMM8. 2013M06 Leadingspace.
YYMMxw.YYMMxw.displaystheyearandmonthnumberforagivendatevalueinthesame
mannerastheYYMM.formatabove,exceptthatyoucanspecifytheseparatorwithxaccordingtothetablebelow.UnliketheDDMMYYx.,MMDDYYx.,andtheYYMMDDx.formats,ablankisnotavalidseparatorwiththisformat.
x
CharacterDisplayedinOutput Comment
C colon(:)
D dash(-)
N noseparator
wcanbefrom4to32,withadefault
adefault
of6.
P period(.)
S slash(/)
YYMMxw.isright-justified,andwcanbefrom5to32,withadefaultwidthof7.Whenwisspecifiedas5or6,atwo-digityear
isused.Ifwis7ormore,afullfour-digityearisdisplayed.Specifyingnoseparatorwith"N"willchangetherangeofwfrom4to32,andthedefaultwidthbecomes6.Sincethisformatcanonlydisplayamaximumof7characters,anythingmorethan7willjustaddleadingspaces.The
followingtableshowstheresultwhenthedatevalueis19237,whichcorrespondstoSeptember1,2012.
FormatName Result Comment
YYMMN4. 1209 Noseparator;minimum
widthis4;two-digityear.
YYMMC5. 12:09
YYMMD6. 12-09 Oneleadingspace;two-digit
year.
YYMMP7. 2012.09 Four-digityear.
YYMMS8. 2012/09 Four-digityear;1leadingspace.
YYMMDDw.
YYMMDDw.isavariationontheDDMMYY.andMMDDYY.formats.Itwritesthedateasayear,followedbythenumericalmonth,andthentheday,withadash(-)astheseparator.Itisright-justifiedwithinthefield.wcanbefrom2to10,andthedefaultis
8.ItissimilartotheMMDDYY.formatinthatifyouspecifythewidthfrom2to5,thedatewillbetruncatedontheright,asSAStriestofitasmuchoftheyearandmonthaspossibleinthespaceallowed.Ifyouuse6,nodasheswillbeprinted.At7,SASwillprintatwo-digityear
withoutadash,and8or9willproduceatwo-digityearbeforethefirstdash.Useawidthof10togetafour-digityearwithdashes.Thefollowingtableshowstheresultwhenthedatevalueis20031,whichcorrespondstoNovember4,2014.
FormatName Result
YYMMDD4. 1411
YYMMDD5. 14-11
YYMMDD6. 141104
YYMMDD7. 141104
YYMMDD8. 14-11-04
YYMMDD9. 14-11-04
YYMMDD10. 2014-
11-04
YYMMDDxw.
YYMMDDxw.displaysthedateinthesamewaythattheYYMMDD.formatdoes,exceptthatyoucanspecifytheseparator.Thexintheformatnamespecifiestheseparatorthatyou
wanttouseaccordingtothetablebelow.
x
CharacterDisplayedinOutput Comment
B blank
C colon(:)
D dash(-) Effectively
thesameasusingtheYYMMDD.format.
N noseparator
wisamaximumof8,not10.
P period(.)
S slash(/)
Thedatewillberight-justifiedwithinthewidththatyouspecify.wcanbefrom2to10,andthedefaultis8.Ifyouspecify2–5,thedatewillbetruncated
ontheright,asSAStriestofitasmuchofthedayandmonthaspossibleinthespaceallowed.Ifyouuse6,noseparatorwillbeused.At7,SASwillprintatwo-digityearwithoutaseparator,and8or9willputatwo-digityearbeforethefirstseparator.Thefollowingtableshows
theresultwhenthedatevalueis19500,whichcorrespondstoMay22,2013.
FormatName Result
YYMMDDN4. 1305
YYMMDDC5. 13:05
YYMMDDD6. 130522
YYMMDDP7. 130522
YYMMDDB8. 130522
YYMMDDN8. 20130522
YYMMDDS9. 13/05/22
YYMMDDD10. 2013-05-22
YYMONw.
YYMONw.writesdatesasatwo-orfour-digityearfollowedbythethree-lettermonthabbreviation.Itisright-justified.wcanbefrom5to32,andthedefaultis7.Useawidthof7togetafour-digityear.Ifwislessthan7,atwo-digityearwillbe
displayed.Ifwislargerthan7,leadingspaceswillbeadded.Thefollowingtableshowstheresultwhenthedatevalueis20796,whichcorrespondstoDecember8,2016.
FormatName Result
YYMON5. 16DEC
YYMON6. 16DEC
YYMON7. 2016DEC
YYMON10. 2016DEC
YYQw.
YYQw.writesdate
valuesasatwo-orfour-digityear,followedbytheletterQ,andasingle-digitrepresentingthequarteroftheyear.Itisright-justified,andwcanbefrom4to32.Thedefaultwidthis6.Use6togetafour-digityear,whileawidthof4or5willgiveyouatwo-digityear.
Specifyingawidthlargerthan6willonlyaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis21384,whichcorrespondstoJuly19,2018.
FormatName Result Comment
YYQ4. 18Q3 Two-digityear.
YYQ5. 18Q3 Two-digityearwith1leadingspace.
YYQ6. 2018Q3 Four-digityear.
YYQ8. 2018Q3 Four-digityearwith2leadingspaces.
YYQxw.YYQxw.writesdatevaluesasatwo-or
four-digityear,followedbyaseparatorthatyouspecify,andasingle-digitrepresentingthequarteroftheyear.xistheletterthatyouusetoindicatetheseparatoraccordingtothetablebelow.UnliketheDDMMYYx.,MMDDYYx.,andtheYYMMDDx.formats,a
blankisnotavalidseparatorwiththisformat.
x
CharacterDisplayedinOutput Comment
C colon(:)
D dash(-)
N noseparator
wcanbefrom3to32,withadefaultof4.Whenwis3or4,theyearwillbe
displayed
withtwodigits.
P period(.)
S slash(/)
Thisformatisright-justified,andwcanbefrom4to32.The
defaultwidthis6.Useawidthof6togetafour-digityear,while4or5willgiveyouatwo-digityear.Specifyingawidthlargerthan6willaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis19659,whichcorrespondstoOctober28,2013.
FormatName Result Comment
YYQN3. 134 Two-digityearwithnoseparator.
YYQC4. 13:4 Two-digityear.
YYQS5. 13/4 Two-digityearwith1leadingspace.
YYQP6. 2013.4 Four-digityear.
YYQD7. 2013-4
Four-digityearwith1leading
space.
YYQRw.
YYQRw.writesdatevaluesasatwo-orfour-digityear,followedbytheletterQ,andthequarteroftheyearisrepresentedinRomannumerals.It
isright-justified,andwcanbefrom6to32.Thedefaultwidthis8.Use8togetafour-digityear,while6or7willgiveyouatwo-digityear.Specifyingawidthlargerthan8willaddleadingspaces.
Thefollowingtableshowstheresultwhenthedatevalueis
20312,whichcorrespondstoAugust12,2015.
FormatName Result Comment
YYQR6. 15QIII Two-digityear.
YYQR7. 15QIII Two-digityearwith
1leadingspaceforthethirdquarteronly;four-digityeardisplayedforthe
1st,2nd,and4thquarterswithoutanyleadingspace.
YYQR8. 2015QIII Four-digit
year.
YYQR12. 2015QIII Four-digityearwith4leadingspaces.
YYQRxw.
YYQRxw.writesdate
valuesasatwo-orfour-digityear,followedbyaseparatorthatyouspecify,andthequarteroftheyearisdisplayedasaRomannumeral.xistheletterthatyouusetoindicatetheseparatoraccordingtothefollowingtable.Thisisanotherformatthatcannotuseablank
astheseparator.
x
CharacterDisplayedinOutput Comment
C colon(:)
D dash(-)
N noseparator
wcanbefrom5to
32,withadefaultof7.Whenwis5or6,theyearwillbedisplayedwithtwo
digits.
P period(.)
S slash(/)
Thisformatisright-justified,andwcanbefrom6to32.Thedefaultwidthis8.Use8togetafour-digityear,while6or7will
displayatwo-digityear.Specifyingawidthlargerthan8willaddleadingspaces.Thefollowingtableshowstheresultwhenthedatevalueis19545,whichcorrespondstoJuly6,2013.
FormatName Result Comment
YYQRP6. 13.III Two-digityear.
YYQRS7. 13/III Two-digityearwith1leadingspaceforthethirdquarteronly;
four-digityeardisplayedforthe1st,2nd,and4thquarterswithoutany
leadingspace.
YYQRN8. 2013III Four-digityearwith1leadingspaceandnoseparator.
YYQRC9. 2013:III Four-digityearwith1leadingspace.
YYQRD10. 2013-III
Four-digityearwith2leadingspaces.
YYWEEKUw.YYWEEKUw.writesthedatevalueasaweeknumberindecimalformatusingtheUalgorithm.Unlikemanyotherdate,time,anddatetimeformats,itisleft-justified.wcanbefrom3to8,andthedefaultis7.TheUalgorithmcalculates
weeksbasedonSundaybeingthefirstdayoftheweek,andtheweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroifnecessary.Thedisplaythatthisformatpresentsvariesbasedonthewidthspecification.Thisformatissimilartothe
WEEKU.format,exceptthatitdoesnotprovidethenumericaldayoftheweek.Thedatevalueusedinthisexampleis20041,whichcorrespondstoNovember14,2014.
FormatName Result
YYWEEKU3. W45
YYWEEKU4. W45
YYWEEKU5. 14W45
YYWEEKU6. 14W45
YYWEEKU7. 2014W45
YYWEEKU8. 2014-W45
YYWEEKVw.
YYWEEKVw.writesthedatevalueasaweeknumberindecimalformatusingtheValgorithm,whichisInternationalStandardsOrganization(ISO)compliant.Itisleft-justifiedinthesamefashionastheYYWEEKU.format.wcanbefrom3to8,andthedefaultis7.This
formatissimilartotheWEEKV.format,exceptthatitdoesnotprovidethenumericaldayoftheweek.TheValgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweek,andtheweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroif
necessary.
ThisalgorithmdefinesthefirstweekoftheyearascontainingbothJanuary4andthefirstThursdayoftheyear.Therefore,ifthefirstMondayoftheyearfallsonJanuary2,3,or4,theprecedingdaysofthecalendaryearareconsideredtobeapart
ofweek53ofthepreviouscalendaryear.Thedatevalueusedinthisexampleis20455,whichcorrespondstoSaturday,January2,2016.Notethatalthoughthedateisin2016,thealgorithmusedbythisformatplacesthedateinweek53oftheyear2015.Thefirstweekofthe
year2016startsonSunday,January3,2016,asthatcontainsthefirstThursdayoftheyearandJanuary4,2016.
FormatName Result
YYWEEKV3. W53
YYWEEKV4. W53
YYWEEKV5. 15W53
YYWEEKV6. 15W53
YYWEEKV7. 2015W53
YYWEEKV8. 2015-
W53
YYWEEKWw.
YYWEEKWw.writesthedatevalueasaweeknumberindecimal
formatusingtheWalgorithm.AswiththeYYWEEKU.andYYWEEKV.formats,itisleft-justified.wcanbefrom3to8,andthedefaultis7.ThisformatissimilartotheWEEKW.format,exceptthatitdoesnotprovidethenumericaldayoftheweek.TheWalgorithmcalculates
weeksbasedonMondaybeingthefirstdayoftheweekwithoutanyotherrestriction.Theweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroifnecessary.Thedisplaythatthisformatpresentsvaries,basedonthewidth
specification.Thefollowingtableshowstheresultwhenthedatevalue20455,whichcorrespondstoSaturday,January2,2016(thesamedateusedintheYYWEEKV.algorithmexample).NotethattheWalgorithmassignsthedateasbeinginweekzeroofthecalendar
year2016.UnliketheValgorithm,itdoesnotconsiderthedateasbeingapartofweek53in2015,butassignsittoweek0in2016.Week1isdefinedasthefirstfullweekin2016.
FormatName Result
YYWEEKW3. W00
YYWEEKW4. W00
YYWEEKW5. 16W00
YYWEEKW6. 16W00
YYWEEKW7. 2016W00
YYWEEKW8. 2016-W00
2.4.2Time
FormatsTimeformatstranslatesecondsintooneofseveraldifferentwaysofdisplayingtime.OnlytheTIMEAMPM.andTOD.formatsarespecifictoclockvalues,displayingclockvaluesfrom12:00:00a.m.to11:59:59p.m.Allotherformatswilldisplay
hoursgreaterthan23whentranslatingavaluegreaterthanorequalto86400,whichwouldbemidnightofthefollowingday.Thedisplayofminutesalwaysrangesfrom0to59,exceptwhenyouareusingtheMMSSw.dformat.Thebuilt-inSASformatsalwaysdisplaysecondsfrom0
to59.
Thewidthspecificationfortime(anddatetime)valuesisdifferentfromtheonefordateformatsbecauseithastoallowfordecimalpartsofseconds.Insteadofw,timeanddatetimeformatsarespecifiedasw.d,wherewistheoverallwidth
oftheentireformat,andthedaccountsforthenumberofdigitstotherightofthedecimalpoint.wmustbegreaterthan(d+1)toaccountforthedecimalpoint.Aswithdateformats,eachoftheseformatshasitsowndefaultwidthspecification,whichisdetailedinthe
descriptionoftheformat.
HHMMw.dHHMMw.ddisplaysSAStimevaluesashours:minutes.Itisright-justifiedanddoesnotdisplayaleadingzeroinfrontofthehours.wcanbefrom2to20,withadefaultof
5,whiledindicatesthenumberofdecimalplacestotherightoftheminutes.Aspreviouslynoted,wmustbegreaterthand+1,toaccountforthedecimalpoint.ItisdifferentfromtheTIMEw.dformatinthatitdoesnotdisplayseconds.Ifdis0ornotpresent,SASwillround
tothenearestminute.Otherwise,SASwilldisplaythesecondsindecimalminutes(seconds/60).Leadingspaceswillbeaddedtothedisplaybasedonthenumberofdigitsintheresult.Ifthewidthspecifiedisnotlongenoughtoaccommodatethe3spacesforthecolon
andtheminutes,SASwillonlydisplaythehoursanddoesnotroundthedisplayedvalue.Thefollowingtableshowstheresultwhenthetimevalueis49794,whichcorrespondsto13hours,49minutes,and54seconds.
FormatName Result Comment
HHMM2. 13
HHMM3. 13
HHMM5. 13:50
HHMM5. 13:50
HHMM8. 13:50
HHMM8.2 13:50.90
HOURw.d
HOURw.ddisplaysSAStimevaluesashoursanddecimalfractionsofhours.Itisright-justified.wcanbefrom
2to20,withadefaultof2.disthenumberofdecimalplacestotherightofthehours,andwmustbegreaterthand+1toaccountforthedecimalpoint.Ifyoudonotspecifyanydecimalplaces,SASroundstothenearesthour.Thefollowingtableshowstheresultwhenthetimevalueis
53706,whichcorrespondsto14hours,55minutes,and6seconds.
FormatName Result Comment
HOUR2.0 15 Roundedtothenearest
hour.
HOUR4.2 14.9 55minutes,6seconds,is.92hours;doesnotleave
enoughspaceforaseconddecimalplace.
HOUR6.2 14.92 Oneleadingspace.
HOUR8.2 14.92 Three
leadingspaces.
MMSSw.d
MMSSw.ddisplaysSAStimevaluesasminutesandseconds(mm:ss).Itisright-justified.wcanbefrom2to20,withadefaultof5.Ifyoudo
notspecifywlargeenoughtofitminutesandseconds,SASwillroundanddisplaytheminutesonly.dwillprintdecimalfractions(e.g.,tenthsorhundredths)ofseconds.wmustbegreaterthand+1toaccountforthedecimalpoint.Thefollowingtableshowstheresultwhenthe
timevalueis37269,whichcorrespondstothetime10:21:09a.m.(10:21:09).
FormatName Result Comment
MMSS4. 621
MMSS5. 621
MMSS8.2 621:09.0
MMSS9.2 621:09.00
TIMEw.d
TIMEw.ddisplaysSAStimevaluesashours:minutes:seconds.Itisright-justifiedanddoesnotprintaleadingzeroinfrontofthehours.wcanbefrom2to20,withadefaultof8,whiledindicatesthenumberofdecimalplacestotherightof
theseconds.wmustbegreaterthand+1toaccountforthedecimalpoint.dwillprintdecimalfractions(e.g.,tenthsorhundredths)ofseconds.
Thisformatisnotrestrictedtoa24-hourday;ifhoursisgreaterthan24,thenitwilldisplaytheactualvalue
ofhours,whichmeansthatthedefaultlengthof8maynotbeenoughtoholdtheentireformattedtimevalue.ItisdifferentfromtheHHMM.formatinthatitdisplayssecondsasopposedtodecimalfractionsofminutes.Ifdis0ornotpresent,SASwillroundtothenearestsecond.The
timevalueusedforthefollowingtableis49794seconds,thesamevalueusedfortheHHMMw.dformat.Thetimevaluecorrespondstothetime1:49:54p.m.(13:49:54).
FormatName Result Comment
TIME5. 13:49
TIME6. 13:49 Leadingspace.
TIME7. 13:49 Twoleadingspaceswithsecondstruncated.Ifthiswereasingle-digit
hour(i.e.,0through9),theentiretimewouldbedisplayedwithoutleadingspacesbecauseit
wouldfitin7spaces.
TIME8. 13:49:54 Defaultwillaccommodateupto99hours.
TIME9. 13:49:54 Leadingspace;may
benecessaryforhourvaluesgreaterthan99.
TIMEAMPMw.d
TIMEAMPMw.ddisplaystimein
hours:minutes:secondsfollowedbyaspaceandthenAMorPM.Itisright-justified.wcanbefrom2to20,andthedefaultis11.wmustbegreaterthand+1,toaccountforthedecimalpoint.Anytimevaluegreaterthanorequalto86400(midnight)willbedisplayedasthe12-
hourclocktimeofthenextday.Thisformatdoesnotprintaleadingzero.Ifyouwantthesecondstobeprinted,useatleast11forthewidth.Thefollowingtableshowstheresultwhenthetimevalueis11923,whichcorrespondstothetime3:18:43a.m.
FormatName Result
TIMEAMPM7. 3:18AM
TIMEAMPM9. 3:18AM
TIMEAMPM11. 3:18:43AM
TODw.d
TODw.ddisplaystimeinhours:minutes:secondsusingthe24-hour
clock.Itisright-justified.wcanbefrom2to20,andthedefaultis11.disthedecimalfractionofseconds.wmustbegreaterthand+1,toaccountforthedecimalpoint.Anytimevaluegreaterthanorequalto86400(midnightofthenextday)willbemarkedasthe24-hourclocktime
ofthenextday.Thisformatdoesnotprintaleadingzero.Ifyouwantthesecondstobedisplayed,use8forthewidth.Useatleast10ifyouwantdecimalfractionsofsecondsshown.Thefollowingtableshowstheresultwhenthetimevalueis75122,whichcorrespondstothetime
8:52:02p.m.(20:52:02):
FormatName Result Comment
TOD5. 20:52
TOD8. 20:52:02
TOD11. 20:52:02 Threeleading
spaces;usefulwhenusingfractionsofseconds.
2.4.3Datetime
FormatsDatetimeformatstranslateSASdatetimevaluesintooneofseveraldifferentformats.SASdatetimevaluesarethenumberofsecondssincemidnight,January1,1960.Youcanuseaformattodisplayboththedateandtime.
Again,youneedtopayattentiontothewidthspecificationindatetimeformatsbecauseitallowsfordecimalfractionsofseconds.Insteadofw,timeanddatetimeformatsarespecifiedasw.d,wherewistheoverallwidthoftheentireformat,andthedaccountsforthe
numberofdigitstotherightofthedecimalpoint.wmustbegreaterthand+1toaccountforthedecimalpoint.Aswithdateformats,eachoftheseformatshasitsowndefaultwidthspecification,whichisdetailedinthedescriptionoftheformat.
StartingwithSASversion9,therearealsoanumberof"DT"formatsthatwillallowyoutodisplayjustthedateorjustthetimefromadatetimevalue,eliminatingtheneedtousetheDATEPART()orTIMEPART()functionsfordisplaypurposes.Althoughthese"DT"formatsappeartogive
thesameresultastheircorrespondingdateortimeformats,theresultsyougetwillbeverydifferentshouldyouuseadatetimeformatonadatevalueandviceversa.Datetimeformatstranslatesecondssincemidnight,January1,1960,whiledateformatstranslatedays
sinceJanuary1,1960.
Example2.5showswhathappenswhenyouusedateformatstointerpretdatetimevaluesandviceversa.IfyoutranslatetheSASdatevalue19855usingadateformat,youwillgetthecorrectvalueofMay12,2014(❶and❷).However,ifyouuse
adatetimeformattotranslatethesamevalue,youwillget5:30:55a.m.onJanuary1,1960,whichcorrespondsto19,855secondsaftermidnight,January1,1960(❸and❹).Insimilarfashion,ifyoutranslatethevalue1705587720usingadatetimeformat,youwillget
2:22p.m.onJanuary17,2014(❺and❻).Thistime,ifyoutrytouseadateformattotranslatethisvalue,youwillgetaseriesofasterisksbecausethevalueistoofarinthefuturefortheSASformatalgorithmtohandle(❼and❽).Evenifyoutrytogetthemonth,day,andyear
ofthisvalueusingtheappropriatefunctions,itwillnotwork.
Example2.5:TheDifferencebetweenDateandDatetimeValuesinFormatsThatDisplayDates
DATA_NULL_;date=19855;datetime=1705587720;PUT"MMDDYY10.representationofdate="
datemmddyy10.;❶PUT"MONYY7.representationofdate="datemonyy7.;❷PUT"DTMONYY7.representationofdate="datedtmonyy.;❸PUT"WhenvalueofdateisusedasaSAS*datetime*value,thedaterepresentedis:"datedatetime20.;❹PUT"DATETIME20.representationofdatetime="datetimedatetime20.;❺
PUT"DTMONYY7.representationofdatetime="datetimedtmonyy7.;❻PUT"MONYY7.representationofdatetime="datetimemonyy7.;❼PUT"WhenvalueofdatetimeisusedasaSAS*date*value,thedaterepresentedis:"datetimemmddyy10.;❽RUN;
Andhereistheresult.
MMDDYY10.representationofdate=05/12/2014❶MONYY7.representationofdate=MAY2014❷DTMONYY7.representationofdate=JAN60❸WhenvalueofdateisusedasaSAS*datetime*value,thedaterepresentedis:01JAN1960:05:30:55❹DATETIME20.representationofdatetime=17JAN2014:14:22:00❺DTMONYY7.representation
ofdatetime=JAN2014❻MONYY7.representationofdatetime=*******❼WhenvalueofdatetimeisusedasaSAS*date*value,thedaterepresentedis:**********❽
Withthatinmind,herearetheformatsthatareapplicabletodatetimevalues.
DATEAMPMw.dDATEAMPMw.ddisplaysdatetimevaluesasddmonyy(yy):hh:mm:ss.ssxx,whereddisthedayofthemonth,monisthethree-letterabbreviationforthemonth,andyy(yy)isthetwo-orfour-digityear.Acolonfollows
thedate,andthetimeisrepresentedbyhh:mm:ss.ss,followedbyaspaceandthenAMorPM.Itisright-justified.wcanbefrom7to40,andthedefaultis19.disthedecimalfractionofsecondsandmustbelessthanw–1,toaccountforthedecimalpoint.wmustbeatleast13toprint
AMorPM.Ifwis10,11,or12,thetimeisdisplayedasa24-hourclock.Also,ifw–dislessthan17,thedecimalvalueswillbetruncatedtofitthespecifiedfieldwidth.Thisformatproducestwo-digityearsforwidthsof19orless.Thefollowingtableshowstheresultwhen
thedatetimevalueis1746745319.6,whichcorrespondstothetime11:01:59.6p.m.onMay8,2015.
Notetheroundingtothenearestsecond,whichcausesthedisplayedresulttoberoundedtothenearestminutewhenthereisn'tenoughroomforthe
decimal.
FormatName Result
DATEAMPM7. 08MAY15
DATEAMPM12. 08MAY15:11
DATEAMPM18. 08MAY15:11:02AM
DATEAMPM18.1 08MAY15:11:02PM
DATEAMPM19. 08MAY15:11:02:00
PM
DATEAMPM19.1 08MAY15:11:02:00PM
DATEAMPM21. 08MAY15:11:02:00
PM
DATEAMPM21.1 08MAY15:11:01:59.6PM
DATETIMEw.dDATETIMEw.ddisplays
datetimevaluesasddmonyy(yy):hh:mm:ss.ss,whereddisthedayofthemonth,monisthethree-lettermonthabbreviation,andyy(yy)isthetwo-orfour-digityear.Acolonfollowsthedate,andthetimeisrepresentedbyhh:mm:ss.ss.ItissimilartotheDATEAMPMw.dformat,
exceptthatitusesthe24-hourclockandthereforedoesnotdisplayAMorPM.Itisright-justified.wcanbefrom7to40,andthedefaultis19,whichwillprovideenoughroomforseconds.Usealengthof15ifyouonlywanthoursandminutestobedisplayedalongwiththedate.d
isthedecimalfractionofsecondsandmustbelessthanw–1toaccountforthedecimalpoint.Ifw–dislessthan17,thedecimalvalueswillbetruncatedtofitthespecifiedfieldwidth.Ifw–dislessthan19,thisformatproducestwo-digityears.Thefollowingtableshows
theresultwhenthedatetimevalueis1698258126.84,whichcorrespondstothetime6:22:07p.m.onOctober24,2013.
FormatName Result
DATETIME16. 24OCT13:18:22:07
DATETIME18. 24OCT13:18:22:07
DATETIME18.1 24OCT13:18:22:06.8
DATETIME19. 24OCT2013:18:22:07
DATETIME19.1 24OCT13:18:22:06.8
DATETIME20. 24OCT2013:18:22:07
DATETIME20.1 24OCT2013:18:22:06.8
DATETIME21. 24OCT2013:18:22:07
DATETIME21.2 24OCT2013:18:22:06.84
DTDATEw.
DTDATEw.displaysdatetimevaluesasthenumericaldayofthemonth,followedbythethree-lettermonthabbreviationandtheyearwithoutanyseparatingcharacters.Itisright-justifiedwithinthefield.wcan
befrom5to9,andthedefaultwidthis7.Ifyouwanttodisplayfour-digityears,useDTDATE9.TheoutputisidenticaltotheoutputusingtheDATE.format.Thedifferenceisthatthisformatwillonlyworkcorrectlywithdatetimevalues,whiletheDATE.formatonlyworkscorrectly
withdatevalues.Thefollowingtableshowstheresultwhenthedatetimevalueis1729519835.7,whichcorrespondstothetime2:10:36p.m.onOctober21,2014.
FormatName Result
DTDATE5. 21OCT
DTDATE6. 21OCT
DTDATE7. 21OCT14
DTDATE8. 21OCT14
DTDATE9. 21OCT2014
DTMONYYw.
DTMONYYw.displaysthedatefromadatetimevalueasthethree-lettermonthabbreviationfollowedimmediatelybytheyear.Thereareno
separatingcharacters.Itisright-justified,andwcanbefrom5to7,withadefaultof5.Specifying5or6willgiveyouatwo-digityear,while7willgiveyouafour-digityear.AlthoughthisformatappearstoproducethesameMMMyy(yy)resultastheMONYY.format,theDTMONYY.
formatonlyworkswithdatetimevalues,whiletheMONYY.formatonlyworkswithdatevalues.Thefollowingtableshowstheresultwhenthedatetimevalueis1727036339.1,whichcorrespondstothetime8:18:59p.m.onSeptember22,2014.
FormatName Result
DTMONYY5. SEP14
DTMONYY6. SEP14
DTMONYY7. SEP2014
DTWKDATXw.
DTWKDATXw.writesdatetimevaluesasdayofweekname,day,monthname,andyear.ItdiffersfromtheWEEKDATX.formatinthatitworksondatetimevalues,notdatevalues.Itisright-justified,andwcanrangefrom3to37.The
defaultis29,whichisthemaximumwidthofadateinthisformat.Specifyinganythinglongerthan29willcauseleadingspacestobeadded.Ifthewidthspecifiedistoosmalltodisplaythecompletedayoftheyearandmonth,SASwillabbreviate.Itwillfirstabbreviatethemonth
andthenthedayoftheweekasnecessary.Thefollowingtableshowstheresultwhenthedatetimevalueis1645971726,whichcorrespondstothetime2:22:06p.m.onFebruary27,2012.
FormatName Result
DTWKDATX3. Mon
DTWKDATX9. Monday
DTWKDATX15. Mon,27
Feb12
DTWKDATX23. Monday,27Feb2012
DTWKDATX29. Monday,27February
2012
DTYEARw.
DTYEARw.displaystheyearforthegivendatetimevalue.TheDTYEAR.formatisidenticalinresulttotheYEAR.format,but
itisusedwithdatetimevaluesinsteadofdatevalues.Itisright-justified,andwcanbefrom2to4,withadefaultwidthof4.Whenwisspecifiedas2or3,atwo-digityearisused.Thefollowingtableshowstheresultwhenthedatetimevalueis1716310050.2,whichcorrespondsto
thetime4:47:30p.m.onMay21,2014.
FormatName Result Comment
DTYEAR2. 14 Two-digityear.
DTYEAR3. 14 Two-digityearwith
aleadingspace.
DTYEAR4. 2014 Four-digityear.
DTYYQCw.
DTYYQCw.writesdatetimevaluesasa
two-orfour-digityear,followedbyacolon,andasingle-digitrepresentingthequarteroftheyear.Itisright-justified,andwcanbefrom4to6.Thedefaultwidthis4.Useawidthof6togetafour-digityear.Use4or5togetatwo-digityear.Thisgivesyouthesameresultwith
datetimevaluesthatusingtheYYQC.formatwouldyieldwithadatevalue.Thefollowingtableshowstheresultwhenthedatetimevalueis1662064659.5,whichcorrespondstothetime8:37:40p.m.onAugust31,2012.
Format
Name Result Comment
DTYYQC4. 12:3 Two-digityear.
DTYYQC5. 12:3 Leadingspace;two-digityear.
DTYYQC6. 2012:3 Four-digit
digit
year.
MDYAMPMw.MDYAMPMw.writesdatetimevaluesinthefollowingformat:mm/dd/yy(yy)hh:mmAM/PM.Therearenoleadingzeroesineitherthedateorthetimeportionsofthis
format.Itisright-justified,andwcanbefrom8to40,withadefaultwidthof19.Thefollowingtableshowstheresultwhenthedatetimevalueis1716089122,whichcorrespondstothetime3:25:22a.m.onMay19,2014.Notethatinthefollowingexampletherearetwospaces
betweenthedateandthetimebecausethehourisonlyasingledigit.
FormatName
MDYAMPM8.
MDYAMPM15.
MDYAMPM16.
MDYAMPM17. 5/19/143:25AM
MDYAMPM18. 5/19/143:25AM
MDYAMPM19. 5/19/20143:25AM
MDYAMPM21. 5/19/20143:25AM
MDYAMPM24. 5/19/20143:25AM
2.5Creating
CustomDateFormatsUsingtheVALUEStatementofPROCFORMATInadditiontothedateandtimeformatssuppliedwithSAS,youcancreateyourowncustomformatswiththeFORMATprocedure.Withdates
andtimes,youcanmodifythedefaultdisplayofanexistingSASformatorcreateyourownusingtheVALUEorthePICTUREstatement.BelowIshowhowtomodifythedefaultdisplayofanexistingSASformatusingtheVALUEstatement.
Example2.6:CreatingYourOwnDateFormatwiththeVALUEStatementinPROCFORMATAnaccesscontrolcompanywantsareportofthepeople
whosesecuritycardshaveexpiredasofJanuary1,2014,andtheyhavetheexpirationdateforeachcard.Insteadofhavingtoreadthereportanddeterminewhichdatesarepriortothecutoff,theywanttodisplayanydatepriortoJanuary1,2014,as"EXPIRED,"anddates
afterthatusingtheMMDDYY10.format.Setthevalueto"EXPIRED"fordatespriortoDecember31,2013,usingthatastheupperlimit,andthespecialvalue"LOW"asthebottomoftherange.Fortheremainingvalues,usethelowerlimitofJanuary1,2014,and
thespecialvalue"HIGH"astheupperlimit,andindicatetheSASformattobeappliedtothisrangeinbrackets❶.IfyoudonotenclosetheSASformatinbrackets,youwillgetanerrorintheFORMATprocedure.
PROCFORMAT;VALUEexp
LOW-'31DEC2013'd="Expired"'01JAN2014'd-HIGH=[MMDDYY10.];❶RUN;
PROCPRINTDATA=access;IDcard_num;VARexp_dateexp_date_raw;FORMATexp_dateexp.exp_date_rawDATE9.;RUN;
card_num exp_date
84485598 11/14/2015
16205371 11/27/2014
63656754 01/14/2014
10270040 Expired
94822015 Expired
27800904 Expired
97189418 08/14/2014
70815194 03/14/2016
50465401 Expired
43034970 09/28/2014
Example2.7:CreatingYourOwnTimeFormatwiththeVALUEStatementin
PROCFORMATInordertobeabletodrivethenextstageinaroadrace,driversmustfinishapreviousstageintenminutesorless,andtheresultsareposted.Thisexampleshowsthatyoucancustomizetimeanddatetimeformatsaswellasdateformats.
Tocustomizedatetimeformats,youwouldspecifyadatetimeformatinsteadofadateortimeformat.
PROCFORMAT;VALUEqualifyLOW-'00:10:00't=[MMSS5.];'00:10:00't<-HIGH='DidNotQualify';RUN;
PROCPRINTDATA=racers;IDname;
VARtime;FORMATtimequalify.;RUN;
name time
Bork DidNotQualify
Bova DidNotQualify
Brantley 08:31
Brickowski 08:59
Burkhart 07:10
Burroughs 08:05
Butler DidNotQualify
2.6CreatingCustomDate
FormatsUsingthePICTUREStatementofPROCFORMATTocreateyourowndateandtimeformatswiththePICTUREstatementintheFORMATprocedure,youneedtousetheDATATYPE=option.
DATATYPEcantakethevaluesof"DATE,""TIME,"or"DATETIME"toindicatethetypeofvalueyouareformatting.Youthenneedtodefineyourdisplaybyusingoneormoreofthepictureformatdatedirectivesshowninthelistbelow.Thesedirectivesarecase-sensitive.
Table2.1:PictureFormatDateDirectives
DateDirective Description
%a Locale'sabbreviatedweekdayname.Localeisdefinedby
theLOCALE=systemoption.
%A Locale'sfullweekdayname.Localeisdefinedbythe
LOCALE=systemoption.
%b Locale'sabbreviatedmonthname.Localeisdefinedbythe
LOCALE=systemoption.
%B Locale'sfullmonthname.LocaleisdefinedbytheLOCALE=
systemoption.
%d Dayofthemonthasadecimalnumber(1–31),withnoleadingzero.Putazero
betweenthepercentsignandthe"d"tohavealeadingzerointhedisplay.
%H Hour(24-
hourclock)asadecimalnumber(0–23),withnoleadingzero.Putazerobetweenthepercentsignandthe"H"
tohavealeadingzerointhedisplay.
%I Hour(12-hourclock)asadecimalnumber(1–12),withno
leadingzero.Putazerobetweenthepercentsignandthe"I"tohavealeadingzerointhedisplay.
%j Dayoftheyearasadecimalnumber(1–366),withnoleadingzero.Putazerobetweenthe
percentsignandthe"j"tohavealeadingzerointhedisplay.
%m Monthasadecimal
number(1–12),withnoleadingzero.Putazerobetweenthepercentsignandthe"m"tohavealeadingzero
inthedisplay.
%M Minuteasadecimalnumber(0–59),withnoleadingzero.Putazerobetweenthe
percentsignandthe"M"tohavealeadingzerointhedisplay.
%p Locale'sequivalentof
eithera.m.orp.m.LocaleisdefinedbytheLOCALE=systemoption.
%S Secondasa
decimalnumber(0–59),withnoleadingzero.Putazerobetweenthepercentsignandthe"S"tohavea
leadingzerointhedisplay.
%U Weeknumberoftheyear(Sundayasthefirstdayoftheweek)
asadecimalnumber(0–53),withnoleadingzero.Putazerobetweenthepercentsignandthe"U"tohavea
leadingzerointhedisplay.
%w Weekdayasadecimalnumber,where1isSundayandSaturdayis
7.
%y Yearwithoutcenturyasadecimalnumber(0–99),withnoleadingzero.Putazerobetweenthe
percentsignandthe"y"tohavealeadingzerointhedisplay.
%Y Yearwithcenturyasadecimal
number(four-digityear).
%% Thepercentcharacter(%).
Notethatifyouaregoingtousethesedirectivesinapicture
format,youwillprobablywanttoaddthefollowinglineofcodeorsomevariantinthePICTUREstatementtohandlethedisplayofmissingvalues.
.-.z="NoDateGiven"
Example2.8createsaformatsimilartotheWORDDATE.format,
exceptthatleadingzeroesareapartofthedatedisplay.Payspecialattentiontohowthepictureiscreatedinline4.Whenyouareusinganyofthedatedirectivesfromthetableabove,youmustencloseyourpicturestringinsinglequotes.Ifyouusedoublequotes,SASwill
trytointerpretthedirectivesasmacrocallsbecauseofthepercentsign(%).ThePROCFORMATstepwillexecutewithouterror,andyouwillnotseeanywarningsintheSASloguntiltheformatisused.Theformatwillnotworkifyouhaveamacrothathasthesamenameas
theformatyoucreated.
Example2.8:CreatingaPictureFormatforDatesUsingDateDirectives
1PROCFORMAT(DEFAULT=21);2PICTUREZWDATE3.-.z="NoDateGiven"4LOW-HIGH='%B%0d,%Y'(DATATYPE=DATE);5RUN;
6PROCPRINTDATA=pictest
LABEL;7VARdatedate2;8FORMATdateworddate.date2zwdate21.;9LABELdate="DateUsingWORDDATE."10date2="DateusingZWDATE.";11RUN;
Line3definesthedisplayformissingvalues.Withoutit,youwillseetheSASmissingvaluesymbol:
eitheraperiod(.)oraspecialmissingvalue.Line4givesthepictureofhowthedateistobedisplayed.Thezeroprecedingthedaydirective(%0d)causestheleadingzerotobeprintedasapartofthedate.Thelengthofthestringwiththedatedirectivesdeterminesthedefaultwidthofthe
format.Inthisexample,thedefaultwidthis10,butinordertomakesurethatallthedatesprintcorrectly,theFORMATstatementinline8setstheformatwidthto21.Whatfollowsistheresultingoutput.
Date
DateusingWORDDATE.
usingcustomPICTUREformat
ZWDATE.
July8,2012 July08,2012
April17,2014
April17,2014
October30,2013
October30,2013
. NoDateGiven
May14,2012
May14,2012
February2,2013
February02,2013
. NoDate
Given
November26,2014
November26,2014
Example2.9:UsingDateDirectiveswithTextThisexampledefinesa
formatthatwilldisplaytextalongwiththedateandtime.Itprovidesastandardizeddateandtimestampthatcanbeaddedasatitleorfootnotetoreports(forexamplesofhowtodothis,seeSections6.1.2andsection6.1.3.Inline2ofthecodebelow,theDEFAULT=optionisusedto
specifyadefaultlengthfortheformat.Withoutthatoption,thisformatwouldhaveadefaultlengthof35,whichisthenumberofcharactersbetweenthequotes.However,thereisnowaythatthedefaultwidthcansuccessfullyprinttheentiredateandtimestampforallcases,
becausefullmonthnamesarealwayslongerthantwocharacters,whichisallthattheformatdirective"%B"makesroomfor.Similarly,thefour-digityearwilltakeupmorethanthetwocharactersaccountedforbythe%Ydirective.Thecodebelowusestheformatwidthof35
toillustratewhatwouldhappenwithouttheDEFAULT=option.
Inline3,ifthedatetimestampismissing,thedatetimestampdisplaystheword"Missing."Thepictureforallothervaluesisdefinedinline4;"LOW-HIGH"specifiestherange.The
picturedescriptionbeginswithtext,andthedateisrepresentedbythefullmonthname(%B),followedbythenumericday(%dwithoutaleadingzero),acomma,andthefour-digityear(%Y).Thetimefollowstheword"at"andisrepresentedasa12-hourclocktime
withoutseconds(%I:%0M),followedbyAMorPM(%p).TheDATATYPE=optiontellstheformatthatitwillbereceivingdatetimevaluestotranslate.
SASCode1PROCFORMAT;2PICTURErptdate(DEFAULT=43)
3.-.Z='Missing'4LOW-HIGH='Generatedon%B%d,%Yat%I:%0M%p'(DATATYPE=DATETIME);5RUN;67DATA_NULL_;8rpt_date="15dec2012:22:25:00"dt;9PUT'SASdatetimevalue='rpt_date;10PUT'FormattedwithDATETIME.='rpt_datedatetime.;11PUT'Usingcustomformatatwidthof35='rpt_daterptdate35.;
12PUT'Usingcustomformatatdefaultwidthof43='rpt_daterptdate.;12RUN;
TheResultSASdatetimevalue=1671229500FormattedwithDATETIME.=15DEC12:22:25:00Usingcustomformatatwidthof35=GeneratedonDecember15,2012at1❶Usingcustomformatatdefaultwidthof43
=GeneratedonDecember15,2012at10:25PM
Asyoucansee,withoutthecorrecteddefaultwidth,theresultingoutputistruncatedat35characters.
2.7CreatingCustomFormats
UsingPROCFCMPforProcessingThereisanotherpossibilityforcustomformatsbeyondthefunctionalityoftheVALUEandPICTUREstatements.YoucanactuallyprocessdatausingPROCFCMPtowriteyourownfunctionsandthen
displaytheresultofthatfunctionasaformattedvalue.Thiscanbehelpfulforhandlingdirtydatedata(missingvaluesformonth,day,oryear)orimputingvaluesformissingdatecomponents.WhilethespecificsofPROCFCMParebeyondthescopeofthisbook,the
followingsectionwilldemonstratesomeofthecapability.
Example2.10:UsingPROCFCMPtoImputeDateswithAnnotationforImputedDates
Thisexampledefinesaformatthatwilltakeadate,andifanycomponentismissing,itwillimputeavaluefordisplayonthereportalongwithanindicatorofwhichcomponentismissing.Theadvantageofdoingthiswithaformatisthattheoriginalvalueinthedatasetis
untouched,allowingforinvestigationandlatercorrection.TheOUTLIB=option(❶)onthePROCFCMPstatementdefinesthelocationwherethecompiledfunctionistobestored.TheFUNCTIONstatement(❷)namesthefunctionanddescribestheinput
parameter(cdate;the$indicatesthatitisacharactervalue),andtheseconddollarsignindicatesthatthereturnedvaluewillalsobecharacter.
PROCFCMPCodetoCreatetheMAKEDATE()Functionfor
ImputationODSESCAPECHAR='~';
PROCFCMPOUTLIB=control.functions.dates;❶
FUNCTIONmakedate(cdate$)$;❷LENGTHdtstr$42supr$16;supr='';/*Initializesuperscriptvariable*//*assumethatdataisinMMDDYYYYform,but
check*//*Parsedatestring,getelements*/cmo=SCAN(cdate,1,'/-.:','M');cdy=SCAN(cdate,2,'/-.:','M');cyr=SCAN(cdate,3,'/-.:','M');IFcyrEQ''ORINDEX(cyr,'_')GT0ORcyrEQ'.'THENy=.;ELSE
y=INPUT(cyr,4.);
/*Testyearvalue-earliestdateis1990,cannotbeinfuture*/IFyne.and(1990LTyLTYEAR(TODAY()))THENDO;/*assumeyearisgood*/IFcmoEQ''ORINDEX(cmo,'_')GT0ORcmoEQ'.'THENm=.;ELSEm=INPUT(cmo,2.);IF1LEmLE12
THENDO;/*monthhastobebetween1and12*//*Monthisgoodchkday*/IFcdyEQ''ORINDEX(cdy,'_')GT0ORcdyEQ'.'THENd=.;ELSEd=INPUT(cdy,2.);IFdLE1ORdGT(DAY(INTNX('MONTH',MDY(m,1,y),0,'e')))THENDO;/*Dayisbadforthismonth-imputemiddleofmonth*/
d=CEIL(DAY(INTNX('MONTH',MDY(m,1,y),0,'e'))/2);supr='~{superDay}';END;END;ELSEDO;/*Monthisbad-resetmonthandday*/m=6;d=30;supr='~{superMonth}';END;/*Createthedatevalue*/
date=MDY(m,d,y);dtstr=CATT(PUT(date,mmddyy10.),supr);END;ELSEDO;/*yrisbad-flag*/dtstr='Unknown~{superY}';END;RETURN(dtstr);ENDSUB;RUN;QUIT;
Thissectionofthe
examplewillusetheMAKEDATE()functioncreatedaboveinsideofacustomformat.Itisimportanttonotethatthedatesdisplayedarecharacters;therefore,theformatisacharacterformat(asindicatedbytheleadingdollarsign[$]).TheOTHER=keywordwithnoother
formatrangesdefinesarangeofallpossiblevalues,andplacingthefunctionnameinsidethebrackets(❷)appliesthefunction.
UsingtheMAKEDATE()FunctionasaCustomFormat
PROCFORMAT;VALUE$mkdt
❶OTHER=[makedate()]❷;RUN;
DATAerrorcnt;INPUTrecno@4rptdt$10.errs;DATALINES;113/15/2013374209/08/20133302/30/2013324__/15/201315504/27/2013195605/__/201317707/08/____20806/04/0135
908/32/201341011//201361101/23/203111;;;;RUN;
TITLE1'ErrorCountsbyDate';PROCREPORTDATA=errorcntNOWDSPLIT='\';COLUMNrecnorptdtrptdt=dterrs;DEFINErecno/order'Record#';DEFINErptdt/'Original\Datefrom\ErrorLog';
DEFINEdt/'Imputed\Date'f=$mkdt36.;❶DEFINEerrs/"Errors\Reported";RUN;
ThePROCREPORTstepaboveusesthevaluethatisstoredinthedatasetandcreatesanalias(DT)forit.Weapplytheformatwecreatedtothataliased
variable(❶)toshowboththeoriginalandtheon-the-flyimputationaliasforit.
TheOutput
Record#
OriginalDatefromErrorLog
ImputedDate
1 13/15/2013
2 09/08/2013
3 02/30/2013
4 __/15/2013
5 04/27/2013
6 05/__/2013
7 07/08/____
8 06/04/013
9 08/32/2013
10 11//2013
11 01/23/2031
Itisimportanttorealizethatusingthisfunctionasaformatdoesnotcreateimputedvaluesinthedataset.Itisonlyawayto
displaythevaluesfromthedataset.
2.8ThePUT()FunctionandFormatsWhathappensifyouneedtousetheformattedvalueofadateinacharacter
stringyou'reassembling?Ifyouusethevariablethatcontainsthedatevalue,you'llgettheactualSASdatevalue,regardlessofanypermanentformatsassignedtothevariable.ThePUT()functionisusedtostoretheformattedvalueofanumeric
valueinacharactervariable.Thesyntaxis:
PUT(value,format);
valueisaconstantoravariable(eithernumericorcharacter),andformatisthenameofaSASformat.Ifyouareformattingacharactervariableorconstant,thenthe
formatyouusemustbeacharacterformat.Similarly,ifyouareformattinganumericvalue,theformatmustbeanumericformat.Example2.11willdemonstratehowtousethePUT()function.ThePUT()function❶createsthecharactervariablechar_value.Thelengthofthevariable
inthiscaseisdefinedbythewidthoftheformat,10.Ifyou'vealreadydefinedthelengthofthecharactervariablewhereyoustoretheresult,ithastobeatleastaslongastheformatwidth,oryouroutputwillbetruncated.
Example2.11:Usingthe
PUT()FunctiontoCreateaCharacterDateString
DATAsample281;numeric_value=18947;fmt_num_value=18947;char_value=PUT(numeric_value,MMDDYY10.);❶FORMATfmt_num_valuemmddyy10.;LABELnumeric_value="SASDate\Value"fmt_num_value="Formatted\SASDate\Value"char_value="CharacterDate\inString";
RUN;
ODSRTFFILE="c:\book\2ndEd\examples\putfunction.rtf";
PROCPRINTDATA=sample281NOOBSSPLIT='\';RUN;ODSRTFCLOSE;
SASDateValue
FormattedSASDateValue
18947 11/16/2011
Sowhat'sthedifference?Theformattedvaluelooksthesameasthecharacterdate,right?However,inthissimplePROCPRINT,onedifferenceisapparent.Thenumericvariableisright-justified(the
defaultfortheMMDDYY.formatisright-justified),whilethecharactervariableisleft-justified(defaultforcharactervariables).Ifyoulookatthelabels,youwillseethatthelabelsalsoreflectthedefaultjustification.Thelabelsforthenumericvariablesareright-
justified,andtheoneforthecharactervariableisleft-justified.
WhywouldyouneedtouseacharacterrepresentationofaSASdate?Ifyouareprintingadateinsideofatextstring(e.g.,inatitleorfootnote,orinthetextofaformletter),youwillneedto
createacharactervariablewiththedate.Example2.12putstheRPTDATE.formatcreatedinSection2.6.1oneachpageofareportasafootnote.
Example2.12:UsingaCharacterDateStringinaFootnote
PROCFORMAT;PICTURErptdate(DEFAULT=43)
.-.Z='Missing'LOW-HIGH='Generatedon%B%d,%Yat%I:%0m%p'(DATATYPE=DATETIME);RUN;
Inordertodothis,wewillhavetocreateamacrovariabletostorethevaluesothatitcanbeusedinaFOOTNOTEstatement.ThemethodchosenhereisviaaDATAstep
andtheCALLSYMPUTXstatement.CALLSYMPUTXtrimsanytrailingspacesasopposedtoCALLSYMPUT.Thereareotherwaystocreatethemacrovariable&RPTDTMaswell(seeSection6.1.3).
DATA_NULL_;CALL
SYMPUTX('RPTDTM',PUT(DATETIME(),RPTDATE.));RUN;FOOTNOTE"&RPTDTM";
Chapter3:ConvertingDatesandTimesintoSASDate,Time,andDatetime
Values
3.1AvoidingtheTwo-DigitYearTrap3.2UsingInformats3.3TheINFORMATStatement
3.4ListingandDiscussionofInformats
InChapter2,IdiscussedtranslatingSASdatestothewayweexpressthem.Howcanwedothereverse?Afterall,ifyouhaveadate,time,ordateandtimethatyouneedto
storeormanipulate,itwon'tberepresentedasaSASdate,time,ordatetimevalue(unlessitcomesfromanotherSASdataset).Thetranslationfromcommondateand/ortimeterminologytoSASisalmostaseasyasgoingtheotherway,anditisdoneinoneoftwoways:Thefirst,
discussedinSection1.4,usesdate,time,anddatetimeliterals.Whilethisworksforasmallnumberofthesevaluesthatareknownatthetimeyouwritetheprogram,howdoyoudealwithmultipledates,orthosethatareknownonlyatruntime?Byusinginformatstoprocess
them.
3.1AvoidingtheTwo-DigitYearTrapFirst,itisalwaysgoodpracticetousefour-digityearsinyourdatevalues.Ifthisisnotpossible,SASwill
handledateswithtwo-digityearswithoutanyproblems,butthissituationiswhereyou,theuser,shouldbeconcernedwiththeYEARCUTOFF=systemoption.Anytimethatyoutranslateadateordatetimefromaneverydayrepresentationusingtwo-digityears(for
example,05/16/89)toitsSASvalue,theYEARCUTOFF=systemoptionwillaffecttheresultingSASvalue.TheYEARCUTOFF=systemoptionwilldefinethebeginningofthe100-yearperiodforthosetwo-digityears.InSAS9.4,theSASdefaultvalueforthisoptionis1926,
definingarangeof1926through2025.Therefore,two-digityearsintherangefrom26through99willbeassignedtotheyears1926–1999,whileyearvaluesfrom00through25willbesettotheyears2000–2025.ThisruleappliestoeverythingthathastobetranslatedintoaSAS
dateordatetimevalueandwherethereareonlytwodigitsrepresentingtheyear.ThismeansthattheYEARCUTOFF=optionappliestoexternaldatabeingprocessedwiththeINPUTstatement,anydateordatetimeliterals,aswellasanyfunctions(suchasINPUT())wherethe
inputstringonlyhastwodigitsrepresentingtheyear.TheexamplebelowshowshowdateanddatetimeliteralsareaffectedbytheYEARCUTOFF=systemoption.ItdisplaystheactualSASdateordatetimevaluerepresentedbytheliteralalongwithitsformattedvalue.
Example3.1:EffectsoftheYEARCUTOFF=SystemOptiononDateandDatetimeLiteralsOPTIONSYEARCUTOFF=1920
SASDateLiteral
a1 '23MAR2005'd
a2 '23MAR1905'd
a3 '23MAR05'd
a4 '19AUG1959:14:45:00'dt
a5 '19AUG2059:14:45:00'dt
a6 '19AUG59:14:45:00'dt
Thevariablesa3anda6aredateanddatetimeconstants,respectively,withtwo-digityearsasapartoftheconstant.Whiletheliteralswithfour-digityearsarestoredastheirproperSASdates,
a3isinthe21stcentury,buta6issetinthe20thcentury.The100-yearrangeis1920–2019.Therefore,'05'fallsintherange00–19andisassignedtotheyear2005,and'59'fallsintherange20–99andisassignedtotheyear1959.Forthefollowingexample,let'susethesamedate
anddatetimeliterals,butchangethevalueoftheYEARCUTOFF=option.
OPTIONSYEARCUTOFF=1905
SASDateLiteral
a1 '23MAR2005'd
a2 '23MAR1905'd
a3 '23MAR05'd
a4 '19AUG1959:14:45:00'dt
a5 '19AUG2059:14:45:00'dt
a6 '19AUG59:14:45:00'dt
Now,a3hasmovedtothe20thcentury.Theliteralswithfour-digit
yearsremainstoredastheirproperSASdatesanda6remainsinthe20thcentury,butwehavemovedthe100-yearrangetostartin1905.Therefore,therangeisnow1905–2004,and'05'fallsinthe05–99range,soitisassignedto1905.
Thesamethingwill
happenwhenyouuseaninformattotranslateadateordatetimestringwherethereareonlytwodigitsrepresentingtheyear.
3.2UsingInformatsFormatstakevalues
anddisplaytheminaspecificfashion,whileinformatstakeaseriesofalphanumericcharactersandtranslatethemintoasinglevalue.Datesandtimesarethebestexampleofapplyinginformats,sinceSASdatevaluesarenotnormallyhowthemajorityoftheplanetexpressesdates.
Adatesuchas11/24/05,or24-05-2002containsnon-numericcharacters,sotheywouldhavetobereadascharactervalues,whichisquiteadistancefromnumericSASdatevalues.Aswithformats,youcancreate(andstoreforfutureuse)yourowninformatsifoneisnot
availablewithinSAStofityourneeds.TherearefewerSAS-suppliedinformatsthanformats,soyoushouldbecarefultoonlyusetheinformatslistedinthischaptertotranslateyourdateanddatetimestrings,andnottheformatsfromChapter2.
JustasyoucanusetheFORMATstatementtoapplyaformattoavariable,youcanusetheINFORMATstatementtoapplyaninformattoavariableinaprocedureoraDATAstep.However,themostcommonuseofinformatsiswiththeINPUTstatementinaDATAstep,asdataare
beingreadin,orwiththeINPUT()functiontotranslatecharacterdatathatarealreadyindatasets.
Youspecifyaninformatbygivingtheinformatname,followedbyanoptionalwidthspecificationandaperiod(.).Informatsarelikeformatsinthat
eachinformathasadefaultwidththatSASwilluseifnoneisspecified.
3.3TheINFORMATStatementTheINFORMATstatementisanalogoustotheFORMAT
statement.YouusetheINFORMATstatementtoassociateaninformatwithavariableinaSASdataset.Youcanalsoremoveaninformatthathasbeenpermanentlyassociatedwiththevariablebyleavingtheinformatnameblank.Youmightalsousethe
INFORMATstatementtoassociateaninformatwithavariableforthedurationoftheprocedure(whichmightbeusefulincertainproceduressuchastheFSEDITprocedure).
INFORMATdate1mmddyy10.;
Thestatementabovesaysthatanytimeacharacterstringisreadintothevariabledate1,itwillbetranslatedintoaSASdatevalueusingtheinformatMMDDYY10(detailedbelow).IfthecharacterstringbeingprocessedisnotinanMMsDDsYY(YY)(sstandsforaseparator),
youwillgetamissingvaluestoredindate1andanerrormessageintheSASlog.
Justaswithformats,youcanremoveinformatsthathavebeenpermanentlyassociatedwithavariablebyusingthevariablenameintheINFORMATstatement
withoutaninformat,asisshownbelow.
INFORMATtime3;
Thisstatementwillremoveanyinformatthathasbeenpermanentlyassociatedwiththevariabletime3.
3.3.1Using
InformatswiththeINPUTStatementThebasicsyntaxofanINPUTstatementwithaninformatisasfollows:
INPUT@1date1mmddyy10.;
First,youwillusually
specifyastartingcolumn.Thedefaultstartingcolumnis1,butyoucanspecifythestartingcolumnwiththe@sign,followedbythecolumnnumber.Ifyoudonot,thestartingcolumnwillbesettothecurrentlocationoftheinputpointer.Youshouldalsospecifyawidthfortheinformat
toindicatehowmanycharactersaretoberead.TheaboveINPUTstatementwillreadthefirsttencharactersinaline,startingatthefirstcharacterinadataline,andSASwillexpectittolooklikemmsdds(yy)yy,wheremmisthemonthfrom01to12,srepresentsaseparatorcharacter,dd
isadayfrom01to31,and(yy)yyisatwo-orfour-digityear.Thefollowingexampledemonstratesthattheseparatorcharacterdoesnothavetobethesameoneveryline,andthefielddoesnothavetobeexactlytencharacterslong.
Example3.2:INPUT
Statement1.DATAinformats_are_smart;2.INPUT@1date1:MMDDYY10.;3.unformatted_date=date1;4.DATALINES;5.10/17/20146.05-04-597.3-1-19408.RUN;9.PROCPRINT;10.FORMATdateworddatx.;
11.RUN;
TheResult
Obs date1 unformatted_date
1 17October2014
2 4May1959
3 1March1940
Asyoucansee,thecharactersineachlineoftheDATALINESstatementwereconvertedtoaSASdatevalue.Thelengthoftheinformatmustbelongenoughtoreadallof
thecharactersinthedatestring.Intheexample,thereareamaximumof10charactersinthedatestring.Therefore,thewidthoftheinformatisspecifiedas10.Theotherimportantthingtonoteistheuseofthecolon(:,line2,inbold)modifierprecedingtheinformat
name.Itisbestpracticetousethecolonmodifierwithanyinformat,notjustthoserelatingtodatesandtimes,whenyouaredealingwithvaryinglengthfields.Thecolonmodifierensuresthatitdoesn'tmatterifthelengthsofthecharacterstringsrepresentingdateinthedataareless
thanthewidthspecifiedfortheinformat.
Ifthecharactersreaddonotmatchthatlayout(forexample,June26,2014,whentheinformatspecifiedisMMDDYY.)oriftheinformatwouldyieldanimpossiblevalue(forexample,February
31),SASwillsetthevalueofthevariabledate1tomissingandsetthesystemvariable_ERROR_to1.Ingeneral,youshouldknowthelayoutofthecharactersbeforeselectinganinformat.Beginningwithversion9ofSAS,ifyoudonotknowthelayoutofthedatesaheadoftime,
theANYDTfamilyofinformats(seeSection3.4.4)aredesignedtosolvethisproblem.
3.3.2InformatswiththeINPUT()FunctionTheINPUT()functionistheparalleltothe
PUT()function,anditstoresanumericorcharactervalueasanumericorcharactervariable.Thetypeoftheresultdependsonthetypeoftheinformatthatisused.Acharacterinformat(onethatbeginswitha$)willreturnacharactervalue.Allinformatsusedwithdates,times,
anddatetimesarenumeric.Therefore,thevariablereturnedisnumeric.Thesyntaxisgivenbelow.
INPUT(character-value,informat-name);
IfyouwanttodefinetheinformatthatistobeappliedduringaSASjob(atruntime),
youwillneedtousetheINPUTN(character-value,informat-name)function(orINPUTC(),ifyouwanttoproduceacharactervariable)instead.informat-namerepresentsacharactervariableorcharacterconstantthatcontainsaninformatname,whiletheINPUT()functionneedsan
actualinformatname.Makesurethatyouhavedefinedthewidthoftheinformatsothatitislongenoughtocaptureallthecharactersintheentirecharactervariable.ThefollowingexamplesillustratetheuseoftheINPUT()andINPUTN()functions:
Example3.3:INPUT()Function
DATA_NULL_;datestr="15-NOV-2013";sasdate=INPUT(a,date11.);PUTsasdate=;RUN
TheINPUT()functiontranslatedthedateinthecharactervariabledatestrintoitsequivalentSASdate
value,19677,andstoreditinthenumericvariablesasdate.Thedate11.informataccountsforthelengthofthecharactervariable.
Example3.4:INPUTN()Function
DATA_NULL_;datestr="15-NOV-2013";inf="DATE11.";sasdate=INPUTN(a,inf);
PUTsasdate=;RUN;
TheINPUTN()functionusedthevalueofthecharactervalueinf(DATE11.)astheinformattouseintranslatingthedateinthecharactervariabledatestrintoitsequivalentSASdatevalue,19677.
3.3.3WhentheInformatDoesNotMatchtheDataBeingReadInformats,likeformats,areseparatedintoclassesaccordingtothetypeofdatathatarebeingread.Inmostcases,ifyouusethewronginformatforthe
datatype,informatswillreturnanerror(settheSASautomaticvariable_ERROR_to1),andthevalueofthevariablebeingreadwillbesettomissing.
Thisbehaviordiffersfromdate,time,anddatetimeformatsinthatifyouusethewrongtypeofformat
todisplayavalue(forexample,ifyouuseadateformattodisplayatimevalue),noerrorwilloccur,andatworst,youwillgetawarningintheSASlog.However,incorrectlyspecifyingaformatwillmostlikelycausethedisplaytobeincorrect.Example3.5showswhathappenswhen
youtrytouseaninformatthatdoesnotmatchthecharacterstringthatyouaretryingtoprocess.
Example3.5:UsingtheWrongInformat
DATAbad_informat;INPUT@1date:datetime18.;DATALINES;11-06-19888-25-2004
4-24-2005;;;;RUN;
TheLog1DATAbad_informat;2INPUT@1date:datetime18.;3DATALINES;
NOTE:Invaliddatafordateinline41-18.RULE:----+----1----+----2----+----3----+----4----+----5----+----6----+
411-06-1988date=._ERROR_=1_N_=1NOTE:Invaliddatafordateinline51-18.58-25-2004date=._ERROR_=1_N_=2NOTE:Invaliddatafordateinline61-18.64-24-2005date=._ERROR_=1_N_=3NOTE:ThedatasetWORK.BAD_INFORMAThas3observationsand1variables.NOTE:DATAstatementused(Totalprocesstime):
realtime0.53secondscputime0.03seconds7;;;;8RUN;
TheResultingSASDataset
Obs date
1 .
2 .
3 .
Asyoucanseeintheaboveexample,usingtheDATETIME.informattoprocessaseriesofcharacterstringsthatdonotrepresentdatetimesproducesanoteinthelog.Italsosetstheautomaticvariable
_ERROR_to1foreachrecordwhereitencounteredamismatchbetweentheinformatspecifiedandthedatathatitattemptedtoread.TheendresultisthatthevalueofthedatevariableinyouroutputdatasetismissingbecauseSASwasnotabletoprocessthe
charactersusingthespecifiedinformat.Remembertoalwayscheckyourlogandyourdatasetafterreadingatextfile.
3.4ListingandDiscussionofInformats
Eachdiscussionofaninformatinthissectionwillprovideanexplanationoftheinformat,itswidthspecification,andthetextitisdesignedtoprocess.Eachsubsectionisaccompaniedbyatablethatgivesexamplesofthetextthatistobeprocessed,alongwith
theinformat(anditswidthspecification)andtheresultingSASdate,time,ordatetimevalue.SAScontinuestodevelopformatsandinformats,soitisalwaysagoodideatochecktheonlinedocumentationatsupport.sas.com.
3.4.1DateInformats
DATEw.DATEw.readsdatesintheformddmonyy(yy),whereddrepresentsthedayofthemonth,monisthethree-lettermonthabbreviation,andyy(yy)isthetwo-orfour-digityear.The
defaultvalueofwis7,butyoushouldspecify9ifyouarereadingfour-digityears.dd,mon,andyy(yy)canbeseparatedbyblanksorspecialcharacters.Ifyouseparatethem,youmustaccountfortheblanks(orspecialcharacters)inthewidthspecification.Ifyouhaveblanksafter
themonthandtheday,thenyouneedtohaveawidthof9fortwo-digityearsor11forfour-digityears.Iftheleadingzeroforddismissing,ithasnoeffectonthevalue.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorresponds
tothetextshownineachline.
CharactersRead Informat
20sep15 DATE7.
4feb2014 DATE11.
07-may-1960
DATE11.
DDMMYYw.
DDMMYYw.readsdatesoftheformddmmyy(yy),whereddrepresentsthedayofthemonth,mmrepresentsthenumberofthemonth,andyy(yy)isthetwo-orfour-digityear.Thedefaultvalueofwis6,butyoushouldspecify8ifyouarereadingfour-digityears.dd,
mm,andyy(yy)canbeseparatedbyblanksorspecialcharacters.Ifyouseparatethem,youmustaccountfortheseparatingcharactersinthewidthspecification.Ifyouhaveblanksafterthemonthandtheday,thenyouneedtohaveawidthof8fortwo-digityearsor10forfour-digityears.SAS
willdoitsbesttodecipherthestringifnoseparatorsareused,butsomedatescannotbeprocessed—forexample,2112008.Withoutplace-holdingzerosorseparators,thereisnowaytoknowwhetherthedateis21January2008or2November2008.Thefollowingtablegives
examplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead Informat
140390 DDMMYY6.
06/09/05 DDMMYY8.
22-04-2003
DDMMYY10.
JULIANw.
JULIANw.translatesaJuliandateintheformyy(yy)ddd,withthetwo-orfour-digityearprecedingthezero-filleddayoftheyear.Itisright-justified.wcanbefrom5to32,andthedefaultis5.Ifyou
specify5,theyearportionoftheJuliandateistwodigitslong.Ifyouspecify7ormore,theyearportionisfourdigitslong.Zerosmustfillthespacebetweentheyearanddayvalues:Forexample,thefifthdayoftheyearmustbegivenas"005."Anydateprecedingtheyear
1582ontheGregoriancalendarcannotbereadasaJulianvalue.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead Informat
09284 JULIAN5.
2014005 JULIAN7.
2012168 JULIAN7.
MMDDYYw.MMDDYYw.readsdatesoftheformmmddyy(yy),wheremmrepresentsthenumberofthemonth,dd
representsthedayofthemonth,andyy(yy)isthetwo-orfour-digityear.Thedefaultvalueofwis6,butyoushouldspecify8ifyouarereadingfour-digityears.dd,mm,andyy(yy)canbeseparatedbyblanksorspecialcharacters.Ifyouseparatethem,youmustaccountforthe
blanksinthewidthspecification.Ifyouhaveblanksafterthemonthandtheday,thenyouneedtohaveawidthof8fortwo-digityearsor10forfour-digityears.SASwilldoitsbesttodecipherthestringifnoseparatorsareused,butsomedatescannotbeprocessed—for
example,1272003.Withoutplace-holdingzerosorseparators,thereisnowaytoknowwhetherthedateisJanuary27,2003,orDecember7,2003.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownin
eachline.
CharactersRead Informat
041798 MMDDYY6.
1/15/2013 MMDDYY10.
08282015 MMDDYY10.
MONYYw.
MONYYw.readsdates
oftheformmonyy(yy),wheremonisthethree-lettermonthabbreviation,andyy(yy)isthetwo-orfour-digityear.UsingthisinformatwillsettheSASdatevaluethatcorrespondstothefirstdayofthemonth.Thedefaultvalueofwis5,butyoushouldspecify7ifyouarereading
four-digityears.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
Characters
Read Informat
JAN15 MONYY5.
dec1920 MONYY7.
aug2020 MONYY7.
PDJULG4.
PDJULG4.readsapackedJuliandateinhexadecimalformatforIBMcomputers.Thewidthspecificationisalways4,becausethe
Juliandateisparsedasfollows:thefour-digitGregorianyeariswritteninthefirsttwobytes,andthethree-digitintegerthatrepresentsthedayoftheyearisinthenextone-and-a-halfbytes.Thelasthalf-bytecontainsallbinary1s,whichindicatesthevalueispositive.There
isnoexamplegivenforthisinformatbecausepacked-decimalJuliandatesyieldnonprintablecharacters.
PDJULIw.PDJULIw.alsoreadsapackedJuliandateinhexadecimalformatforIBMcomputers.It
differsfromthePDJULG.informatinthatitexpectsthetwodigitsofthecenturyinthefirstbyte,followedbytwodigitsoftheyearinthesecondbyte.Thenextone-and-a-half-bytesstorethethree-digitintegerthatcorrespondstothedayoftheyear,whilethelasthalf-byteisfilled
withhexadecimal1s,representingapositivenumber.Thecenturyandyeararecalculatedbysubtracting1900fromthefour-digitGregorianyear.Onceagain,thereisnoexample,sincepacked-decimalJuliandatesyieldnonprintablecharacters.
YYMMDDw.YYMMDDw.isusedtoreaddatesoftheformyy(yy)mmdd,whereyy(yy)isthetwo-orfour-digityear,mmrepresentsthenumberofthemonth,andddrepresentsthedayofthemonth.Thedefaultvalueofwis6,butyoushouldspecify8ifyou
arereadingfour-digityears.yy(yy),mm,andddcanbeseparatedbyblanksorspecialcharacters.Ifyouseparatethem,youmustaccountfortheseparatingcharactersinthewidthspecification.Ifyouhaveblanksafterthemonthandtheday,thenyouneedtohaveawidthof8fortwo-
digityearsor10forfour-digityears.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead Informat
441205 YYMMDD6.
20150517 YYMMDD8.
2014-07- YYMMDD10.
2014-07-
06
YYMMDD10.
YYMMNw.
YYMMNw.readsdatesoftheformyy(yy)mm,whereyy(yy)isthetwo-orfour-digityear,andmmrepresentsthenumberofthemonth.
Thedayisautomaticallysetto1.Thedefaultvalueofwis4,butyoushouldspecify6ifyouarereadingfour-digityears.TheNintheinformatnameisnecessary.Yourdatamustnothaveanyseparatingcharactersbetweenthemonthandtheyear.Thisinformat
willproduceadatevaluethatisequaltothefirstdayofthemonthgiven.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.Notethatline2ofthistabledemonstrateswhat
happensifyoutrytoreadadatewithatwo-digityearusingthewidthof6.Inthiscase,SASistranslatingthefourdigitsastheyear,sothemonthvalueisconsideredtobemissing.
CharactersRead Informat
1 9905 YYMMN4.
2 9905 YYMMN6.
3 201403 YYMMN6.
4 201610 YYMMN6.
YYQw.YYQw.readsdatesoftheformyy(yy)Qq,whereyy(yy)isthetwo-orfour-digityearfollowedbytheletterQ
andqisanumberfrom1to4,indicatingthequarteroftheyear.Thedatevalueproducedbythisinformatwillcorrespondtothefirstdayofthegivenquarter.Use6forwifyouarereadingfour-digityears,or4ifyouarereadingtwo-digityears.Thedefaultwis6.Thefollowingtable
givesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead Informat
ResultingSASDateValue
14Q1 YYQ4.
2010Q3 YYQ6.
2015Q2 YYQ6.
2013Q4 YYQ6.
YYMMDDw.YYMMDDw.isusedtoreaddatesoftheformyy(yy)mmdd,whereyy(yy)isthetwo-orfour-digityear,mm
representsthenumberofthemonth,andddrepresentsthedayofthemonth.Thedefaultvalueofwis6,butyoushouldspecify8ifyouarereadingfour-digityears.yy(yy),mm,andddcanbeseparatedbyblanksorspecialcharacters.Ifyouseparatethem,youmustaccountforthe
separatingcharactersinthewidthspecification.Ifyouhaveblanksafterthemonthandtheday,thenyouneedtohaveawidthof8fortwo-digityearsor10forfour-digityears.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorresponds
tothetextshownineachline.
CharactersRead Informat
441205 YYMMDD6.
20150517 YYMMDD8.
2014-07-06
YYMMDD10.
YYMMNw.YYMMNw.readsdates
oftheformyy(yy)mm,whereyy(yy)isthetwo-orfour-digityear,andmmrepresentsthenumberofthemonth.Thedayisautomaticallysetto1.Thedefaultvalueofwis4,butyoushouldspecify6ifyouarereadingfour-digityears.TheNintheinformatnameis
necessary.Yourdatamustnothaveanyseparatingcharactersbetweenthemonthandtheyear.Thisinformatwillproduceadatevaluethatisequaltothefirstdayofthemonthgiven.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdate
valuethatcorrespondstothetextshownineachline.Notethatline2ofthistabledemonstrateswhathappensifyoutrytoreadadatewithatwo-digityearusingthewidthof6.Inthiscase,SASistranslatingthefourdigitsastheyear,sothemonthvalueisconsideredtobe
missing.
CharactersRead Informat
1 9905 YYMMN4.
2 9905 YYMMN6.
3 201403 YYMMN6.
4 201610 YYMMN6.
YYQw.
YYQw.readsdatesoftheformyy(yy)Qq,whereyy(yy)isthetwo-orfour-digityearfollowedbytheletterQandqisanumberfrom1to4,indicatingthequarteroftheyear.Thedatevalueproducedbythisinformatwillcorrespondtothefirstdayofthegivenquarter.Use6forwif
youarereadingfour-digityears,or4ifyouarereadingtwo-digityears.Thedefaultwis6.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead Informat
ResultingSASDateValue
14Q1 YYQ4.
2010Q3 YYQ6.
2015Q2 YYQ6.
2013Q4 YYQ6.
TheWEEKInformats
TheWEEKinformatsreaddatesintheISO-standardWEEKformat.TherearethreealgorithmsusedtocalculatetheWEEKvaluefromagivendate.TheUalgorithmcalculatesweeksbasedonSundaybeingthefirstdayoftheweekwithoutanyotherrestriction.TheV
algorithmdefinesthefirstweekoftheyearascontainingbothJanuary4andthefirstThursdayoftheyear.Therefore,ifthefirstMondayoftheyearfallsonJanuary2,3,or4,theprecedingdaysofthecalendaryearareconsideredtobeapartofweek53ofthepreviouscalendaryear.
Itisalsopossibleforcalendardaysattheendofayeartobeconsideredasbeinginthefirstweekofthenextcalendaryear.Finally,theWalgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweekwithoutanyotherrestriction.
TheWEEKalgorithmscalculatedatesdifferently,soitiscriticalthatyouusethecorrectalgorithmfortheweekvaluethatyouareconverting.Thismeansthatyouneedtoknowwhichalgorithmwasusedtocreatetheweekvaluebeforeyoutrytoconvertit.Ifyouusea
differentweekalgorithmfromtheonethatwasusedtocreatetheweekvalue,youwillgetthewrongactualdate.Example3.6demonstratesthis.
Example3.6:TheDifferencebetweentheVariousWEEKAlgorithms(U,V,W)
Date
Weekvalue
FormattedwithWEEKDATEUAlgorithm
1 W12 Sunday,March23,2014
2 13W45 Sunday,
November10,2013
3 15W5303 Tuesday,January5,2016
4 2014W2104 Wednesday,May28,2014
5 2015-W01-02
Monday,January5,2015
Example3.6demonstratesthedifferencesthatexistnotonlyintheresultingdatebetweenthealgorithms,butalsointhedayoftheweek,
whichdependsonwhetherthealgorithmusesSundayorMondayasthefirstdayoftheweek.Rows3and5highlightthedifferencesinthewaythefirstandlastweekofthecalendaryeararehandledbythedifferentalgorithms.Asyoucansee,ifyouusethewrongalgorithm,
notonlycanyouendupwithanunintendeddate,buttheresultingdatemightnotevenbeinthesameyear.
WEEKUw.WEEKUw.isnewasofSASversion9.3.ItisusedtotranslateweekvaluesintoSASdatesusingtheUalgorithm.
TheUalgorithmcalculatesweeksbasedonSundaybeingthefirstdayoftheweek,andtheweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroifnecessary.Weekvaluesaredatesintheformyyyy-Wnn-dd,whereyyyyistheoptionalyear(canbe
twoorfourdigits).Wistheletter"W"for"Week";nnistheweeknumberrangingfrom0to53;andddistheoptionaldayoftheweek.Thedashesareoptionalseparators,buttheyaretheonlyseparatorsthatcanbeusedinISO8601weekvaluesandareusedbetweentheyear,the
weeknumber,andtheday(ifpresent).Thewidthspecification,w,canrangefrom3to200andtellsSASwhattoexpectfromthecharacterstringbeingprocessedaccordingtothefollowingtable.
Width(w)
PatternExpected Example
3–4 Wnn W08
5–6 yyWnn 14W08
7–8 yyWnndd 14W0803
9–10 yyyyWnndd 2014W0803
11–200
yyyy-Wnn-dd
2014-W08-03
Specifyinganyvalue
greaterthan11willhavenoeffectonthedatereturned,althoughtheimpliedcursorplacementcancauseanINPUTstatement(notfunction)toyieldunexpectedresults.
Characters
Read Informat
W12 WEEKU3.
14W40 WEEKU5.
15W2801 WEEKU7.
2014W3304 WEEKU9.
2015-W06-02
WEEKU11.
WEEKVw.WEEKVw.isavailableasofSASversion9.3.ItisusedtotranslateweekvaluesintoSASdatesusingtheValgorithm.TheValgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweek,andtheweeknumberis
displayedasatwo-digitnumberfrom0to53,withaleadingzeroifnecessary.ThisalgorithmdefinesthefirstweekoftheyearascontainingbothJanuary4andthefirstThursdayoftheyear.Therefore,ifthefirstMondayoftheyearfallsonJanuary2,3,or4,theprecedingdays
ofthecalendaryearareconsideredtobeapartofweek53ofthepreviouscalendaryear.Weekvaluesaredatesintheformyyyy-Wnn-dd,whereyyyyistheoptionalyear(canbetwoorfourdigits).Wistheletter"W"for"Week";nnistheweeknumberrangingfrom0to53;andddisthe
optionaldayoftheweek.Thedashesareoptionalseparators,buttheyaretheonlyseparatorsthatcanbeusedinISO8601weekvaluesandareusedbetweentheyear,theweeknumber,andtheday(ifpresent).Thewidthspecification,w,canrangefrom3to200andtellsSASwhat
toexpectfromthecharacterstringbeingprocessedaccordingtothefollowingtable:
Width(w)
PatternExpected Example
3–4 Wnn W08
5–6 yyWnn 14W08
7–8 yyWnndd 14W0803
9–10 yyyyWnndd 2014W0803
11–200
yyyy-Wnn-dd
2014-W08-03
Specifyinganyvaluegreaterthan11willhavenoeffectonthedatereturned,althoughtheimpliedcursorplacementcancausean
INPUTstatement(notfunction)toyieldunexpectedresults.
CharactersRead Informat
W12 WEEKV3.
14W40 WEEKV5.
15W2801 WEEKV7.
2014W3304 WEEKV9.
2015-W06-02
WEEKV11.
WEEKWw.WEEKWw.isavailableasofSASversion9.3.Itisusedtotranslate
weekvaluesintoSASdatesusingtheWalgorithm.TheWalgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweekwithoutanyotherrestriction.Theweeknumberisdisplayedasatwo-digitnumberfrom0to53,withaleadingzeroif
necessary.Weekvaluesaredatesintheformyyyy-Wnn-dd,whereyyyyistheoptionalyear(canbetwoorfourdigits).Wistheletter"W"for"Week";nnistheweeknumberrangingfrom0to53;andddistheoptionaldayoftheweek.Thedashesareoptionalseparators,buttheyare
theonlyseparatorsthatcanbeusedinISO8601weekvaluesandareusedbetweentheyear,theweeknumber,andtheday(ifpresent).Thewidthspecification,w,canrangefrom3to200andtellsSASwhattoexpectfromthecharacterstringbeingprocessedaccordingto
thefollowingtable:
Width(w)
PatternExpected Example
3–4 Wnn W08
5–6 yyWnn 14W08
7–8 yyWnndd 14W0803
9–10 yyyyWnndd 2014W0803
11–200
yyyy-Wnn-dd
2014-W08-03
Specifyinganyvaluegreaterthan11willhavenoeffectonthedatereturned,althoughtheimpliedcursorplacementcancauseanINPUTstatement(notfunction)toyieldunexpectedresults.
CharactersRead Informat
W12 WEEKW3.
14W40 WEEKW5.
15W2801 WEEKW7.
2014W3304 WEEKW9.
2015-W06- WEEKW11.
02
3.4.2TimeInformats
HHMMSSw.HHMMSSw.isavailableasofSASversion9.3.Itwillreadtimevaluesintheformhh:mm:ssor
hhmmss,wherehhishours,mmisminutes,andssisseconds,withanoptionalseparator.Thisinformatwillignorefractionalseconds.Thedefaultwidthforthisformatis8,butwcanrangefrom1to20.Whentherearesixdigitsinthestringbeingread,thefirsttwodigitswill
betranslatedintohours,thesecondtwointominutes,andthelasttwointoseconds.
CharactersRead Informat
143500 HHMMSS6.
971406 HHMMSS6.
000339 HHMMSS6.
081525 HHMMSS6.
Theparsingandinterpretationperformedbythisinformatchangesiftherearefewerthansixdigitsinthestring
beingreadandisbasedonthefollowingrules:Ifthereisanoddnumberofdigitsinthestringbeingread,SASwilladdazerotothebeginningofthestring,andthefirsttwodigitswillthenbetranslatedashours.SASwillthenaddzerostotheendofthestringuntilithassixdigitsandcanbe
translatedashours,minutes,seconds.
CharactersRead Informat
1 HHMMSS6.
11 HHMMSS6.
112 HHMMSS6.
1127 HHMMSS6.
11274 HHMMSS6.
112745 HHMMSS6.
Whentherearemorethansixdigitsinthestringthatisbeingread,SASwillparsethestringfromrighttoleft.Theassumptionisthatsincesecondsandminutesnormallycycleat60,theywillonlyeverrequiretwodigits.Itwilltranslatethelast
fourdigitsofthestringasminutesandseconds.Alldigitstotheleftofthefinalfourdigitswillbetranslatedintohours.
CharactersRead Informat
172154 HHMMSS10.
1721543 HHMMSS10.
17215430 HHMMSS10.
172154305 HHMMSS10.
1721543058 HHMMSS10.
MSEC8.
MSEC8.readsIBMmainframetimevaluesaccuratetothenearestmillisecond.Thewidthis8becausetheOSTIMEmacroandSTCKsysteminstructionsstoretheirtimevaluesin8bytes.
PDTIME4.PDTIME4.convertspacked-decimaltimevaluescontainedinSMFandRMFrecordsproducedbyIBMmainframesystemstoSAStimevalues.Thewidthisshownas4becauseSMFandRMFrecordsare4byteslong.Whilethe
informatRMFSTAMP8.alsoreadspackeddecimalRMFrecords,RMFSTAMP8.readsboththe4bytesoftimeand4bytesofdateinformationcontainedintheRMFrecordandcreatesaSASdatetimevaluefromit.PDTIME4.onlyreadsthe4bytesoftimeinformationfrom
anRMFrecordandcreatesaSAStimevalue.
RMFDUR4.RMFDUR4.convertsIBMmainframeRMFdurationrecordsintoSAStimevalues.Thewidthisshownas4becauseRMFrecordsare4-byte-longpacked
hexadecimalrecords.
STIMERw.STIMERw.readstimesproducedbytheSTIMERSystemoptionintheSASlog.Thisinformathasnodefaultwidth.Itreadstimesandinterpretsthembasedoncolonsanddecimalpoints.Ifthere
isonecolon,thefirsttwodigitsareminutesandthelasttwoareseconds.Iftherearetwocolons,thedigitsprecedingthefirstcolonarehours,thenextsetoftwodigitsisminutes,andthelasttwoareseconds.Ifthereisadecimalpoint,thevaluefollowingthedecimal
pointistranslatedasadecimalfractionofseconds.Itcanreadtimevaluesinthefollowingformats,wherehhcorrespondstohours,mmcorrespondstominutes,sscorrespondstoseconds,andffcorrespondstodecimalfractionsofseconds.
ssss.ffmm:ssmm:ss.ffhh:mm:sshh:mm:ss.ff
CharactersRead Informat
33 STIMER2.
51.60 STIMER5.
14:05 STIMER5.
3:11.03 STIMER7.
1:19:21 STIMER7.
1:46:17.74 STIMER11.
TIMEw.
TIMEw.willreadtimesintheformhh:mm:ss.ff,wherehhindicatesthehours,mmisminutes,andssisthenumberofseconds.Theymustbeseparatedbyaspecialcharacter,suchasacolon(:),period(.),or
hyphen(-).ffindicatesdecimalfractionsofsecondsandmustbeseparatedfromthesecondsbyadecimalpoint(.).Bothsecondsandtheirdecimalfractionsareassumedtobezeroiftheyarenotpresent.Thisinformatcanreada.m.andp.m.timevalues.Ifhhisgreaterthan24,
and/ormmandssaregreaterthan60,thetimevaluereadwillgivethecorrectnumberofseconds,evenifitisgreaterthan86399.99(thenumberofsecondsinaday).Thisinformatwillparsethetimestringbeingreadashours,minutes,secondsfromlefttoright.Therefore,
ifyouareattemptingtoreadonlyminutesandseconds,youmusthaveleadingzerosforthehours,andvaluesforbothminutesandseconds.Otherwise,yourvaluewillbetranslatedashours:minutes,notminutes:seconds.wrangesfrom5to32withadefaultof8.
CharactersRead Informat
1 124:46 TIME6.
2 14:11:03.3 TIME10.
3 08-15 TIME5.
4 00:10 TIME5.
5 00:10:42 TIME8.
6 10.42 TIME10.
7 00:10:42.5 TIME10.
TODSTAMP8.
TODSTAMP8.converts
aneight-bytetime-of-daystampproducedbytheOSTIMEmacroortheSTCKinstructiononIBMmainframesintoaSAStimevalue.Thewidthis8becausethesecallsreturneight-bytetime-of-dayvalues.UsethisinformatwhenyouarereadingIBMmainframetime-of-dayvalueson
otheroperatingsystems.
TU4.TU4.convertsIBMmainframetimerunits(38,400timerunitspersecond)toSAStimevalues.ItisusedwhenreadingIBMmainframetimerunitvaluesunderotheroperating
systems.Thewidthis4becausetheOSTIMEmacroreturnsafour-byteword.
3.4.3DatetimeInformats
B8601CIw.dB8601CIw.disavailableasofSASversion9.3.Itreads
IBMtimevalueswithacenturymarkeroftheformcyymmddhhmmss<fff>,wherecrepresentsthecenturydigit.Thecenturydigitiscalculatedbysubtracting1900fromthecurrentyear,dividingby100,anddroppingtheremainder.yyisthe
two-digityearfrom00to99,themmrepresentsthenumberofthemonth,andddrepresentsthedayofthemonth.Thetimeisrepresentedbyhhmmss<fff>,wherehhindicatesthehours,mmisminutes,ssisthenumberofseconds,andfffindicatesthousandthsofseconds.
wrangesfrom10to26,withadefaultvalueof16,whiledrangesfrom0to6forthefractionalpartofseconds.
CharactersRead Informat
21504231905 B8601CI16.
1560928053505 B8601CI16.
2140630102416454 B8601CI19.3
2131216094500 B8601CI16.
B8601DJw.dB8601DJw.disavailableasofSASversion9.3.Itreadsdatetimesinstandard
Javadateandtimenotation.yyyymmddhhmmss<ffffff>whereyyyyisthefour-digityear,mmrepresentsthenumberofthemonth,ddrepresentsthedayofthemonth,andtimeisrepresentedbyhhmmss<ffffff>,wherehhindicatesthehours,mmisminutes,ssisthe
numberofseconds,andffffffindicatesmillionthsofseconds.wrangesfrom10to26,withadefaultvalueof16,whiledrangesfrom0to6forthefractionalpartofseconds.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorresponds
tothetextshownineachline.
CharactersRead
201607181108
20141123054509
201303070814433064
201406241630254
DATETIMEw.d
DATETIMEw.dreadsSASdatetimevalues.Thedatetimevaluemustbeintheformddmonyy(yy),followedbyablankoraspecialcharacter,andthenthetimeintheformathh:mm:ss.ff.ddrepresentsthedayof
themonth,monisthethree-lettermonthabbreviation,andyy(yy)isthetwo-orfour-digityear.hhindicatesthenumberofhours,mmisthenumberofminutes,andssisthenumberofseconds.ffindicatesfractionalpartsofseconds.Bothsecondsandfractionalseconds
areassumedtobezeroiftheyarenotpresent.wcanbefrom13to40,withadefaultof18,whiledcanrangefrom0to6.
Ifyouuseatwo-digityear,SASwillapplytheYEARCUTOFF=systemoptionintranslatingtheyear.Thisinformatcanalso
reada.m.andp.m.timevalues.
CharactersRead
22APR20145:23PM
22APR2014-17:23
22APR2014:05:23:15
PM
22APR2014/17:23:15.6
MDYAMPMw.dMDYAMPMw.dreadsdatetimevaluesintheformofmm-dd-yy(yy)hh:mm:ss.ffAM|PM,wheremmrepresentsthenumberofthemonth,ddrepresents
thedayofthemonth,andyy(yy)isthetwo-orfour-digityear,followedbythetimewherehhrepresentshours,mmrepresentsminutes,ssrepresentsoptionalseconds,ffrepresentsoptionalfractionalseconds,andAM|PMindicatesa.m.orp.m.Theseparatorsarenotoptionaland
canbeahyphen(-),orperiod(.),orslash(/),orcolon(:).Thedefaultvalueofwis19andrangesfrom8to40,whiledrangesfrom0to39forthefractionalpartofseconds.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorresponds
tothetextshownineachline.Line4showsthatthisformatcantranslatetwenty-four-hourclockvalueswithouttheAM|PMindicator.
CharactersRead Informat
1 05-08-20159:33AM
MDYAMPM18.
2 10-26-20145:00PM
MDYAMPM18.
3 04-25-20131:00:57.4
MDYAMPM22.3
PM
4 08-09-201714:15
MDYAMPM17.
RMFSTAMP8.
RMFSTAMP8.convertsIBMmainframeRMF
dateandtimerecordsintoSASdatetimevalues.Thewidthisshownas8becauseRMFrecordsarepacked-decimalrecordswith4bytesoftimeinformationfollowedby4bytesofdateinformation.WhilePDTIME4.alsoreadsRMFrecords,itonlyreadsthetimeportion
oftheRMFrecordandproducesaSAStimevalue.RMFSTAMP8.readsboththedateandtimeportionsoftheRMFrecordandproducesaSASdatetimevalue.
SHRSTAMP8.SHRSTAMP8.convertsIBMmainframeSHR
dateandtimerecordsintoSASdatetimevalues.Thewidthisshownas8becauseSHRrecordsarepacked-decimalrecordswith4bytesofdateinformationfollowedby4bytesoftimeinformation.
SMFSTAMP8.
SMFSTAMP8.convertsIBMmainframeSMFrecordsintoSASdatetimevalues.Thewidthisshownas8becauseSMFrecordsarepacked-decimalrecordswith4bytesoftimeinformationfollowedby4bytesofdateinformation.ThisenablesyoutoreadSMFrecordswithout
regardtooperatingsystem.
YMDDTTMw.dYMDDTTMw.dreadsdatetimevaluesintheform<yy>yy-mm-ddhh:mm:ss.ff,wherespecialcharacterssuchasahyphen(-),period(.),slash(/),orcolon(:)areusedtoseparate
theyear,month,day,hour,minute,andseconds.Separatorsarerequiredforeachcomponent.Theyearcanbeeithertwoorfourdigits.yy(yy)isthetwo-orfour-digityear,mmrepresentsthenumberofthemonth,andddrepresentsthedayofthemonth.Thetimefollows,wherehh
representshours,mmrepresentsminutes,ssrepresentsoptionalseconds,andffrepresentsoptionalfractionalseconds,whichmustbeseparatedfromthesecondsbyadecimalpoint(.).Thisinformatwilltranslatea.m.andp.m.timevalues.Thedefaultvalueofwis19
andcanrangefrom13to40,whiledrangesfrom0to39forthefractionalpartofseconds.
CharactersRead
2014-07-18-11-08-05
2014/01/11:05:19:45
1983.02.18.05:59PM
2015-08-23-14:24:16.5
3.4.4The"ANYDATE"Seriesof
InformatsSAS9addressedanissuewiththeprocessingofdatesandtimesthathasalwaysaffectedSASusers.AlthoughinformatshandlethetranslationofastringofcharactersintoSASdateandtimevalueseasily,inordertousethemyouhadto
knowwhatthestringofcharacterslookedlikebeforeyouprocessedthem.Giventhemanywaysthatdatesandtimescanberepresented,itwasnotuncommonforseveralrecordstohaveincorrectvaluesafterprocessingbecauseofanerrorintheunderlyingtextstrings
beingtranslated.Forexample,ifyouexpectthedatestobeintheform"ddMOMyyyy,"buthalfwaythroughthefilethestringswereenteredas"mmddyyyy,"atleasthalfofyourresultingdatasetwillhavemissingdatevalues.TheDATE.informatcannotreadstrings
formattedtobereadwiththeMMDDYY.informat,andviceversa.Therearenowthreeinformatsthatwillintelligentlyand,forthemostpart,successfullyenableyoutoavoidthisproblem.
TheANYDTDTE.,ANYDTDTM.,andANYDTTME.informats
willtranslatedates,datetimevalues,andtimevalues,respectively,intotheircorrespondingSASvalues.Thistranslationwillbeperformedwithouthavingtoknowtherepresentationofthesedate,datetime,andtimevaluesinadvance.Somelimitsexistasto
thetypesofrepresentationstheseinformatswillbeabletotranslate,andinthiseraofbigdatayoushouldalsobeawarethatusingtheseinformatswillrequiremoreCPUtimethanifyouareabletouseoneoftheregularinformatstoprocessyourdata.
ThepotentialforconfusionexistswithDDMMYY,MMDDYY,andYYMMDDvalues,especiallyinthepresenceoftwo-digityearvalues.TheSASoptionDATESTYLEindicateshowsuchconfusionswillberesolved.ThepossiblevaluesfortheDATESTYLE=system
optionareshowninthefollowingtable.
Value Explanations
MDY Setsthedefaultorderasmonth,day,year."10-03-12"wouldbe
translatedasOctober3,2012.
YMD Setsthedefaultorderasyear,month,day."10-03-12"wouldbe
translatedasMarch12,2010.
DMY Setsthedefaultorderasday,month,year."10-03-12"wouldbe
translatedasMarch10,2012.
LOCALE(default)
SetsthedefaultvalueaccordingtotheLOCALE=system
option.WhenthedefaultvaluefortheLOCALE=systemoptionis"English_US,"thissets
DATESTYLEtoMDY.Therefore,bydefault,"10-03-12"wouldbetranslatedasOctober3,2012.
Note:YDM,MYD,andDYMhavebeenremovedfromSAS9.3andlaterversions.Ifyoucontinuetousetheminlegacycode,noerrorwillappearinthelog,butanyinputstringsthatcannotbetranslatedwithoutknowingtheDATESTYLE(forexample,"10-03-12")
willbetranslatedasmissing.
WhathappenswhentheinputstringcannotbetranslatedusingtheDATESTYLEoptionineffect?TheANYDTseriesofinformatswilltesttheinputstringtoseewhetheroneoftheotherDATESTYLEoptionswillwork.If
onlyoneDATESTYLEproducesavalidSASdateordatetimevalue,thenSASwillprocesstheinputstringusingthatDATESTYLE.However,itisentirelypossiblethattheinputstringcanbetranslatedusingmorethanoneoftheremainingDATESTYLEoptions.Forexample,theinput
string"270328"cannotbetranslatedusingMDY,butbothYMDandDMYwillproduceavalidSASdate.SAShasaninternalpriorityofwhichDATESTYLEtakesprecedencewhentheoptionineffectwillnotwork,andtwoormoreDATESTYLESwill.ItisbasedontheDATESTYLEoptionin
effect.ThefollowingtabledetailshowtheDATESTYLEischoseniftheDATESTYLEoptionineffectdoesnotyieldavalidSASdatevalue.
DATESYTLEOptioninEffect
InputString
DATESTYLEsPossible
MDY 170514
YMD 110845
DMY Noambiguityispossible.DMYwillalwaystakeprecedence.
Inshort,whentheDATESTYLEisMDY,thenanyambiguitywillberesolvedusingYMD,andwhentheDATESTYLEisYMD,anyambiguityisresolvedusingDMY.
ANYDTDTEw.ANYDTDTEw.willtranslatedatathatcan
bereadwiththefollowinginformats:DATE,DATETIME,DDMMYY,JULIAN,MDYAMPM,MMDDYY,MMxYY,MONYY,TIME,YMDDTTM,YYMMDD,YYMMn,orYYQintoSASdatevalues.Thisinformatcanalsoworkwiththefollowingstandarddateformats:"February25,
2012,""08/2014,"or"2015-05."wcanrangefrom5to32,andthedefaultwidthis9.Thisinformatextractsdatevaluesfromadatetimestring.However,ifonlyatimevalueisgiven,thedateisassumedtobeJanuary1,1960.ThefollowingtableusesOPTIONSDATESTYLE=MDYas
thedefaultinterpretationfortwo-digityearvalues.
CharactersRead
05172014
20140517
2014Q2
051714
17052014
170514
17MAY2014:15:12:06
15:12:06
2014137
MAY2014
17MAY2014
May17,2014
14-05
2014-05
05-2014
05-17-20143:12:06PM
2014-05-17-15:12:06
ANYDTDTMw.
ANYDTDTMw.willtranslatedatathatcan
bereadwiththefollowinginformats:DATE,DATETIME,DDMMYY,JULIAN,MDYAMPM,MMDDYY,MMxYY,MONYY,TIME,YMDDTTM,YYMMDD,YYMMn,orYYQintoSASdatetimevalues.Thisinformatcanalsoworkwiththefollowingstandarddateformats:"February25,
2012,""08/2014,"or"2015-05."wcanrangefrom1to32,andthedefaultwidthis19.
Thisinformatwillparsetimevaluesfrominputstringsbasedoncolonsandperiods.Ifthereisonecolon(forexample,15:12),thefirsttwodigitsaretranslatedashoursand
thelasttwoasminutes.Iftherearetwocolons(forexample,15:12:06),thedigitsprecedingthefirstcolonaretranslatedashours,thenextsetoftwodigitsasminutes,andthelasttwoasseconds.Ifthereisasingledecimalpointandoneormorecolons(forexample,12:06.5),
thevaluefollowingthedecimalpointistranslatedasadecimalfractionofseconds,andthevalueprecedingthedecimalpointisconsideredtobeseconds.Asinglecolonisthereforeinterpretedasminutes:seconds.fractionalseconds.Inordertoaccountforhours,the
correctformatwouldbehours:minutes:seconds.fractionalseconds.
Iftherearemultipledecimalpoints(forexample,15.12.06),thentheyareconsideredtobedelimitersfordatevaluesandthusarenottranslatedastime
values.
Thisinformatextractsdatetimevaluesfromastring.Ifonlyatimevalueisgiven,thedateisassumedtobeJanuary1,1960.Ifonlyadatevalueisgiven,thetimeisassumedtobemidnight(0:00).Thefollowingtableusesthesameinputdataasis
usedintheANYDTDTE.informatexampleabove.
CharactersRead
05172014
20140517
2014Q2
051714
17052014
170514
17MAY2014:15:12:06
15:12:06
2014137
MAY2014
17MAY2014
May17,2014
2014-05
05-2014
14-05
05-17-20143:12:06
PM
2014-05-17-15:12:06
ANYDTTMEw.
ANYDTTMEw.willtranslatedatathatcanbereadwiththefollowinginformats:DATE,DATETIME,DDMMYY,JULIAN,
MDYAMPM,MMDDYY,MMxYY,MONYY,TIME,YMDDTTM,YYMMDD,YYMMn,orYYQintoSAStimevalues.Thisinformatcanalsoworkwiththefollowingstandarddateformats:"February25,2012,""08/2014,"or"2015-05."wcanrangefrom1to32,andthedefaultwidthis8.
ANYDTTMEw.canextracttimevaluesfromadatetimevalue.However,ifonlyadatevalueisgiven,thetimeisassumedtobe12:00a.m.
Characters
Read
17MAY2014:15:12:06
15:12:06
05-17-20143:12:06PM
2014-05-17-15:12:06
08.05
08.05
08:05
08:05:05
17:15
2:45PM
2:45PM
6AM
6:00AM
27:36:58
3.4.5SoWhyNotJustUsethe"ANYDATE"SeriesofInformats?ItistemptingtoautomaticallyuseANYDTDTE.,ANYDTTM.,orANYDTTME.toprocess
stringsrepresentingdates,datetimes,andtimes.Youdonothavetoworryabouttheformattingoftheinputstring,andSASwillmakesenseoutofit.The"ANYDATE"informatsdohavelimitations,andtherulesthatSASfollowsmightnotbetherulesthatyouneedtoapply.
First,thereisthematteroftheadditionalprocessingneeded.Theseinformatsgothroughadecisiontreetodeterminehowtotranslateeverysinglevalueencountered;therefore,theamountofadditionalprocessingwillincreasewiththenumberoftimeseach"ANYDATE"informat
hastobeused.Thiswouldhaveanegligibleimpactonasmallamountofdata,butifyouneedtousethemonbigdata,youmightwanttoconsiderstandardizingtherepresentationofyourdate,time,anddatetimetextvaluesbeforehandandusingthecorresponding
informat.Second,itisentirelypossiblethatyouwouldwanttoconsideranonstandardvalueerroneousanddon'twantSAStodecidewhattodowithitwithoutyoubeingabletoinspectitfirst.Third,exceptionscanoccur,evenwhentheuseofanANYDATEinformatiswarranted.
WhileitisalwaysagoodideatocheckalldatathatyouareconvertingtoSASfromanothersourceandespeciallywhenyouareconvertingdates,times,anddatetimevalues,itiscriticalifyouareusingtheANYDT.informats.
Finally,itisimportant
tonotethattheANYDATEseriesofformatsaredesignedtohandletheissueofvaryingwaysofrepresentingdates,butthey,likeallotherdate,time,anddatetimeinformats,arenotdesignedtohandledirtydata.Missingseparators,misspelledwords,andmissing
datecomponentsareafewofthemajordataproblemsthatareencounteredwhenprocessingdates,times,anddatetimesfromsourcesotherthanSAS.Unlessyouspecificallyprovidecodetofixthoseproblemsontheflyorcanensurethatyourdatesarecleanbeforeprocessingthem,
youwillwindupwithmissingdate,time,ordatetimevaluesinyourdataset.SASprogrammershavewrittenagreatdealofcodetohandlethisspecificissue;KingandFlemingshowonesuchapproachinthe2011SASGlobalForumproceedings(seehttp://support.sas.com/resources/papers/proceedings11/117-
2011.pdf).Example3.7isaskeletonofanapproachusingauser-writtenfunctionandtheANYDATE.informat.
Example3.7:ASimpleFunctiontoHandleDateswithMissingSeparators
LIBNAMEcontrol"c:\book\2ndEd\examples";ODSESCAPECHAR='~';OPTIONSCMPLIB=
(control.functions);
PROCFCMPOUTLIB=control.functions.dates;
FUNCTIONmakedate(cdate$)$;LENGTHdtstr$42supr$16;supr='';*assumethatdateisinMMDDYYform,butcheck;*missingdatesoftenhaveaformof__/__/____;IFSUBSTR(cdate,7,4)
NOTIN('','____')THENDO;*assumeyearisgood;yy=INPUT(SUBSTR(cdate,7,4),4.);m=SUBSTR(cdate,1,2);IF'01'<=m<='12'THENDO;mm=INPUT(m,2.);*Monthisgoodchkday;*UseINTNXtofindthemaximumnumberofdaysincurrentmonth;d=SUBSTR(cdate,4,2);IF'01'<=d<=PUT(DAY(INTNX('MONTH',MDY(mm,1,yy),0,'e')
),z2.)THENdd=INPUT(d,2.);ELSEDO;*Dayisbadforthismonth;*Fixbydividingnumberofdaysinmonthby2;dd=CEIL(DAY(INTNX('MONTH',mdy(mm,1,yy),0,'e'))/2);supr='~{superDay}';END;END;ELSEDO;*Monthisbad-
resetmonthandday;mm=6;dd=31;supr='~{superMonth}';END;*Createthedatevalue;date=MDY(mm,dd,yy);dtstr=CATT(PUT(date,MMDDDYY10.),supr);END;ELSEDO;*yrisbad;dtstr='Unknown~{superY}';
END;RETURN(dtstr);ENDSUB;RUN;QUIT;PROCFORMAT;VALUE$mkdtOTHER=[makedate()];RUN;
ThecodeinExample3.7createdafunctiontobeusedasaformatforourdates,whichwillimputea
replacementdatestringwhenprovidedwithadatestringthatmayormaynothavemissingdatecomponents.Notethatthisisacharacterformatbecauseithastotreattheincomingdatedataascharacterstrings.IfyoutrytoreaddatestringswithmissingdatecomponentsasaSAS
date,youwillgetamissingvalue.
Nowlet'sreadinsomesampledata.ThedatasetRPTDATEScontainsproductionerrortrackingdatafromalegacysystem.Unfortunately,someofthedatedatawascorrupted,sotherearemissingandincorrect
days,months,andyears.
DATArptdates;INPUTrecno@4rptdt$10.errs;DATALINES;113/15/2013374209/08/20133302/30/2013324__/15/201315504/27/2013195605/__/201317707/08/____20806/04/0135
908/32/201341011//201361101/23/203111;;;;RUN;
Butnowthatwe'vecreatedafunctionthatistobeusedasaformat,let'suseit.Belowisadatasetwithsomedatesandacountofmachinefaultsoccurringonthatdate.
Asyoucansee,thedateshavenotbeenenteredverywell,withmissingcomponents(rows3,5,and6)andtypographicalerrors(rows7and9).We'regoingtousetheformat$MKDTtoimputethedateswecan,andannotateeachdatethatwasimputedintheoutputstring.
Figure3.1:RPTDATESDataSetwithInvalidDates
NowwewilluseaPROCREPORTtodisplaythetableandformatourbaddata.In
line2,wealiastheoriginaldatestringasasecondcolumninordertoshowitwithandwithouttheformatthatwecreated.Weleavetheoriginaldatestringinthevariablerptdtandinline4weapplytheformatthatwecreatedtothevaluesinthealiasedcolumndt.
1.PROCREPORTDATA=rptdatesNOWDSPLIT='\';2.COLUMNrptdtrptdt=dterrs;3.DEFINErptdt/DISPLAY"Original\Datefrom\ErrorLog";4.DEFINEdt/'Imputed\Date'f=$mkdt36.;5.DEFINEerrs/"Errors\Reported";6.RUN;
TheresultofthePROC
REPORTisbelow.The"ImputedDate"columnisnothingmorethantheresultofdisplayingtheoriginaldatestringusingthe$MKDT.format.
Output
OriginalDatefromErrorLog
ImputedDate
13/15/2013 06/30/2013
09/08/2013 09/08/2013
02/30/2013 02/14/2013
__/15/2013 06/30/2013
04/27/2013 04/27/2013
05/__/2013 05/16/2013
07/08/____ UnknownY
06/04/013 UnknownY
08/32/2013 08/16/2013
11//2013 11/15/2013
01/23/2031 UnknownY
ThiscapacitytousePROCFCMPtocreatefunctionsthatprocesscharacterstringsandthenusethefunctionyoucreateinacustominformat(orformat,for
thatmatter)givesyoutheabilitytocreatecustomdateinformats.Withalittlecreativityonyourpart,youcanusethismethodtosolvesomeofthemoredifficultdateprocessingchallengesthatyoumayencounter.
Chapter4:ISO8601Dates,Times,Datetimes,Durations,andFunctions
4.1WhatIsISO8601?4.2ISO8601Formats4.3ISO8601Informats4.4TimeZoneFunctions4.5ISO8601
DurationsandIntervals4.6Conclusion
4.1WhatIsISO8601?ISO8601isthenameofaninternationallyacceptedwayof
describingdatesandtimesusingnumbersandisoneofnumerousinternationalstandardsmaintainedbytheInternationalStandardsorganization(ISO).Whileusingnumberseliminatestheneedfortranslatingmonthnames,thestandarddefinestheorderofdateandtime
componentsinadatestring,removingtheconfusionofwhether01-11-05meansJanuary11,2005,November12005,orNovember5,2001.Thisfacilitatestheexchangeofdata,especiallybetweeninternationalparties.Thecompletestandard(availablefrom
http://www.iso.org/iso/home.htmlcoversthefollowing:
•Date•Timeofday•Coordinateduniversaltime(UTC)•LocaltimewithoffsettoUTC•Dateandtime•Timeintervals
•Recurringtimeintervals
ThisstandardhasbeenadoptedbytheClinicalDataInterchangeStandardsConsortium(CDISC)fortherepresentationofitsdateandtimedata,sothoseinthepharmaceuticalindustryare
particularlyfamiliarwithit.
SAShasbuilt-informatsspecificallydesignedtodisplayitsdate,time,anddatetimevaluesinthewaydescribedbythestandard.Thereisalsoacompletesetofinformatsdesignedtointerpretstringsthat
conformtothestandardsothattheycaneasilybeconvertedtoSASdate,time,anddatetimevaluesandthereforeusedincalculationsandstoredinSASdatasets.OnemajordifferencebetweentheISOformatsandinformatsandtheirstandardcounterpartsisthatthe
ISOstandardallowsformissingcomponents.Forexample,ifyouhaveadatevaluewhereyouonlyknowthemonthandyear,itcanbeexplicitlyrepresentedinanISO-standarddatestring.ThestandardSASdateformatscanonlyrepresentacompleteSASdatevalue.Even
thestandardformatsthatonlydisplaymonthandyearusecompleteSASdatevalues,butthedaysarenotpartofthedisplay.TheISOinformatsarealittlemoreintricatebecauseofthisfeatureofthestandard;someoftheinformatsperformadefaultsubstitutionforany
missingcomponentsinordertocreateavalidSASdate,time,ordatetimevalue.Bycomparison,thestandardSASdate,time,anddatetimeinformatswillreturnamissingvalueifyoupresentthemwithastringthathasamissingcomponent.Therefore,whileit
mightseemthatsomeoftheformatsandinformatsthatwedescribedinChapters2and3willproduceresultsaccordingtothestandard,itismuchmorereliabletousetheformatsandinformatsdescribedinthischapterwhenyouareworkingwithISOstandarddatesand
times.
AswithstandardSASformats,itiscriticalthatyouonlyusedateformatsandinformatsfordatevalues,timeformatsandinformatswithtimevalues,anddatetimeformatsandinformatswithdatetimevalues.
4.2ISO8601FormatsAlltheISO8601formatsareleft-justified,asopposedtothemajorityofstandardSASdate,time,anddatetimeformats,whichareright-justifiedbecausetheyrepresentnumericvalues.Theformatsin
thefollowingdescriptionsaregroupedbydate,time,anddatetime.Eachformathasabasic(formatnamestartswith"B")andanextended(formatnamestartswith"E")version.TheextendedversionoftheISOformatsusesdelimitersbetweencomponents,whilethe
basicversionsdonot.Allthefollowingexampleswillpresentthebasicversionoftheformat,followedbytheextendedversionofthesameformatwiththesameSASvalue,soyoucanseethedifference.ItisimportanttonotethatSAScontinuestodevelopformatsandinformats,soitis
alwaysagoodideatocheckthedocumentationthatcamewithyourreleaseofSAS,ortheonlinedocumentationatsupport.sas.comforanyadditionalformatsand/orinformats.
4.2.1ISODateFormats
B8601DAw.B8601DAw.writesdatevaluesintheISO8601basicdatenotationyyyyMMdd,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,andddisthezero-paddednumericaldayofthemonth.Itisleft-justifiedwithinthefield.wcanbefrom8
to10,andthedefaultwidthis10.Thefollowingtableshowstheresultwhenthedatevalueis19920,whichcorrespondstoJuly16,2014.
FormatName Result
B8601DA8. 20140716
B8601DA9. 20140716
B8601DA10. 20140716
E8601DAw.
E8601DAw.writesdatevaluesintheISO8601extendeddatenotationyyyy-MM-dd,whereyyyyisthefour-digityear,MMisthezero-
paddedmonth,andddisthezero-paddednumericaldayofthemonth.Itisleft-justified.wisalways10.Thefollowingtableshowstheresultwhenthedatevalueis19920,whichcorrespondstoJuly16,2014.
FormatName Result Comment
E8601DA10. 2014-07-16
4.2.2ISOTimeFormats
YoucandeterminewhichoftheISO8601timeformatsyouwanttousebyansweringtwoquestions.First,doestheSAStimevaluethatyouaregoingtodisplayrepresentUTCorlocaltime?IfitrepresentsUTC,thenyouwilluseeitherthe*8601TX.orthe*8601TZ.format,
andyouhavetodeterminewhetheryouwanttodisplayUTCasitslocaltimeequivalent(basedontheTIMEZONE=optionsetting).Inthatcase,youwouldusethe*8601TX.format.IfyouwanttodisplaytheUTCtimevalueasitisstored,usethe*8601TZ.format.Ifthe
SAStimevaluerepresentslocaltime,thenusethe*8601LZ.format.TheTIMEZONE=optionhasnoeffectbecausetheformatunderstandsthatthetimeisthelocaltime.
B8601TMw.dB8601TMw.dwrites
timevaluesintheISO8601basictimenotationhhmmssffffff,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds.NotethattherearenodelimitersintheISObasictimestring,whichmight
maketheresultdifficulttoread.wcanbefrom6to15,withadefaultwidthof8.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis61479.468,whichcorrespondstothetime5:04:39p.m.
(17:04:39.468):
FormatName Result
B8601TM6. 170439
B8601TM8. 170439
B8601TM10.2. 17043947
B8601TM12. 170439
B8601TM15.3. 170439468
E8601TMw.d
E8601TMw.dwritestimevaluesintheISO8601extendedtimenotationhh:mm:ss.ffffff,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds.Colons(:)
delimithours,minutes,andseconds,whileadecimalpointdelimitsthedecimalportionofseconds.wcanbefrom8to15,withadefaultwidthof8.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis
61479.468,whichcorrespondstothetime5:04:39p.m.(17:04:39.468):
FormatName Result
E8601TM6.
E8601TM8. 17:04:39
E8601TM10.2. 17:04:39.5
E8601TM12. 17:04:39
E8601TM15.3. 17:04:39.468
B8601TXw.d
Thisformatisavailable
asofSASversion9.4.B8601TXw.dadjustsaCoordinatedUniversalTime(UTC)valuetotheuser'slocaltime.Sinceitisintendedforclocktimesonly,valuesgreaterthan86400orlessthan0willshowasterisks.TheformatwritestheadjustedlocaltimeintheISO8601basictime
notationhhmmssffffff+|–hhmm,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthe
zeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashhmm,allwithoutdelimiters,asthisisabasicISOformat.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,usingtheTIMEZONE=
systemoption.IfTIMEZONEisnotset,thentheuserlocaltimeisbasedonthesystemclock.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Youwillneedtoensurethatyouhavealargeenoughwidthspecification,orelsethetimezone
offsetcouldbetruncatedordroppedcompletely.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis37050,whichcorrespondstothetime10:17:30a.m.GreenwichMeanTime.Asyoucansee,thevaluedisplayedchangeswiththetime
zone.
FormatName Result
B8601TX9. 144730+04
B8601TX12. 171730+0700
B8601TX14. 052500-0500
B8601TX16. 221730+1200
E8601TXw.d
ThisformatisavailableasofSASversion9.4.E8601TXw.dadjustsaCoordinatedUniversalTime(UTC)valuetotheuser'slocaltime.Sinceitisintendedforclocktimesonly,valuesgreaterthan86400orlessthan0willshowasterisks.Theformat
writesthelocaltimeintheISO8601extendedtimenotationhh:mm:ss.ffffff+/-hh:mm,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffset.The
timeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashh:mm.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,usingtheTIMEZONE=system
option.IfTIMEZONEisnotset,thentheuserlocaltimeisbasedonthesystemclock.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis37050,which
correspondstothetime10:17:30a.m.GreenwichMeanTime.Asyoucansee,thevaluedisplayedchangeswiththetimezone.
FormatName Result
E8601TX9. 12:17:30
E8601TX. 12:17:30+02:00
E8601TX12. 15:47:30+05
E8601TX14. 18:17:30+08:00
E8601TX16. 12:17:30+02:00
B8601LZw.d
ThisformatisavailableasofSASversion9.4.B8601LZw.ddisplaysSAStimevalueswithoutanyadjustmentsusingtheISO8601basictimenotation
hhmmssffffff+|-hhmm,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffsetfromCoordinatedUniversalTime(UTC).Thetimeoffsetisaplus(fortime
zoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashhmm,allwithoutdelimiters,asthisisabasicISOformat.TheoffsetiscalculatedbasedonthetimezoneatthelocalSASsessionItisnotaffectedbythe
TIMEZONE=systemoption.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.ThemaindifferencebetweenthisformatandtheB8601TX.formatisthattheSAStimevalueisconsideredtobelocal
time,notGreenwichMeanTime.Foreasiercomparison,wewillusethesameSAStimevalueaswiththe*8601TXexamples.Thefollowingtableshowstheresultwhenthetimevalueis37050,whichcorrespondstothetime10:17:30a.m.CentralDaylighttime.
FormatName Result
B8601LZ9. 101730Z
B8601LZ12. 101730-0500
B8601LZ14. 101730-0500
B8601LZ16. 101730-0500
E8601LZw.d
ThisformatisavailableasofSASversion9.4.E8601LZw.ddisplaysSAStimevalueswithoutanyadjustmentsusingthe
ISO8601extendedtimenotationhh:mm:ss.ffffff+/-hh:mm,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffsetfromCoordinatedUniversal
Time(UTC).Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashh:mm.TheoffsetiscalculatedbasedonthetimezoneatthelocalSASsession.Itisnotaffectedbythe
TIMEZONE=systemoption.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.ThemaindifferencebetweenthisformatandtheE8601TX.formatisthattheSAStimevalueisconsideredtobelocal
time,notGreenwichMeanTime.Foreasiercomparison,wewillusethesameSAStimevalueaswiththe*8601TXexamples.Thefollowingtableshowstheresultwhenthetimevalueis37050,whichcorrespondstothetime10:17:30a.m.CentralDaylighttime.
FormatName Result
E8601LZ9. 10:17:30Z
E8601LZ12. 10:17:30Z
E8601LZ14. 10:17:30-05:00
E8601LZ16. 10:17:30-05:00
B8601TZw.d
ThisformatisavailableasofSASversion9.4.B8601TZw.ddisplaysa
SAStimevalueasaCoordinatedUniversalTime(UTC)value.Sinceitisintendedforclocktimesonly,valuesgreaterthan86400orlessthan0willshowasterisks.TheformatwritestheUTCtimeintheISO8601basictimenotationhhmmssffffff+|-hhmmwherehhrepresents
zero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisalwaysgoingtobedisplayedas+0000,becausetheresultingtimedisplayisthetimeatthezero
meridianinGreenwich,England.ThisformatisnotaffectedbytheTIMEZONE=systemoption.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis37050,
whichcorrespondstothetime10:17:30a.m.GreenwichMeanTime.
FormatName Result
B8601TX9. 101730Z
B8601TX12. 101730+0000
B8601TX14. 101730+0000
B8601TX16. 101730+0000
E8601TZw.d
ThisformatisavailableasofSASversion9.4.E8601TZw.ddisplaysaSAStimevalueasaCoordinatedUniversal
Time(UTC)value.Sinceitisintendedforclocktimesonly,valuesgreaterthan86400orlessthan0willshowasterisks.TheformatwritestheUTCtimeintheISO8601extendedtimenotationhh:mm:ss.ffffff+/-hh:mm,wherehhrepresentszero-paddedhours,mmrepresents
zero-paddedminutes,ssrepresentsseconds,andffffffrepresentsdecimalfractionofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisalwaysgoingtobedisplayedas+00:00,becausetheresultingtimedisplayisthetimeatthezeromeridianinGreenwich,England.Thisformatis
notaffectedbytheTIMEZONE=systemoption.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableshowstheresultwhenthetimevalueis37050,whichcorrespondstothetime10:17:30a.m.
GreenwichMeanTime.
FormatName Result
E8601TX9. 10:17:30Z
E8601TX. 10:17:30+00:00
E8601TX12. 10:17:30Z
E8601TX14. 10:17:30+00:00
E8601TX16. 10:17:30+00:00
4.2.3ISO
DatetimeFormats
B8601DNw.B8601DNw.writesdatesfromdatetimevaluesintheISO8601basicdatenotationyyyyMMdd,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,andddisthe
zero-paddednumericaldayofthemonth.Itisleft-justifiedwithinthefield.wcanbefrom8to10,andthedefaultwidthis10.Notethatthebasicdatenotationhasnodelimiters.Thedatetimevalueusedinthisexampleis1664263800,whichcorrespondsto7:30:00a.m.onWednesday,
September26,2012.
FormatName Result
B8601DN8. 20120926
B8601DN9. 20120926
B8601DN10. 20120926
E8601DNw.
E8601DNw.writesdatesfromdatetimevaluesintheISO8601extendeddatenotationyyyy-MM-dd,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,andddisthezero-paddednumericaldayofthemonth.Itisleft-justified.wisalwaysequalto10,andthe
defaultwidthis10.Thedatetimevalueusedinthisexampleis1664263800,whichcorrespondsto7:30:00a.m.onWednesday,September26,2012.
FormatName Result Comment
E8601DN10. 2012-
09-26
B8601DTw.d
B8601DTw.dwritesdatetimevaluesintheISO8601basicdatetimenotationyyyyMMddThhmmssffffffwhereyyyyisthefour-digityear,MMisthezero-paddedmonth,dd
isthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds.TistheISO8601delimiterfortime.NotethattherearenootherdelimitersintheISObasic
datetimestring,includingthedecimalfractions,whichmightmaketheresultdifficulttoread.wcanbefrom15to26,withadefaultwidthof19.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thedatetimevalueusedinthisexampleis1686408430.44,which
correspondsto2:47:10.44p.m.onSunday,June9,2013.
FormatName Result
B8601DT15.2. 20130609T144710
B8601DT19. 20130609T144710
B8601DT19.2. 20130609T14471044
B8601DT24.1. 20130609T1447104
B8601DT26. 20130609T144710
E8601DTw.d
E8601DTw.dwritesdatetimevaluesintheISO8601extendeddatetimenotationyyyy-MM-ddThh:mm:ss.ffffff,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-padded
minutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds.TistheISO8601delimiterfortime.Colons(:)delimithours,minutes,andseconds,whileadecimalpointdelimitsthedecimalportionofseconds.wcanbefrom19to26,withadefaultwidthof19.dcanbe
from0to6,withadefaultof0.Thevalueisleft-justified.Thedatetimevalueusedinthisexampleis1686408430.44,whichcorrespondsto2:47:10.44p.m.onSunday,June9,2013.
FormatName Result
E8601DT19. 2013-06-
09T14:47:10
E8601DT19.2. 2013-06-09T14:47:10
E8601DT22.1. 2013-06-09T14:47:10.4
E8601DT24. 2013-06-09T14:47:10
E8601DT24.2. 2013-06-09T14:47:10.44
B8601DXw.d
ThisformatisavailableasofSASversion9.4.B8601DXw.dadjustsa
CoordinatedUniversalTime(UTC)datetimevaluetotheuser'slocaldateandtime.TheformatwritestheadjustedlocaltimeintheISO8601basicdatetimeandtimezonenotationyyyyMMddThhmmssffffff+|–hhmm,whereyyyyisthefour-digityear,MMisthezero-padded
month,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.NotethattherearenodelimitersintheISO
basicdatetimestringincludingthe+/-ofthetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashhmm,allwithoutdelimiters.Theoffsetiscalculatedfromthe
timeatthezeromeridianinGreenwich,England,usingtheTIMEZONE=systemoption.IfTIMEZONEisnotset,thentheuserlocaltimeisbasedonthesystemclock.wcanbefrom20to35,withadefaultwidthof26.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.
Thefollowingtableusesthevalue1763371185,whichcorrespondsto9:19a.m.onNovember17,2015,GreenwichMeanTime.Asyoucansee,thedisplaydoesnotchangedependingonthewidthspecification,becausetheminimumlengthof20canaccommodatethe
entirewidthoftheoutput.
FormatName Result
B8601DX20. 20151117T111945+0200
B8601DX22. 20151117T031945-0600
B8601DX24. 20151117T041945-0500
B8601DX26. 20151117T171945+0800
B8601DX28. 20151117T194945+1030
E8601DXw.d
ThisformatisavailableasofSASversion9.4.E8601DXw.dadjustsaCoordinatedUniversalTime(UTC)datetimevaluetotheuser'slocaldateandtime.Theformatwritesthe
adjustedlocaldatetimeintheISO8601extendeddatetimeandtimezonenotationyyyy-MM-ddThhmmss.ffffff+/-hh:mm,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-padded
hours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffset
timerepresentedashh:mm.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,usingtheTIMEZONE=systemoption.IfTIMEZONEisnotset,thentheuserlocaltimeisbasedonthesystemclock.wcanbefrom20to35,withadefaultwidthof26.d
canbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thefollowingtableusesthevalue1763371185,whichcorrespondsto9:19a.m.onNovember17,2015,GreenwichMeanTime.
Format
Name Result
E8601DX20. 2015-11-17T02:19:45
E8601DX22. 2015-11-17T05:19:45-04
E8601DX26. 2015-11-17T03:19:45-06:00
E8601DX28. 2015-11-17T19:49:45+10:30
B8601DZw.d
B8601DZw.ddisplaysaSASdatetimevaluebasedonthezeromeridianCoordinatedUniversalTime(UTC)intheISO8601basicdatetimeandtimezonenotationyyyyMMddThhmmssffffff+|–hhmm,whereyyyyisthefour-digityear,MM
isthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisalways
goingtobedisplayedas+0000,becausetheresultingtimedisplayisthetimeatthezeromeridianinGreenwich,England.Therefore,thisformatisnotaffectedbytheTIMEZONE=systemoption.WhiletheSASdocumentationsaysthatwcanbefrom16to35,withadefault
widthof26,youwillgetawarningandamissingvalueifyouuseaformatwidthoflessthan20.dcanbefrom0to6,withadefaultof0.Thevalueisleft-justified.Thedatetimevalueusedinthisexampleis1730398875,whichcorrespondsto6:21:15p.m.onOctober31,
2014,GreenwichMeanTime.
FormatName Result
B8601DZ20. 20141031T182115+0000
B8601DZ26. 20141031T182115+0000
E8601DZw.d
E8601DZw.ddisplaysaSASdatetimevaluebasedonthezeromeridianCoordinatedUniversalTime(UTC)intheISO8601extendeddatetimeandtimezonenotation
yyyy-MM-ddThhmmss.ffffff+/-hh:mm,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimal
fractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisalwaysgoingtobedisplayedas+00:00,becausetheresultingtimedisplayisthetimeatthezeromeridianinGreenwich,England.Therefore,thisformatisnotaffectedbytheTIMEZONE=system
option.wcanbefrom20to35,withadefaultwidthof26,andthevalueisleft-justified.dcanbefrom0to6,withadefaultof0.Thedatetimevalueusedinthisexampleis1730398875,whichcorrespondsto6:21:15p.m.onOctober31,2014,GreenwichMeanTime.
FormatName Result
E8601DZ20. 2014-10-31T18:21:15Z
E8601DZ22. 2014-10-31T18:21:15Z
E8601DZ26. 2014-10-31T18:21:15+00:00
E8601DZ28. 2014-10-31T18:21:15+00:00
4.3ISO8601InformatsISO8601informatsaredesignedtoprocessstringsofcharactersthatrepresentISO8601dates,times,anddatetimesand,whenusedwiththeINPUTstatementorINPUT()orINPUTN()functions,willproduceaSAS
date,time,ordatetimevaluewhenthestringisreadwiththeselectedinformat.
4.3.1ISODateInformats
B8601DAw.B8601DAw.willreaddatevaluesinboththeISO8601basicdate
notationyyyyMMddandtheISO8601extendeddatenotationyyyy-MM-dd,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,andddisthezero-paddednumericaldayofthemonth.wisalways10,andthedefaultis10.Itisimportanttonotethatifeithermonthor
dayismissing,SASwilluseavalueof1forthemonthand/ordaytoprovideaSASdatevalue.However,thismightnotbewhatyouwant,asyoursituationmightcallforanalgorithmtoimputedateswithmissingmonthsand/ordaysinstead.
CharactersRead Informat
20140504 B8601DA.
201405 B8601DA.
2014 B8601DA.
E8601DAw.
E8601DAw.readsdatevaluesintheISO8601extendeddatenotationyyyy-MM-dd,whereyyyyisthefour-digityear,MMisthezero-
paddedmonth,andddisthezero-paddednumericaldayofthemonth.Thisinformatcanonlyhavealengthof10,asthatistheonlylengthforadateinISO8601extendeddatenotation.Unliketheparallelbasicdatenotationinformat,SASwillnotsubstituteavalueof1foreither
missingmonthorday,andyouwillgetamissingvalueforyourSASdate.
CharactersRead Informat
2014-05- E8601DA10.
2014-05 E8601DA10.
2014 E8601DA10.
4.3.2ISOTimeInformats
B8601TMw.dB8601TMw.dreadstimevaluesintheISO8601basictimenotationhhmmssffffff,
wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisdecimalfractionsofseconds.wcanbefrom6to15,with8asthedefault.Usingawof6willreadtimevalueswithnodecimalportion.dcanbefrom0to6,withadefaultof
0.
CharactersRead Informat
144535 B8601TM8.
0630 B8601TM8.
1208455 B8601TM10.1
E8601TMw.d
E8601TMw.dreadstimevaluesintheISO8601extendedtimenotationhh:mm:ss.ffffff,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresents
seconds,andffffffisdecimalfractionsofseconds.wcanbefrom8to15,with8asthedefault.Usingawof8willreadtimevalueswithnodecimalportion.dcanbefrom0to6,withadefaultof0.
CharactersRead Informat
10:17:45 E8601TM8.
18:05 E8601TM8.
07:15:12.25 E8601TM12.2
B8601TZw.d
B8601TZw.dreadsCoordinatedUniversalTime(UTC)timevaluesusingtheISO8601basictimenotationhhmmssffffff,+|-hhmm,wherehhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentszero-paddedseconds,
andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashhmm.Thetimezoneoffsetmightalsobe
indicatedbytheletterZ,representingthezeromeridian.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,andtheresultingSAStimevaluewillbethetimeatthezeromeridian.wcanbefrom9to20,withadefaultwidthof14,whiledcanbefrom
0to6,withadefaultof0.Sincethisinformatisintendedtoonlyreadclocktimes,valuesresultingintimesgreaterthan24:00:00orlessthan00:00:00willbeadjustedappropriatelysothattheresultwillbewithinthe24-hourclock.
CharactersRead Informat
175200+0000 B8601TZ14.
175200Z B8601TZ9.
091520+0600 B8601TZ14.
210800-0500 B8601TZ14.
E8601TZw.d
E8601TZw.dreadsCoordinatedUniversalTime(UTC)timevaluesusingtheISO8601extendedtimenotationhh:mm:ss.ffffff+|-hh:mm,wherehh
representszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentszero-paddedseconds,andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestof
themeridian),followedbytheoffsettimerepresentedashh:mm.ThetimezoneoffsetmightalsobeindicatedbytheletterZ,representingthezeromeridian.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,andtheresultingSAStime
valuewillbethetimeatthezeromeridian.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Sincethisinformatisintendedtoonlyreadclocktimes,valuesresultingintimesgreaterthan24:00:00orlessthan00:00:00willbeadjusted
appropriatelysothattheresultwillbewithinthe24-hourclock.
CharactersRead Informat
17:52:00+00:00
17:52:00Z
06:00:30.57+08:00
04:17:00-05:00
YoumightwonderwhyaUTCvalueof06:00:30.57+08:00
yieldsatimevalueof22:00:30.57atthezeromedian,andnot14:00:30.57.The+08:00houroffsetmeansthatGMTplus8hourswillgiveyouthelocaltime.Therefore,theconversionfromlocaltimetotimeatthezeromedianislocaltimeminustheoffset.6-8=-2,whichisthen
adjustedto22byadding24hours.
E8601LZw.d
E8601LZw.dreadsCoordinatedUniversalTime(UTC)timevaluesusingtheISO8601extendedtimenotationhh:mm:ss.ffffff+|–hh:mm,wherehhrepresentszero-padded
hours,mmrepresentszero-paddedminutes,ssrepresentszero-paddedseconds,andffffffisdecimalfractionsofseconds,whichisthenfollowedbythetimeoffset.Thetimeoffsetisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followed
bytheoffsettimerepresentedashh:mm.ThetimezoneoffsetmightalsobeindicatedbytheletterZ,representingthezeromeridian.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,andtheresultingSAStimevaluewillbethetime
ofthelocalSASsession,basedonthesystemclock.ItisnotaffectedbytheTIMEZONE=systemoption.wcanbefrom9to20,withadefaultwidthof14.dcanbefrom0to6,withadefaultof0.Sincethisinformatisintendedtoonlyreadclocktimes,valuesresultingin
timesgreaterthan24:00:00orlessthan00:00:00willbeadjustedappropriatelysothattheresultwillbewithinthe24-hourclock.
CharactersRead Informat
17:52:00+00:00 E8601LZ14.
17:52:00Z E8601LZ9.
06:00:30.57+08:00 E8601LZ18.2
04:17:00-05:00 E8601LZ14.
4.3.3ISODatetimeInformats
B8601CIw.dB8601CIw.dreadsIBMtimevalueswithacenturymarkeroftheformcyyMMddhhmmss<fff>,wherecrepresentsthe
centurydigit.Thecenturydigitiscalculatedbysubtracting1900fromthecurrentyear,dividingby100,anddroppingtheremainder.yyisthetwo-digityearfrom00to99,MMrepresentsthenumberofthemonth,andddrepresentsthedayof
themonth.Thetimeisrepresentedbyhhmmss<fff>,wherehhindicatesthehours,mmisminutes,ssisthenumberofseconds,andfffindicatesthousandthsofseconds.wrangesfrom10to26,withadefaultvalueof16,whiledrangesfrom0to6forthefractionalpartofseconds.
However,itisimportanttonotethatthereareonly3placesofdecimalprecision.
CharactersRead Informat
11504231905 B8601CI16.
0560928053505 B8601CI16.
1140630102416454 B8601CI19.3
2131216094500 B8601CI16.
B8601DJw.dB8601DJw.dreadsdatetimesinstandardJavadateandtimenotationyyyyMMddhhmmssffffff,whereyyyyisthefour-digityear,MMrepresentsthenumber
ofthemonth,ddrepresentsthedayofthemonth,andtimeisrepresentedbyhhmmss<ffffff>,wherehhindicatesthehours,mmisminutes,ssisthenumberofseconds,andffffffindicatesmillionthsofseconds.wrangesfrom10to26,withadefaultvalueof16,whiledrangesfrom
0to6forthefractionalpartofseconds.ThefollowingtablegivesexamplesofhowtoapplythisinformattoyieldtheSASdatevaluethatcorrespondstothetextshownineachline.
CharactersRead
201607181108
20141123054509
201303070814433064
201406241630254
B8601DTw.d
B8601DTw.dreadsdatetimevaluesinthe
ISO8601basicdatetimenotationyyyyMMddThhmmssffffffwhereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffis
decimalfractionsofseconds.TistheISO8601delimiterfortime.NotethattherearenootherdelimitersintheISObasicdatetimestring,includingthedecimalfractions.wcanbefrom19to26,withadefaultwidthof19.dcanbefrom0to6,withadefaultof0.Itis
importanttonotethatifeithermonthordayismissing,SASwilluseavalueof1forthemonthand/ordaytoprovidethedatefortheSASdatetimevalue,whilesettingthehours,minutes,andsecondstozero.However,thismightnotbewhatyouwant,asyoursituationmightcallforan
algorithmtoimputedatetimeswithmissingmonthsand/ordays,and/ortimesinstead.
CharactersRead
20141007T133008745
20150716T0859003315
20140331T1404
20150903T06
20140804
201312
2016
E8601DTw.d
E8601DTw.dreadsdatetimevaluesinthe
ISO8601extendeddatetimenotationyyyy-MM-ddThh:mm:ss.ffffff,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffis
decimalfractionsofseconds.TistheISO8601delimiterfortime.wcanbefrom19to26,withadefaultwidthof19.dcanbefrom0to6,withadefaultof0.Unliketheparallelbasicdatetimeinformat,thereisnodefaultsubstitutionformissingdateand/ortimecomponents,so
theresultisamissingdatetimevalue.
CharactersRead Informat
2014-10-07T13:30:08
E8601DT19.
2015-07-16T08:59:00
E8601DT19.
2014-03-31T14:04
E8601DT19.
2015-09-03T06
E8601DT19.
2014-08-04 E8601DT19.
2013-12 E8601DT19.
2016 E8601DT19.
B8601DZw.d
B8601DZw.dreadsa
SASdatetimevaluebasedonthezeromeridianCoordinatedUniversalTime(UTC)intheISO8601basicdatetimeandtimezonenotationyyyyMMddThhmmssffffff+|-hhmm,whereyyyyisthefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericalday
ofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisthedecimalfractionofseconds.Thisisfollowedbythetimeoffset,whichisaplus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestof
themeridian),followedbytheoffsettimerepresentedashhmm.ThetimezoneoffsetmightalsobeindicatedbytheletterZ,representingthezeromeridian.TheoffsetiscalculatedfromthetimeatthezeromeridianinGreenwich,England,andtheresultingSASdatetime
valuewillbethedatetimeatthezeromeridian.wcanbefrom20to35,withadefaultwidthof26.dcanbefrom0to6,withadefaultof0.
CharactersRead
20150208T112705+0500
20150920T05045914-0400
20140511T211700Z
20140511T211700+0000
E8601DZw.d
E8601DZw.dreadsaSASdatetimevaluebasedonthezeromeridianCoordinatedUniversalTime(UTC)intheISO8601extendeddatetimeandtimezonenotationyyyy-MM-ddThh:mm:ss.ffffff+|–hh:mm,whereyyyyis
thefour-digityear,MMisthezero-paddedmonth,ddisthezero-paddednumericaldayofthemonth,hhrepresentszero-paddedhours,mmrepresentszero-paddedminutes,ssrepresentsseconds,andffffffisthedecimalfractionofseconds.Thisisfollowedbythetimeoffset,whichisa
plus(fortimezoneseastofthezeromeridian)oraminus(fortimezoneswestofthemeridian),followedbytheoffsettimerepresentedashh:mm.ThetimezoneoffsetmightalsobeindicatedbytheletterZ,representingthezeromeridian.Theoffsetiscalculatedfromthe
timeatthezeromeridianinGreenwich,England,andtheresultingSASdatetimevaluewillbethedatetimeatthezeromeridian.wcanbefrom20to35,withadefaultwidthof26.dcanbefrom0to6,withadefaultof0.
CharactersRead Informat
2015-02-08T11:27:05+05:00
E8601DZ26.
2015-09-20T05:04:59.14-04:00
E8601DZ29.2
2014-05- E8601DZ26.
2014-05-
11T21:17:00Z
E8601DZ26.
2014-05-11T21:17:00+00:00
E8601DZ26.
4.4TimeZoneFunctions
4.4.1IntroductionThereareseveraltimezonefunctionsavailableinSAS.TheyareprovidedaspartofNationalLanguageSupport(NLS),butthesefunctionsarecoveredinthissectionbecausethisiswheretheformatsand
informatsthatprovidefortimezoneoffsetsandsupportforUTCaredetailed.
Forallofthefollowingfunctions,time-zone-idrepresentsaSAStime-zoneIDvalue.Itisalsoanoptionalargumentinthesefunctions.Ifitisnotprovided,thefunctionwillusethe
currentsettingoftheTIMEZONE=systemoptionasthedefault.Beforeusingthesefunctions,youneedtocheckthesettingofyourTIMEZONE=systemoptiontomakesurethatitdoeshaveavalue,ormanyofthesefunctionswillproduceamissingresult.Thisoptioncanbelockedby
yourSASadministrator.
4.4.2TheTIMEZONE=OptionManyoftheISOtimeanddatetimeformatsusetheTIMEZONE=systemoption,whichisavailableasofSAS
version9.4.TheTIMEZONE=systemoptionallowsyoutosetatimezonebasedonageographicallocation.Itisnotsetbydefault.Thisoptionaffectsthefollowing:
•Timesthatarerecordedinlogsandevents.•Creationand
modificationtimestampsonSASdatasets•TheDATE(),DATETIME(),TIME(),andTODAY()functions•ThetimezoneformatsB8601DXw.d,E8601DXw.d,B8601LXw.d,
E8601LXw.d,B8601TXw.d,E8601TXw.d,NLDATMZw.,NLDATMTZw.,andNLDATMWZw.•ThetimezonefunctionsdescribedinSection4.4.3.
Thevalueoftheoptionmayberepresentedinoneoftwoways:It
maybeathree-orfour-letteracronymthatdescribesthetimezone(forexample,EST,forEasternStandardTime),oratime-zoneIDthatspecifiesaregionandanarea,separatedbyaforwardslash(/),suchas"America/New_York."ThetimezoneIDvaluesareuniqueand
compatiblewithJavatimezonenames,whilethethree-orfour-letterabbreviationsarenot.Considertheabbreviation“CST”,whichstandsfor"ChinaStandardTime,"or"CubaStandardTime,"or"CentralStandardTime."HowdoesSASchoosewhat"CST"representsinyour
program?ItusesthevalueoftheLOCALE=systemoptiontodecidewhatthecorrectregionandareashouldbe.Ofcourse,ifyouarerunningaSASprogramintheUnitedStates,butareusingtheLOCALE=systemoptiontoproduceoutputforanothergeographicalregion,
thismaycauseincorrecttiming.IwouldrecommendusingthetimezoneIDinsteadoftheacronymsasabestpractice.Thereareover500timezoneIDvalues;consulttheSASdocumentationtofindthetimezoneIDvaluesyouneed.
4.4.3ListofTimeZoneFunctionsNotethatallofthesefunctionsareonlyavailablebeginningwithSASversion9.4.
TZONEID(time-zone-id)TZONEIDwillreturn
eitherthecurrenttimezoneIDiftime-zone-idisavalidvalue,orablankwhentime-zone-idismissingorinvalid.Note:PriortoSAS9.4TS1M2,supplyingatime-zone-idforthisfunctionwillcauseanerror.
Sample
FunctionCall
OPTIONSTIMEZONE=
TZONEID()
TZONEID() Africa/Addis_Ababa
TZONEID() Africa/Brazzaville
TZONEID() America/Montreal
TZONENAME(time-
zone-id,datetime-value)
TZONENAMEreturnsthecurrenttimezonenamebasedonthetimezoneIDandanydaylightsavingtimerules.Thisfunctionwillreturnablankiftime-zone-idismissing,ortheTIMEZONE=
systemoptionhasnovalue.Inthefollowingexample,theTIMEZONEoptionissetto'America/Chicago.'
SampleFunctionCall
TZONENAME()
TZONENAME('06JUN2014:08:00'dt)
TZONENAME('06JAN2015:08:00'dt)
TZONEOFF(time-zone-id,datetime-value)
TZONEOFFreturnsthetimezoneoffsetfromCoordinatedUniversalTime(UTC)basedontimezonename,andstandardordaylightsavingtimerules.Iftime-zone-idisblankormissing,theoffsetwillbedeterminedfromthesystemclock.Inthefollowingexample,theTIMEZONEoptionis
setto'Europe/Stockholm.'
SampleFunctionCall
TZONEOFF()
TZONEOFF('06JUN2014:08:00'dt)
TZONEOFF('06JAN2015:08:00'dt)
TZONES2U(datetime-value,time-zone-id)
TZONES2UconvertsaSASdatetimevaluetoaCoordinatedUniversalTime(UTC)datetimevaluebasedonthetimezoneanddaylightsavingrules.Iftime-zone-idisblankormissing,theoffsetwillbedeterminedfromthesystemclock.Inthefollowingexample,theTIMEZONEoptionis
setto'America/Chicago.'
SampleFunctionCall
TZONES2U('11NOV2014:12:00'dt)
TZONES2U('11NOV2014:12:00'dt,'Pacific/Guam')
TZONES2U('11NOV2014:12:00'dt,'Europe/Istanbul')
TZONEDSTNAME(time-
zone-id)
TZONEDSTNAMEreturnsthedaylightsavingtimeabbreviationforthetimezoneID.Iftime-zone-idismissing,andtheTIMEZONE=optionisnotset,youwillreceivea"NOTE:Invalidargumenttofunction
TZONEDSTNAME()"messageinthelog.Ifthetimezoneprovideddoesnotfollowdaylightsavingtime,thentheresultwillbemissing.Inthefollowingexample,theTIMEZONEoptionissetto'America/Chicago.'
SampleFunctionCall
TZONEDSTNAME()
TZONEDSTNAME('Asia/Calcutta')
TZONEDSTNAME('America/Sao_Paulo')
TZONEDSTOFF(time-zone-id)
TZONEDSTOFFreturnsthetimezoneoffsetvalueforthespecifieddaylightsavingtime.If
time-zone-idismissing,andtheTIMEZONE=optionisnotset,youwillreceivea"NOTE:InvalidargumenttofunctionTZONEDSTOFF()"messageinthelog.Inthefollowingexample,theTIMEZONEoptionissetto'America/Chicago.'
SampleFunctionCall
TZONEDSTOFF()
TZONEDSTOFF('Asia/Calcutta')
TZONEDSTOFF('America/Sao_Paulo')
TZONESTTNAME(time-zone-id)
TZONESTTNAMEreturnsthestandardtimenameforthetime
zoneID.ThisfunctiondiffersfromtheTZONEDSTNAME()functioninthatitprovidesthestandardtimeabbreviationasopposedtothedaylightsavingtimeabbreviation.Iftime-zone-idismissing,andtheTIMEZONE=optionisnotset,youwillreceivea"NOTE:
InvalidargumenttofunctionTZONESTTNAME()"messageinthelog.Inthefollowingexample,theTIMEZONEoptionissetto'Pacific/Honolulu.'
SampleFunctionCall
TZONESTTNAME()
TZONESTTNAME('Australia/Sydney')
TZONESTTNAME('Asia/Dubai')
TZONESTTOFF(time-zone-id)
TZONESTTOFFreturnsthetimezoneoffsetvalueforthespecifieddaylightsavingtime.Iftime-zone-idismissing,
andtheTIMEZONE=optionisnotset,youwillreceivea"NOTE:InvalidargumenttofunctionTZONESTTOFF()"messageinthelog.Inthefollowingexample,theTIMEZONEoptionissetto'Pacific/Honolulu.'
SampleFunctionCall
TZONESTTOFF()
TZONESTTOFF('Australia/Sydney')
TZONESTTOFF('Asia/Dubai')
TZONEU2S(UTC-datetime-value,time-zone-id)
TZONEU2SconvertsaCoordinatedUniversalTime(UTC)datetimevaluetoaSASdatetimevalue.Iftime-zone-idisblankormissing,theoffsetwillbedeterminedfromthesystemclockandaccordingtodaylightsavingtimerulesineffect.Inthefollowingexample,the
TIMEZONEoptionissetto'America/Chicago.'
SampleFunctionCall
TZONEU2S('11NOV2014:12:00'dt)
TZONEU2S('11NOV2014:12:00'dt,'Pacific/Guam')
TZONEU2S('11NOV2014:12:00'dt,'Europe/Istanbul')
4.5ISO8601DurationsandIntervalsTheISO8601standardalsoprovidesawaytodescribetheintervalbetweentwodatetimes,oraperiodoftimeoverwhichaneventhasoccurred.Anintervalcanbeexpressedby
usingthestartingandendingdatetimes,oradurationandastartingtime.Durationscanbeexpressedbyprovidingthelengthoftimeinacommonform.However,ISO8601durationsandtimeintervalsdonotdirectlyequatetoasinglepointintime,whileeverythingelse
intheSASdateandtimefacilityrepresentsonespecificpointintime.Nonetheless,SASgivesyoutheabilitytohandledurationsandintervalssothatyouhaveaccesstoallthefunctionalityoftheSASdateandtimefacility.
UnlikeeveryotherpartoftheSASdateand
timefacility,ISO8601durationsandintervalsarestoredincharactervariables,buttheyarenotstoredassimpletext.YoucannotconvertadatetimetoacharacterstringusingthePUT()functionandthenconcatenateitwithadurationstringoranotherdatetimethathasbeenconverted
toacharacterstring.InordertousetheSASdateandtimecapacitywithISOdurationsandintervals,youmustfirstconvertISOdurationandintervalvaluestoaninternalrepresentation.Thisisverymuchthesameprocessthatyouhavetoundertakewhenyouareworkingwithdates
andtimesasweunderstandthem;youmustturnthemintovaluesthatSASunderstandsortakethevaluesthatSASunderstandsandtranslatethemintotherepresentationthatweunderstand.
Therefore,SAShasformatsandinformats
dedicatedtotranslatingthisinternalrepresentationofISOdurationsandintervals.Theinternalrepresentationcannotbeusedwithoutthistranslation.ThereisalsooneextremelyimportantCALLroutinethatisusedtoeffectthetransformationbetweenISOdurations
andintervalstoorfromSASdate,time,anddatetimevalues.First,weshouldtalkabouttheformsofISOdurationsandintervals.
4.5.1ISODurationandIntervalRepresentations
ISODurationRepresentationsISOdurationsarerepresentedinthreeways.Thereisnopreferenceorpriorityattachedtoanyoftheforms:Usetheonethatbestfitsyourdata.OneformisPnYnMnDTnHnMnS,wherePistheindicator
forperiod,andisprecededbyaminussigniftheperiodrepresentedisnegative(the"starting"dateordatetimecomesafterthe"ending"dateordatetime),Yistheindicatorforyears,Mformonths,andDfordays.TheTistheindicatorfortimeandmustbepresentifthere
isatimecomponenttothedurationstring.Histheindicatorforhours,theMtotherightoftheTindicatorisforminutes,andtheSistheindicatorforseconds.nrepresentsanumber.Thisformofdurationdescriptionisthesameforboththebasicandextendednotation,asthereare
nodelimitersnecessary.
AnotherdurationformisPnW,whichisonlyusedtodescribeadurationmeasuredinweeks.nrepresentsanumber,andtheWistheindicatorforweeks.Aswiththepreviousform,whenthestartingdateordatetimeis
afterthe"ending"dateordatetime,thePisprecededbyaminussign.Again,sincetherearenodelimitersinthisform,theoutputusingbasicandextendednotationisidentical.
ThelastofthedurationformsisPyyyyMMddThhmmssfffinbasicnotation,or
Pyyyy-MM-ddThh:mm:ss.fff,intheextendednotation,whereyyyyisthenumberofyears,MMisthenumberofmonths,ddisnumberofdays,hhrepresentsnumberofhours,mmrepresentsminutes,andssrepresentssecondsintheperiod,withfffasdecimalfractionsof
secondsuptothemillisecond.TistheISO8601delimiterfortime.ThisdurationformcanalsoberepresentedasPyyyyMMddorPyyyy-MM-ddifthereisnotimecomponent.Aswiththeotherdurationforms,ifthe"start"islaterthanthe"end,"thePwillbeprecededbya
minussign.
ISOIntervalRepresentationsISOintervalsarerepresentedbytwodatetimesthatrepresentthestartandendoftheinterval,oradurationandadatetimethatrepresentseitherthe
startorendoftheinterval.Thedatetime/datetimeformisyyyyMMddThhmmss/yyyyMMddinthebasicnotation,oryyyy-MM-ddThh:mm:ss/yyyy-MM-ddThh:mm:ssintheextendednotation.Theslashorsolidus(/)betweenthetwodatetimesisarequired
delimiterwhenusingeithernotation.
Inthebasicnotation,theduration/datetimeformis:PnYnMnDTnHnMnS/yyyyMMddwhenthedatetimerepresentstheendoftheinterval,oryyyyMMddThhmmssfff/whenthedatetimevaluerepresentsthe
beginningoftheinterval.Inextendednotation,theformsareyyyy-MM-ddThh:mm:ss.fff/PnYnMorPnYnMnDTnHnMnS/yyyy-MM-ddThh:mm:ss.fff.ThedurationsegmentisspecifiedbyP,theindicatorforperiod,Yistheindicatorforyears,Mformonths,D
fordays.TheTistheindicatorfortime,andmustbepresentifthereisatimecomponenttothedurationstring.Histheindicatorforhours,theMtotherightoftheTindicatorisforminutes,andtheSistheindicatorforseconds.nrepresentsanumber.
4.5.2ISO8601DurationandIntervalFormatsThefirstthingyoumightnoticeabouttheISOdurationandintervalformatsisthat,unlikeanyoftheotherdate-andtime-relatedformatsinSAS,theyarecharacterformats,
asindicatedbytheleadingdollarsign($).Thisisreasonable,sincedurationsandintervalsarestoredascharactervalues.Whydoyouneedformatsforcharactervariables?SASstoresISOdurationsandintervalsinaninternalform,sojustasyouneedformatstoconvert
betweenSASdatevaluesandhowweunderstanddates,youneedtheseformatstoperformtheconversionfromthestoredformtothecorrespondingISO8601representation.Here'sanexamplethatshowswhatthestoredformofdurationandintervalvalueslookslike,alongwithits
formatteddisplay.TheexampleusestheCALLIS8601_CONVERTroutinetocreatetheinternalrepresentations,andwewilldiscussthisroutine,itssyntax,anduseindetailinsection4.5.4.
Example4.1:WhyFormatsareNecessarywithISO
Durations,Intervals,andDatetimes
1.DATAisostore;2.SETisotest;3.LENGTHresult1-result2$32;4.CALLIS8601_CONVERT('dt/dt','du',dt1,dt2,result1);5.CALLIS8601_CONVERT("dt/dt",'intvl',dt1,dt2,result2);6.fmt_result1=PUT(result1,$N8601E.);7.fmt_result2=PUT(result2,$N8601E.);8.RUN;
Theabovecodewilltakethedatetimevaluesdt1anddt2fromadataset.TheCALLIS8601_CONVERTinline4createsanISOdurationvalueinthevariableresult1,whiletheoneinline5createsanISOintervalvalueinthevariableresult2.Thetwo
resultsarethenformattedinnewvariablesusingthePUTfunction.Thevaluesinthisdatasetaredisplayedbelow.
Startofperiod(dt1)
04MAR2014:10:23:23
IntervalValueStoredinDataset(result2)
20143041023230012014C28230403001
Clearly,thestoreddurationandintervalvalues(italicizedintheabovetable)arenotintheISO8601format,soSASprovidesthefollowingformatsto
translatethemintothedesiredrepresentation.
$N8601Bw.d$N8601Bw.writesduration,datetime,andintervalvaluesintheISO8601basicnotation.Thisformatdiffersfromthe$N8601BA.formatinthatitdisplays
durationsintheformPnYnMnDTnHnMnSinsteadofPyyyymmddThhmmss.Itisleft-justified,andwcanbefrom1to200,withadefaultwidthof50.Inordertodisplaydatetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplayintervalvalues
correctly,theminimumwidthis32.Inversion9.4,SASwillautomaticallyprovideupto3decimalplacesforthesecondscomponentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbe
displayed).Thenumberofdecimalplacesshownisdependentupontheformatwidth.TheformatwilldisplaythedurationvalueasanISOdurationandanintervalvalueasanISOintervalwithoutanyadditionalprogramming.SASchoosesoneofthefollowingformsbased
ontheinformationstoredintheISOduration,datetime,orintervalvariable:
•PnYnMnDTnHnMnS•PnYnMnDTnHnMnS/•yyyymmddThhmmssfff•
yyyymmddThhmmssfff•yyyymmddThhmmssfff
$N8601BAw.d
$N8601BAw.writesduration,datetime,andintervalvaluesintheISO8601basicnotation.Thisformatdiffersfromthe$N8601B.formatin
thatitdisplaysdurationsintheformPyyyymmddThhmmssinsteadofPnYnMnDTnHnMnS.)Itisleft-justified,andwcanbefrom1to200,withadefaultwidthof50.Inordertodisplaydatetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplay
intervalvaluescorrectly,theminimumwidthis32.Ifyouattempttodisplayanintervalwithawidthspecificationoflessthan32,youwillgetaseriesofasterisks(*)asyouroutput.Inversion9.4,SASwillautomaticallyprovideupto3decimalplacesfortheseconds
componentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbedisplayed).Whetherone,two,orthreedecimalplacesareshownisdependentupontheformatwidth.Theformatwilldisplay
thedurationvalueasanISOdurationandanintervalvalueasanISOintervalwithoutanyadditionalprogramming.SASchoosesoneofthefollowingformsbasedontheinformationstoredintheISOduration,datetime,orintervalvariable:
•PyyyymmddThhmmss•yyyymmddThhmmss•PyyyymmddThhmmss/yyyymmdd•yyyymmddThhmmss/P•yyyymmddThhmmss/
$N8601Ew.
$N8601Ew.writesduration,datetime,andintervalvaluesintheISO8601extendednotation.Itisleft-justified,andwcanbefrom1to200,withadefaultwidthof50.Inordertodisplaydatetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplay
intervalvaluescorrectly,theminimumwidthis32.Ifyouattempttodisplayanintervalwithawidthspecificationoflessthan32,youwillgetaseriesofasterisks(*)asyouroutput.Inversion9.4,SASwillautomaticallyprovideupto3decimalplacesfortheseconds
componentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbedisplayed).Whetherone,two,orthreedecimalplacesareshownisdependentupontheformatwidth.Theformatwilldisplay
thedurationvalueasanISOdurationandintervalvaluesasanISOintervalwithoutanyadditionalprogramming.SASchoosesoneofthefollowingformsbasedontheinformationstoredintheISOduration,datetime,orintervalvariable:
•PnYnMnDTnHnMnS•yyyy-mm-ddThh:mm:ss.fff•PnYnMnDTnHnMnS/mm-ddThh:mm:ss.fff•yyyy-mm-ddThh:mm:ss.fff/PnY•yyyy-mm-ddThh:mm:ss.fff/yyyy-
mm-ddThh:mm:ss.fff
$N8601EAw.
$N8601EAw.writesduration,datetime,andintervalvaluesintheISO8601extendednotation.Itisleft-justified,andwcanbefrom1to200,withadefaultwidthof50.In
ordertodisplaydatetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplayintervalvaluescorrectly,theminimumwidthis32.Ifyouattempttodisplayanintervalwithawidthspecificationoflessthan32,youwillgetaseriesofasterisks(*)as
youroutput.Inversion9.4,SASwillautomaticallyprovideupto3decimalplacesforthesecondscomponentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbedisplayed).Whether
one,two,orthreedecimalplacesareshownisdependentupontheformatwidth.TheformatwilldisplaydurationvaluesasanISOdurationandintervalvaluesasanISOintervalwithoutanyadditionalprogramming.SASchoosesoneofthefollowingformsbased
ontheinformationstoredintheISOduration,datetime,orintervalvariable:
•Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff•Pyyyy-mm-ddThh:mm.ss.fff/yyyy-mm-ddThh:mm.ss.fff
•yyyy-mm-ddThh:mm.ss.fff/Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff/yyyy-mm-ddThh:mm.ss.fff
$N8601EHw.
$N8601EHw.writesduration,datetime,and
intervalvaluesintheISO8601extendednotation,substitutinghyphensforanymissingcomponents.Withthisformat,omitteddatetimecomponentsarealwaysdisplayed.Itisleft-justified,andwcanbefrom1to200,withadefaultwidthof50.Inordertodisplay
datetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplayintervalvaluescorrectly,theminimumwidthis32.Ifyouattempttodisplayanintervalwithawidthspecificationoflessthan32,youwillgetaseriesofasterisks(*)asyouroutput.Inversion
9.4,SASwillautomaticallyprovideupto3decimalplacesforthesecondscomponentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbedisplayed).Whetherone,two,orthree
decimalplacesareshownisdependentupontheformatwidth.TheformatwilldisplaydurationvaluesasanISOdurationandintervalvaluesasanISOintervalwithoutanyadditionalprogramming,anditwilldisplaytheminoneofthefollowingforms.SASchoosesone
ofthefollowingformsbasedontheinformationstoredintheISOduration,datetime,orintervalvariable:
•Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff•Pyyyy-mm-ddThh:mm.ss.fff/yyyy-
mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff/Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff/yyyy-mm-ddThh:mm.ss.fff
$N8601EXw.
$N8601EXw.writesduration,datetime,andintervalvaluesintheISO8601extendednotation,substitutingtheletter"x"foranymissingcomponents.Withthisformat,omitteddatetimecomponentsarealwaysdisplayed.Itisleft-justified,andwcanbefrom1to200,witha
defaultwidthof50.Inordertodisplaydatetimeanddurationvaluescorrectly,thewidthmustbeatleast16,whiletodisplayintervalvaluescorrectly,theminimumwidthis32.Ifyouattempttodisplayanintervalwithawidthspecificationoflessthan32,youwillgeta
seriesofasterisks(*)asyouroutput.Inversion9.4,SASwillautomaticallyprovideupto3decimalplacesforthesecondscomponentofthesevalues(indicatedbelowbyfff),regardlessofsignificance(thatis,ifthereisnodecimalfractionofseconds,thenzeroswillbe
displayed).Whetherone,two,orthreedecimalplacesareshownisdependentupontheformatwidth.TheformatwilldisplaydurationvaluesasanISOdurationandintervalvaluesasanISOintervalwithoutanyadditionalprogramming.SASchoosesoneofthe
followingformsbasedontheinformationstoredintheISOduration,datetime,orintervalvariable:
•Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff•Pyyyy-mm-ddThh:mm.ss.fff/yyyy-mm-
ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff/Pyyyy-mm-ddThh:mm.ss.fff•yyyy-mm-ddThh:mm.ss.fff/yyyy-mm-ddThh:mm.ss.fff
4.5.3ISO8601Durationand
IntervalInformatsInordertostoreduration,interval,anddatetimevaluesthatarealreadyrepresentedintheirISO8601formascharacterstrings,youwillneedtousethefollowinginformatswiththeINPUTstatementorINPUT()
function.TheCALLIS8601_CONVERTroutineisdesignedtoworkwithSASdate,time,anddatetimevalues,notcharacterstrings.
$N8601Bw.$N8601Bw.willtranslateduration,datetime,andinterval
stringswrittenintheISO8601basicorextendednotationintotheSASinternalrepresentationforthesevalues.Missingcomponentsarecorrectlyprocessedaslongasasinglehyphen(-)isusedinplaceofeachmissingcomponent.wcanbefrom1to200,witha
defaultwidthof50.Inordertoprocessdatetimeanddurationvaluescorrectly,wmustbeatleast16,whiletoprocessintervalvaluescorrectly,wmustbeatleast32.Theinformatwillprocessdatainanyoneofthefollowingforms:
ISOFormRead
Pyyyy-mm-ddThh:mm:ss
PyyyymmddThhmmss
PnYnMnDTnHnMn.fffS
PnYnMnDTnHnMn.fffS
PnW
yyyy-mm-ddThh:mm:ss.
yyyymmddThhmmssfff/yyyymmdd
PnYnMnDTnHnMn.fffS/
yyyy-mm-ddThh:mm:ss.
yyyy-mm-ddThh:mm:ss.
yyyymmddThhmmss.fff
$N8601Ew.
$N8601Ew.willtranslateduration,datetime,andintervalstringswrittenintheISO8601extendednotationintotheSASinternalrepresentationforthesevalues.This
informatdiffersfromthe$N8601B.informatinthatitwillonlyprocessvaluesthatareintheISO8601extendedformat.Ifyouattempttoreadavalueinthebasicnotationwiththisinformat,youwillgetanerror,andthestoredresultwillbeamissingvalue.Thisinformatisusefulwhen
youneedtoenforceadherencetotheextendednotation.Missingcomponentsarecorrectlyprocessedaslongasasinglehyphen(-)isusedinplaceofeachmissingcomponent.wcanbefrom1to200,withadefaultwidthof50.Inordertoprocessdatetimeandduration
valuescorrectly,wmustbeatleast16,whiletoprocessintervalvaluescorrectly,wmustbeatleast32.
Todemonstratethedifferencebetweenthe$N8601B.and$N8601E.informats,theexamplebelowwillusethesameduration
stringinboththebasicandextendednotationsandtrytoprocessitwitheachinformat.
Example4.2:The$N8601B.Informatversusthe$N8601E.Informat
stored=INPUTC(duration_string,inf);
Example4.2usestheabovecodetostorethe
durationstring.infrepresentstheinformatbeingused.
ReadingtheISO8601BasicNotation
InformatUsed DurationString
$N8601B. P00020806T0100
$N8601E. P00020806T0100
Asyoucansee,the$N8601E.informatfailedtoprocessthebasicnotationstring,resultinginamissingvalue.WhenyoutrytoprocessastringintheISObasicnotationusingtheextendednotation-specificinformat,youwillgetthefollowingnoteinyourlog.
NOTE:InvalidargumenttofunctionINPUTatlinexxxcolumnyy.
Nowlet'sseewhathappenswhenwetrytoprocesstheextendednotationstring.
ReadingtheISO8601ExtendedNotation
Informat Duration Stored
Used String Representation
$N8601B. P0002-08-06T01:00
$N8601E. P0002-08-06T01:00
Inthiscase,both
informatscausedSAStostoreidenticalvalues.The$N8601B.informatcanprocessbothbasicandextendednotations,butthe$N8601E.informatwillonlyworkwiththeextendednotation.Usethe$N8601E.informatifyouwanttomakesurethattheinputdataconformtothe
extendednotation.
4.5.4CALLIS8601_CONVERTItisimportanttounderstandthatalthoughISOdurationsandintervalsarestoredincharactervariables,theyarenotsimpletext.Youcannotconvertadatetimetoa
characterstringusingthePUT()functionandthenconcatenateitwithadurationstringoranotherdatetimethathasbeenconvertedtoacharacterstring.InordertousetheSASdateandtimecapacitywithISOdurationsandintervals,youmustfirstconvertISOdurationandintervalvaluesto
aninternalrepresentationthatwillallowthis.
Theformatsandinformatswejustdiscussedwillworkoncharactervalues,butwhatifyouhaveSASdateordatetimevalues,whichofcoursearestoredinnumericvariables,andyou
wanttousethosetobuildyourISOdurationsandintervals?TheCALLIS8601_CONVERTroutineperformsthisconversioninbothdirections,soitwillcreateyourISOdurationsandintervalsfromthoseSASdateanddatetimevalues.Itwillalsodothereverse,
andtransformyourISOdurationsandintervalsintotheirindividualdateanddatetimecomponents.Inordertocreateanintervaloraduration,youwillneedtwovalues:astartandanend(definedasdatesordatetimes),oryoucanprovideaduration,andeitherstartoranend.
Similarly,inordertoconvertaninterval,youwillbesplittingthecomponentsintotwovariables,adurationandadatetime,ortwodatetimes.Inaddition,theroutinecanderivethestartingorendingpointofanISOdurationorinterval.
Thesyntaxforthe
CALLIS8601_CONVERTroutineis:
CALLIS8601_CONVERT(convert-from,convert-to,from--variables,to-variables,replacements);
Theconvert-fromargumentdescribesthetypeof
date/datetime/interval/durationdatathatyouareconverting.convert-fromcanbeoneofthefollowingkeywordvalues,enclosedinquotationmarks,ormightalsoberepresentedbyacharactervariablethatresolvestooneofthesevalues.
KeywordValue
Description
'dn' Usethiswhenthevaluethatyouwanttoconvertconsistsofindividualcomponentsofadatevalue.n
from1to6,andindicateshowmanycomponentsareinthelistoffrom-variablesYoucancreateeitheradateoradatetimevaluewiththis
argumenttype.Theindividualcomponentsfromlefttorightare:month,day,year,hour,minute,andsecond.
'dtn' Usethiswhenthevaluethatyou
wanttoconvertareindividualcomponentsofadatetimevalue.isfrom1to6,andindicateshowmanycomponentsareinthelistoffrom-variables
Youcancreateeitheradateoradatetimevaluewiththisargumenttype.Theindividualcomponentsfromlefttorightare:month,day,year,
hour,minute,andsecond.
'dun' Usethiswhenyouwanttoconvertavalueconsistingofindividualcomponentsofadurationvalue.isfrom1to6,
andindicateshowmanycomponentsareinthedurationvalue.Theindividualcomponentsfromlefttorightarethenumberofmonths,days,
years,hours,minutes,andsecondsintheduration.
'dt/dt' Usethiswhenyouareconvertingtwodatetimevalues.
'dt/du' Usethiswhenyouareconvertingadatetime/durationinterval.Thissignifiesthatthedatetimeisthestartoftheintervalthatyouareconverting.
'du/dt' Usethistoconvertaduration/datetimeinterval.Thissignifiesthatthedatetimeistheendoftheintervalthatyouareconverting.
'intvl' Usethistoconvertintervalvalues.
Theconvert-toargumentdescribestheformoftheresultfromtheCALLIS8601_CONVERTroutine.
KeywordValue Description
'intvl' Usethistocreateanintervalvalue.
'dt/dt' Usethistocreateadatetime/datetimeinterval.
'dt/du' Usethistocreate
'dt/du' Usethistocreate
adatetime/durationinterval.Thissignifiesthatthedatetimeisthebeginningoftheinterval.
'du/dt' Usethistocreatea
duration/datetimeinterval.Thissignifiesthatthedatetimeistheendoftheinterval.
'du' Usethistocreateaduration.
'start' Usethistoderive
'start' Usethistoderive
astartingdateordurationfromanintervalvalue.
'end' Usethistoderivetheendingdateordurationfromanintervalvalue.
'dn' Usethiswhenyou
wanttocreateindividualcomponentsofadatevalue.n1to6,andindicateshowmanycomponentsareinthelistoffrom-variables.The
individualcomponentswillbestoredfromlefttorightinthefollowingorder:month,day,year,hour,minute,andsecond.
'dtn' Usethiswhenyou
wanttocreateindividualcomponentsofadatetimevalue.from1to6,andindicateshowmanycomponentsareinthelistoffrom-variables.The
individualcomponentswillbestoredfromlefttorightinthefollowingorder:month,day,year,hour,minute,andsecond.
'dun' Usethistocreate
'dun' Usethistocreate
individualcomponentsofadurationvalue.from1to6,andindicateshowmanycomponentsareinthelistoffrom-variables.Theindividual
componentswillbestoredfromlefttorightinthisorder:thenumberofmonths,days,years,hours,minutes,andseconds.
from-variablesarethe
variablescontainingthevalue(s)tobeconverted.Specifyonevariableifyouareconvertinganintervalandtwofordatetimeand/ordurationvalues.Ifyouareconvertingindividualcomponentsofadateoradatetime(using'dn,''dtn,'or'dun'inyourconvert-fromargument),then
youwillneedonevariableforeachcomponentspecified.Ifyouareconvertinganinterval,thevariablemustbeatleast32charactersinlength.
to-variablesarethevariablescontainingtheresultthattheroutinecalculates.Specifyonevariableif
youarecreatinganintervalandtwofordatetimeand/ordurationvalues.Ifyouwantindividualcomponentsofadateoradatetimefromthefunction(using'dn,''dtn,'or'dun'inyourconvert-toargument),thenyouwillneedonevariableforeachcomponentspecified.
replacementsenablesyoutoprovideyourownvalueforthemonth,day,hour,minute,andsecondcomponentstobeusedifanyofthosecomponentsaremissingintheconvert-fromargument.Thedefaultis1formonthandday,and0forhour,minute,and
second.Whenyouusethisparameter,eventhoughtheyearcomponentisrequiredforavalidISOdurationorintervalvalue,youwillneedaleadingcommaasaplaceholderfortheyearvalue,followedbyall5replacementvalues,separatedbycommas.Whileitis
possibletoleavesomeofthereplacementvaluesblank(andtherebyusethedefault),itiseasiertoreadwhenavalueisprovidedforeachofthereplacements,evenifitisthesameasthedefault.
Thefollowingexamplesdemonstratemanyof
thecapabilitiesoftheCALLIS8601_CONVERTroutine,includingtheabilitytoperformdateandtimecalculations.
Example4.3:HowLongIs…inSAStime?MostofthecalculationsinvolvingSASdates
andtimeshaveaspecificreferencepointinmind;ingeneral,thereisadateand/oratimeinvolved,suchasJune8,2014,at3:50p.m.However,whatcanyoudoifyouwanttomeasureanISOdurationinSAStime?OnepossibilityistouseasamplestartingpointandSASintervalsto
obtaintheendpoint.Fromthere,itisjustamatterofsubtractingyourdummystartpointfromyourendpoint.OryoucoulduseCALLIS8601_CONVERT.Thefirstperiodissimple:Howlongisfourweeksexpressedintime?Thesecondperiodasksthesamequestionfor3days,4hours,27
minutes,and16.8seconds,whichisnotsoeasytodowithSASintervals.
1.DATAhowlong;2.LENGTHperiod$16;3.period="P4W";4.CALLIS8601_CONVERT('du','du',period,howlong);5.howlong_disp=STRIP(PUT(howlong,time10.1));6.OUTPUT;7.period="P3DT4H27M16.8S";
8.CALLIS8601_CONVERT('du','du',period,howlong);9.howlong_disp=STRIP(PUT(howlong,time10.1));10.OUTPUT;11.RUN;
Inlines4and8,weuse'du'astheconvert-toargumentbecausethereisnoargumentvaluethatwillexplicitlygiveatimevalue.However,whenyouusethe'du'
argumentanddonotspecifytheresultasacharactervariable,CALLIS8601_CONVERTwillcreateyourdurationinseconds(thatis,aSAStimevalue).HereisthePROCPRINTofourHOWLONGdataset:
ISO8601Duration
TimeinSeconds
P4W 2419200.0
P3DT4H27M16.8S 275236.8
Example4.4:ConvertingTwoDatetimestoanISO
DurationThissituationisonefrequentlyencounteredinclinicaltrials.Thestartingandendingdatetimesforaneventwouldbepresentedastext,andyouneedtocalculatethedurationanddisplayitinISO8601formataccordingtotheCDISC
specification.Inthisexample,wewilltakesimulatedeventdata(someofwhichhasmissingcomponentsandentiremissingvalues),calculatethedurations,andpresenttheresultaccordingtotheISOstandard.Herearethedatashownintheiroriginaltextrepresentation.
ObsStartingDate
EndingDate
1
2 2013-01-18T09:30
2013-01-18T21:00
3 2012-12-30T11
2013-01-01T14:00
4 2012-11 2013-01-
04
5 2012-11-19
2013-01-04
6 2012-11-20T08:30
2013-01-03
7 2012 2013-02
8 2012-12-27
9 2012-11 2012-11-20
10 2012-11-19T14:15
2012-11-20
11 2012-12-17T08:20
2013-01-02T09
ThefirststepistocreatetheseasSAS
datetimevalues.Let'srunaquickSASprogramtocreateourexampledataset,AEDTM:
DATAbook.aedtm;INFILE"eventdata.txt"PADMISSOVERDLM='09'xFIRSTOBS=2DSD;INPUTaestdtm:E8601DT.aeendtm:E8601DT.;FORMATaestdtmaeendtmdatetime20.;RUN;
Executingthiscoderesultsinthisdataset:
Whathappenedhere?Mostofthedatetimevaluesaremissing!
Thisisadirectconsequenceofincompletedatafordatesandtimesinthesourcedata.RememberthatSASdatetimevaluesareacompletedateandacompletetime,soyes,thevaluesaremissingbecausethereisnocompletedateandtimeinmostofthesecases.TheISO
standardcanaccommodatepartialdatesandtimes,butthenormalSASdateandtimefacilitycannot.Let'strythisadifferentwayusingtheISO8601informats.
DATAbook.aedtm2;INFILE"eventdata.txt"PADMISSOVERDLM='09'xFIRSTOBS=2DSD;INPUTaestdtm:$N8601B.
aeendtm:$N8601B.;FORMATaestdtmaeendtmdatetime20.;RUN;
Thiscodedidn'tevenrun,givinganerrorinthelog.
1DATAbook.aedtm2;2INFILE"eventdata.txt"PADMISSOVERDLM='09'xFIRSTOBS=2DSD;3INPUTaestdtm:$N8601B.aeendtm
:$N8601B.;4FORMATaestdtmaeendtmdatetime20.;-----------48ERROR48-59:Theformat$DATETIMEwasnotfoundorcouldnotbeloaded.
5RUN;
NOTE:TheSASSystemstoppedprocessingthisstepbecauseoferrors.WARNING:ThedatasetBOOK.AEDTM2maybe
incomplete.Whenthisstepwasstoppedtherewere0observationsand2variables.
TheISOinformatsonlycreatecharactervariables.Therefore,theerrorariseswhenyoutrytouseanumericformatwithacharactervariable.Atthispoint,weareno
closertogettingourdurationsthanbefore.WhathappenswhenwetaketheFORMATstatementout?
Nowwe'vegottheinternalrepresentation
ofISOdatetimesinaSASdataset,whichwehavenamedAEDTM2.Let'sformatthetwovariablesusingthe$N8601EH.formatsothatwecanseetheresultwithaproperISOrepresentation.The$N8601EH.formatprovideshyphensformissingcomponents.
Fromhere,wecancalculatedurationswithCALLIS8601_CONVERTusingthefollowingcodeandthedatasetAEDTM2thatwecreatedintheprevious
step.Inline3,wedefinetheresultvariablesascharactersothatwedonotgetaSAStimevalue.Wearecreatingtwoforthepurposesofthisexercise,DURATIONwiththeroutineinline4,andAEDURinline6,whichistheISO-formattedversionofDURATIONsothatit
canbeshownalongsidetheinternalrepresentationoftheduration.
1.DATAbook.iso_durations;2.SETbook.aedtm2;3.LENGTHdurationaedur$16;4.CALLIS8601_CONVERT('dt/dt','du',aestdtm,aeendtm,duration);5.aedur=duration;6.FORMATaedur$N8601E.;
7.RUN;
Oneofthethingsthatyoumightnoticeisthatdurationshavebeencalculatedforallthevaluesthathaveanendingdate,regardlessofmissingcomponents
inthestartingandendingdatetimes.TheCALLIS8601_CONVERTroutineimputescompletedatetimevaluesbyusingdefaultvaluesformissingcomponents,soithassupplied1formissingmonthsanddays,andzerosforhours,minutes,andseconds.
Thiscausesanydatetimewithamissingtimetobesetat12:00a.m.ofthefollowingday.Thissimpleimputationmightnotbewhatyouwanttouse,andmoreelaboratecodingmightbenecessary.Youmighthavetostartwithparsingtheinputdatetimestringto
determinewhichcomponentsaremissingandapplyyourimputationalgorithmfromthere.Nonetheless,onceyouhaveyourimputeddatetimevalues,CALLIS8601_CONVERTwillcreateandstoreanISOdurationfromthosedatetimes.
Example4.5:ConvertingTwoDatetimestoanISOIntervalLet’susethedatafromexample4.4toquicklydemonstratethecreationofanISOintervalusingtheCALLIS8601_CONVERTroutine.WewillstartwiththeISOdatetime
valuesstoredinthedatasetAEDTM2.
ThefollowingcodewillcreateourISOinterval.Notethatinline3,thelengthoftheresultvariableintervalisset
to32,whichistheminimumlengthforavariablethatholdsanISOinterval.Theresultisshowninthescreencapturefollowingthecode.Onceagain,wearecreatingacopyoftheresulttoshowboththeintervalvalueasastoredvalueandtheISO-formattedintervalvalue.
1.DATAbook.iso_intervals;2.SETbook.aedtm2;3.LENGTHintervalformatted_interval$32;4.CALLIS8601_CONVERT('dt/dt','intvl',aestdtm,aeendtm,interval);5.formatted_interval=interval;6.FORMATformatted_interval$N8601E.;7.RUN;
Example4.6:ConvertingaDatetimeandaDurationintoanISOIntervalInthisexample,wewillcreateanISOintervalfroma
datetimeandadurationusingthefollowingdataset,SAMPLE,whichcontainsastartdatetimeandanISOduration.
Whydon'tweapplythe
$N8601E.formattoAESTDTMandDURATIONsothattheyarereadable?
Ifthisweretrueclinicaldata,therewouldbeanerrorinthedataat
record3,becausethedurationisnegative,indicatingthatthestartdatetimeislaterthantheendingdatetime.WhiletheISOstandardaccountsfornegativedurations,thisdoesnotmeanthatnegativedurationsareappropriateinyourdata.
Thiscodelookssimilartothecodeintheprevioustwoexamples.ThedifferenceisintheargumentsusedfortheCALLIS8601_CONVERTroutineinline4.The'dt/du'signifiesthatthedatetimerepresentsthestartoftheinterval.Wewillshowtheunformattedand
formattedresultasareminderthatthecharacterresultsarestoredintheirSASinternalrepresentation:
1.DATAinterval;2.SETsample;3.LENGTHintervalformatted_interval$32;4.CALLIS8601_CONVERT('dt/du','intvl',aestdtm,duration,interval);5.formatted_interval=interval;6.FORMAT
formatted_interval$N8601E.;7.RUN;
Interval
2012B221030FFFFDFFFFF072330FFFFC
2012C02FFFFFFFFDFFFF105FFFFFFFFC
2012C121200FFFFDFEFFFFF12FFFFFFC
2012C191000FFFFDFFFFF072130FFFFC
2013101FFFFFFFFDFFFFF29FFFFFFFFC
Example4.7:CalculatingtheEndofanIntervalfromaDatetimeandaDuration
AnadditionalcapabilityoftheCALLISO_8601routineistocalculatestartingandendingdatetimesfromintervals,oracombinationofdurationanddatetime.Inthisexample,wewillcalculatetheenddatetimesfortheISOintervalsthatwecreatedinexample4.6.
1.DATAinterval_end;2.SETinterval;3.CALLIS8601_CONVERT('intvl','end',interval,end);4.FORMATinterval$N8601E.endDATETIME20.;5.RUN;
Youcanseethatthiscodeisagainslightlydifferentfromexample4.6.OnelargedifferenceisthatthereisnoLENGTH
statementusedtocreatetheresultasacharactervariable.ThiscausestheroutinetocreatetheresultasaSASdatetimevalue,notanISO8601datetimecharacterstring.Thisisanimportantdistinction.Inline3,wetelltheroutinethatwearegoingtoconvertaninterval,andwe
wanttheendingdatebasedonthatinterval.SincethevariableINTERVALisstillstoredinitsinternalSASrepresentation,wehaveappliedthe$N8601E.formattothatvariable,aswellasformattingtheENDvariablewithDATETIME20.sowecanreadthemeasilyin
theoutput.Hereistheresult.
Interval
2012-11-22T10:30/P7DT23H30M
2012-12-02/P1M5D
2012-12-12T12:00/-PT12H
2012-12-19T10:00/P7DT21H30M
2013-01-01/P29D
Anyoftheprecedingexamplescanbereversed;youcanconvertanISOdurationorintervalintotwodatetimesoryoucanturnan
intervalintoadurationandadatetime.Toshowyouhowitallconnectstotogether,inthislastexample,wewilltakestartingandendingISOdatetimevaluesandcreateanISOdurationandanISOinterval,andthenwewillrecalculatethestartingandendingdatetimesfromthat
ISOinterval,bothastheirISOdatetimevaluesandtheirSASdatetimevalues.
Example4.8:CALLIS8601_CONVERT:ISODatetimes,Durations,andIntervalsfromStarttoEndandBackAgainwithOneRoutine
ThiscodeusesthedatasetEX4_8,whichcontainstwoISOdatetimevaluesinthevariablesAESTDTMandAEENDTM.Theyaredisplayedusingthe$N8601E.formatsoyoucanreadthevalueseasily.
BecausewewanttheresultsinthisexampleastheirISOrepresentations,wedefinetheresultvariablesthatwearecreatingascharactervariables,includingtheendingdatetimes.Note
thatthevariableINTERVALis32bytesinlengthbecausethatistheminimumlengthforanISOintervalvalue.Line4createstheISOdurationandline5theISOintervalvalue,andweusethatintervalinlines6and7toproducethestartingandendingISOdatetimevalues.Lines
8and9linesrecalculatethestartingandendingdatetimesasSASdatetimevalues.Wewillpresenttheresultsseparately.
1.DATAcircle;2.SETex4_8;3.LENGTHduration$16interval$32start_dt$16end_dt$16;4.CALLIS8601_CONVERT('dt/dt','du',aestdtm,aeendtm,duration);5.CALL
IS8601_CONVERT('dt/dt','intvl',aestdtm,aeendtm,interval);6.CALLIS8601_CONVERT('intvl','start',interval,start_dt);7.CALLIS8601_CONVERT('intvl','end',interval,end_dt);8.CALLIS8601_CONVERT('intvl','start',interval,datetime_start);9.CALLIS8601_CONVERT('intvl','end',interval,datetime_end);10.FORMATdurationintervalstart_dtend_dt$N8601E.;11.RUN;
Original Original
StartingISODatetime
EndingISODatetime
ISODurationValue
2012-11-21T09:12
2012-11-30
2012-11-21T09:25
2012-11
2012-12-03T09:00
2012-12-03T10:00
2012-12-14T09:12
2013-01-17
2012-12-14
2012-12-29
14 29
Theonethingthatyoushouldtakenoteofhereisthenegativedurationvalueinthesecondrow.Sincethedaycomponentismissingfromtheendingdatetime,CALLIS8601_CONVERThasuseditsdefaultvalueforthedaycomponent,
whichis1.Obviously,November21(thestartingdate)isafterNovember1,soyoumightwanttouseadifferentimputationforyourendingdates.Nextaretherecalculatedstartingandendingdates,presentedinseparatetablestomakeiteasytoseetheresultoftheconversions.
OriginalStartingISODatetime
RecalculatedISOStartingDatetime
2012-11-21T09:12
2012-11-21T09:12
2012-11-21T09:25
2012-11-21T09:25
2012-12-03T09:00
2012-12-03T09:00
2012-12-14T09:12
2012-12-14T09:12
2012-12-14
2012-12-14
OriginalEndingISODatetime
RecalculatedISOEndingDatetime
2012-11-30
2012-11-30
2012-11 2012-11
2012-12-03T10:00
2012-12-03T10:00
03T10:00 03T10:00
2013-01-17
2013-01-17
2012-12-29
2012-12-29
Takenoteofthesecondrowintheendingdatetimetableabove.Notonlydoesthis
pointouttheproblemwithrelyingontheautomaticsubstitutionoftheroutine,butthedifferencebetweentheISOdatetimevaluesandSASdatetimevalues.TheISOstandardaccommodatesmissingcomponents,soitislegaltohavethevalue"2012-11,"which
clearlyindicates,"DuringthemonthofNovember,buttheexactdayisunknown,"and,"Atsometimeonthedayof…"TheSASdatetimevaluehastoprovidebothexactdateandexacttime,so"2012-11"issetto12:00AM,November1,2012,usingthedefaultreplacements
formissingcomponents.
4.6ConclusionTheISO8601standardhasbeendevelopedfortheclearcommunicationofdateandtimeinformationacrosscountries,applications,and
platforms.SAShasthecapabilitytohandlethisstandardtoitsfullextent,eventhoughonthesurfacethereseemtobemanyincompatibilitiesbetweentheSASdateandtimefacilityandtheISOstandard.Thelargestdifferencesarewithrespecttoincompletedata,and
thatalphabeticcharactersareusedasmorethansimpledelimitersmakestheISO8601handlingfacilityinSASuniquewhenitcomestodatesandtimes.ItistheonlypieceoftheSASdateandtimecapabilitiesthatrequirescharactervariables.
Chapter5:DateandTimeFunctions
5.1CurrentDateandTimeFunctions
5.2ExtractingPiecesfromSASDate,Time,andDatetimeValues5.3CreatingDates,Times,andDatetimesfromNumbersorOtherInformation
5.4CalculatingElapsedTime,andtheHOLIDAY()Function5.5TheBasicsofSASIntervals5.6ModifyingSASIntervals5.7CreatingYour
OwnSASIntervals5.8IntervalFunctionsaboutIntervals5.9RetailCalendarIntervalsandSeasonality
SAShasmanyfunctionstomanipulate
dates,times,anddatetimevalues.Thefunctionscanbecategorizedaccordingtowhattheydo.Youcanobtainthecurrentdate,time,ordatetime(asspecifiedbythecomputer'sclock).Youcanalsoeasilyextractpiecesofdates,times,ordatetimesasnumericalvaluesfrom
theircorrespondingSASvalues,oryoucanassembleSASdate,time,anddatetimevaluesfromSASvariablesorconstants.Anothersetoffunctionsoperateswithintervalssuchasweeksormonths.
5.1CurrentDateandTimeFunctionsCurrentdateandtimefunctionshavenoargumentsandreturnSASvaluesasnotedinthefollowingtable.Thevaluesareobtainedfromtheoperatingsystem'sclock.
Table5.1:CurrentDateandTimeFunctions
DateandTimeFunction Description
DATE(),TODAY()
Thesefunctionsareidentical,
andbothreturnthecurrentdateasaSASdatevalue.
TIME() Thisreturnsthecurrent
timeasaSAStimevalue.
DATETIME() ThisreturnsthecurrentdateandtimeasaSAS
datetimevalue.
5.2ExtractingPiecesfromSASDate,Time,andDatetimeValuesTheextraction
functionsalluseasingleargument(representedbyarginthefollowingtable),whichrepresentsaSASdate,time,ordatetimevalue.ThiscanbeeitheraSASvariablenameortheappropriateconstant.Iftwo-digityearvaluesareused,theresultwillbesubjecttothe
YEARCUTOFF=optionvalueineffect.Theyallreturnanumericvalueastheresult.Thefollowingtablesareseparatedintofunctionsthatusedatesasanargument,thosethatusedatetimesastheargument,andthosethatusetimesasanargument.Eachtablegivesexamplesof
howtoapplyeachfunction,alongwithrelevantcommentsforeachexample.
Table5.2:FunctionsReturningaDateComponentandRequiringaSASDateValueasanArgument
FunctionName Explanation
DAY(arg) Extractsthenumber
ofthedayofthemonthfromaSASdatevalue.
JULDATE(arg) ExtractstheJuliandatefromaSASdatevalue.Itwillreturnafour-orfive-digitvaluewithaone-ortwo-digityear,ifthe
yearportionofthedatefallswithinthe100-yearspandefinedbytheYEARCUTOFF=option.Ifyouwanttoensurefour-digityearvalues,youshouldusethe
JULDATE7()function.
JULDATE7(arg) ExtractstheJuliandatewithafour-digityearfromaSASdatevalue.Thisalwaysreturnsaseven-digitnumber,regardless
oftheyear.
MONTH(arg) ExtractsthenumericalmonthfromaSASdatevalue.
QTR(arg) ExtractsthequarteroftheyearfromaSASdatevalue.
WEEK(arg) ExtractstheweeknumberfromaSASdatevalue,whereSundayisthefirstdayoftheweek,whichisthe"U"algorithm.ThisfunctionhasbeenaugmentedinSAS
versions9.1.3andabovebytheWEEK(functiondescribedimmediatelybelow.
(Version9.1.3andup)WEEK(arg,descriptor)
ExtractstheweeknumberfromaSASdatevalue.descriptorreferstothealgorithmusedtocalculatethefirstweekof
theyear.
TheUalgorithmcalculatesweeksbasedonSundaybeingthefirstdayoftheweek.
TheValgorithmcalculatesweeksto
theISOstandard.Mondayisthefirstdayoftheweek,andthefirstweekoftheyearisdefinedastheonethatcontainsbothJanuary4andthefirstThursdayoftheyear.
TheWalgorithmcalculatesweeksbasedonMondaybeingthefirstdayoftheweekwithoutrestriction.
WEEKDAY(arg) Extractsthenumberofthedayofthe
week,whereSunday=1,Monday=2,andsoonfromaSASdatevalue.
YEAR(arg) ExtractstheyearfromaSASdatevalue.Ifyouuseadateconstant(asin
theexample)andnotaSASdatevalue,itisimportanttorememberthattheYEARCUTOFF=optionaffectstwo-digityears.
Table5.3:FunctionsReturningaDatetime
ComponentandRequiringaSASDatetimeValueasanArgument
FunctionName Explanation
DATEPART(arg) ExtractsthedatefromaSASdatetimevalueasaSASdate
value.
TIMEPART(arg) ExtractsthetimeportionfromaSASdatetimevalueasaSAStimevalue.
Table5.4:FunctionsReturningaTimeComponentandRequiringaSASTimeValueasanArgument
FunctionName Explanation
HOUR(arg) Extractsthehourfroma
SAStimevalue.
MINUTE(arg) ExtractstheminutesfromaSAStimevalue.
SECOND(arg) ExtractsthesecondsfromaSAS
timevalue.
5.3CreatingDates,Times,andDatetimesfromNumbersorOtherInformation
5.3.1IntroductionThisseriesoffunctionswillcreateSASdate,time,anddatetimevaluesfromnumericalvariablesorconstants.Whileinformatstakecompletedate,time,anddatetimereferencesandtranslatethemtotheir
correspondingSASvalue,thesefunctionswillcreateaSASvaluefromdiscretepiecessuchasmonth,day,andyear.
5.3.2ListofFunctionsandTheirDescriptions
DATEJUL(Julian-date);DATEJUL(Julian-date);createsaSASdatevaluefromanumericvaluerepresentingaJuliandate.Julian-datemustbeofthetypeyy(yy)ddd,whereyy(yy)istwoorfourdigitsrepresentingtheyear,anddddmustbea
numberfrom1to365(366ifaleapyear).Ifyouusetwodigitsfortheyear,theYEARCUTOFF=optionwillbeusedtodeterminethecentury.Thefollowingtablegivesexamplesofhowtoapplythisfunction:
SampleFunctionCall
OPTIONSYEARCUTOFF=1920;DATEJUL(21286)
OPTIONSYEARCUTOFF=2000;DATEJUL(21286)
DATEJUL(2014174)
DATEJUL(1989005)
DATEJUL(00368)
DHMS(date,hour,minute,second);DHMS(date,hour,minute,second);createsaSASdatetimevalue.Allfourargumentsarerequired.dateisaSASdatevalue,whichcanbeeitheranumericvalueoradateconstant.Ifyouuseatwo-digityearinadateconstant,thedatewill
betranslatedaccordingtotheYEARCUTOFF=option.hour,minute,andsecondareallnumericvariablesand/orconstants.Hour,minute,andsecondarenotrestrictedtotheirclocktimes.Therefore,hourcanbegreaterthan24,whileminuteandsecondcanbegreaterthan60.The
followingtablegivesexamplesofhowtoapplythisfunction:
SampleFunctionCall
DHMS("08JUN2015"d,15,24,0)
DHMS("02FEB2014"d,11,54,15)
DHMS("30JUN2012"d,8,7,93)
Example5.1:UsingDHMS()WhenYou
AlreadyHaveaSASDateandTimeIfyouneedtocreateadatetimefromaSASdateandaSAStimevalue,youdonothavetousetheHOUR(),MINUTE(),andSECOND()functionstoextractthosecomponentsfromthetimevalue.Remember
thatSASkeepstrackoftimeinsecondssincemidnightandthatthesecondsargumentintheDHMSfunctioncanbegreaterthan59.Therefore,ifyousupplytheSAStimevalueasthesecondsargumentandsethourandminutetozeros,thatwillworkjustfine.Thefollowingexample
demonstrates:
1DATAex5_1;2INPUTrow$sasdate:date9.sastime:time8.;3result=DHMS(sasdate,0,0,sastime);4fmt_result=result;5formatsasdatedate9.sastimetimeampm.;6DATALINES;7A16oct201517:308B08jun201611:009C14apr201500:0010;;;11RUN;
12PROCPRINTDATA=ex5_1NOOBSLABELSPLIT='\';13IDrow;14VARsasdatesastimeresultfmt_result;15FORMATfmt_resultdatetime19.sasdatesastime;16LABELrow='Row'17result='~{text_align=c}SASDatetimeValue\CalculatedUsing\DHMS(sasdate,0,0,sastime)'18fmt_result="ResultFormattedwith\DATETIME19.Format";19RUN;
TheResult
Row sasdate sastime
A 20377 63000
B 20613 39600
C 20192 0
Thecalculationofthedatetimevalueisdoneinline3oftheaboveprogram.Theformatshavebeenremovedfromthesasdateandsastimevariablesinthetableforthepurposeofillustratingtheactualvaluesthatarebeingsenttothefunction.RowCabovehasbeenincludedto
demonstratethatanyvalidSAStimevaluewillwork,even0seconds.Whatgoodisthat?IfyouneedtocreateaSASdatetimevalueandyouonlyhaveadatewithoutatimevalue,thenyoucanuseDHMS(sasdate,0,0,0)toconvertyourSASdateintoaSASdatetime.
HMS(hour,minute,second);HMS(hour,minute,second);createsaSAStimevalue.hour,minute,andsecondareallnumericvariablesand/orconstants.Noneoftheparametersarerestrictedtotheirclocktimes.Therefore,hourcanbegreaterthan24,whileminuteandsecond
canbegreaterthan60.Allthreeargumentsmustbepresentoryouwillgetamissingvalueastheresult.Thefollowingtableprovidesexamples:
SampleFunction Time
Call Value
HMS(18,0,9) 64809
HMS(7,45,80) 27980
HMS(15,03,35.56) 54215.56
HMS(8,17,33) 29853
HMS(21,14,28) 76468
MDY(month,day,year);
MDY(month,day,year);createsaSASdatevaluefromthearguments.Allthreeargumentsarerequired.month,day,andyearareall
numericvariablesorconstants.Ifyearistwodigits,thecenturywillbedeterminedbytheYEARCUTOFF=option.Ifavaluegivenforanyoftheargumentsisnotvalidormissing,suchasMDY(2,31,2014)(February31,2014),thefunctionwillreturnamissingvalueand
giveyouan"invalidargumenttofunction"messageinthelog.Thefollowingtableshowsexamples:
SampleFunctionCall
SASDateValue
MDY(9,3,1876) –
30434
MDY(12,14,15) 20436
MDY(3,26,1915) –16352
MDY(5,22,2014) 19865
NWKDOM(n,weekday,month,year);
NWKDOM(n,weekday,month,year);createsaSASdatevaluefora
givenweekdayinagivenweeknumberfromagivenmonthandyear.Alloftheargumentsarenumericandcanberepresentedbyconstantsornumericvariables.Ifanyoftheargumentsaremissing,ornotvalid,thenthefunctionwillreturnamissingvalue.nrangesfrom1
(first)to5(last).Sometimesusingthevalueof5willgivethesameresultas4,ifthefourthweekofthemonthisalsothelastweekofthemonth.weekdayrangesfrom1to7,where1representsSunday,and7representsSaturday.monthcanrangefrom1(January)to12
(December).yearrepresentstheyearandissubjecttotheYEARCUTOFF=optionifyouusetwodigitsfortheyear.
Youcanusethisfunctiontofinddatesthatareexpressedas"ThefirstSaturdayinMay,"orthe"lastTuesdayinAugust,"
easily.Thefollowingtableprovidesexamplesofhowthisfunctionworks.
DateDescription SampleFunctionCall
First NWKDOM(1,3,11,2014)
TuesdayinNovember.
SecondTuesdayinDecember.
NWKDOM(2,3,12,2014)
ThirdWednesdayinApril.
NWKDOM(3,4,4,2014)
FourthSundayinMay.
NWKDOM(4,1,5,2014)
LastSundayinMay.
NWKDOM(5,1,5,2014)
FirstSundayin
NWKDOM(1,1,6,2018)
June.
SecondSaturdayinDecember.
NWKDOM(2,7,12,2018)
ThirdSaturdayinMay.
NWKDOM(3,7,5,2018)
Fourth NWKDOM(4,2,10,2018)
MondayinOctober.
LastMondayinOctober.
NWKDOM(5,2,10,2018)
Theboldedanditalicizedtextaboveshowsthatthelast
weekofthemonthandthefourthweekofthemonthmayormaynotproducethesamedate.
YYQ(year,qtr);YYQ(year,qtr);createsaSASdatevaluefromthearguments.Bothargumentsarerequired.yearisanumericvariableor
constantrepresentingtheyear,andqtrisanumericvariableorconstantbetween1and4,representingthequarteroftheyear.Ifyearistwodigits,thecenturywillbedeterminedbytheYEARCUTOFF=systemoption.Thisfunctionreturnsthedateofthefirstdayofthequarter
inthegivenyear.Thefollowingtableprovidesexamplesofhowthisfunctionworks.
SampleFunctionCall
SASDateValue
Formattedwithmmddyy10.Format
YYQ(2015,1) 20089
YYQ(99,3) 14426
YYQ(25,2) –12693
YYQ(25,2) 23832
YYQ(2015,2) 20179
5.4CalculatingElapsedTime,andtheHOLIDAY()FunctionBecauseSASusessimplemathasthebasisfordatesandtimes,youmightthinkthatcalculatingelapsedtimeorprojectingintothefuturewouldbe
easy.Itshouldbeamatterofsimpleadditionorsubtraction.However,SASprovidesseveralfunctionsthatdealwithcalculatingelapsedtime,andforthemostpartthefunctionisgoingtobemoreaccuratethansimplemath.Forexample,oneofthemathematicalequations
forcalculatingageis(currentdate–dateofbirth)/365.25.Thisapproximationusesthe.25toaccountforleapyears,butitfailstotakeintoaccounttheexceptionforyearsthataredivisibleby100butnotby400.Whileyoumightrarelyneedsuchaccuracywhencalculatingelapsed
years,theefficiencyofaSASfunctionmightspeedthingsperceptiblywhenworkingwithbigdata.
5.4.1CalculatingElapsedTimewithDATDIF()andYRDIF()
Thesetwofunctionswereoriginallydevelopedforusewithsecuritiescalculationsforspecificfinancialinstruments.
DATDIF(start,end,basis);DATDIF(start,end,basis);calculatesthenumberofdaysbetweentwodates.startisthe
startingdate,whichcanbeadateconstant,anumericvariable,oraSASexpression.endistheendingdate,alsoadateconstant,anumericvariable,oraSASexpression.basisisacharacterconstantorvariablethattellsSAShowtocalculatethedifference.Thestartandendargumentsare
required,whilebasisisoptional.basishastwopossiblevalues.Notethatifyouuseacharacterconstantforbasis,rememberthatitwillneedtobeenclosedinquotationmarks,oryouwillgetanerror.
1.'30/360',which
setseachmonthto30days,andtheyearto360days,regardlessofhowmanydaysareineachmonthoryearinthespanbetweenthetwodates.Ifadayisattheendofamonth(forexample,
February28/29orMarch31),itwillbeconsideredasthe30thofthemonth.
2.'ACT/ACT',whichusestheactualnumberofdaysineachmonthandyearinthespan
betweenthetwodates.Thisisthedefault,anditisidenticaltosubtractingstartfromend.
SampleFunctionCall
DATDIF('19JUL2015'd,'19JUL2016'd,'30/360')
DATDIF('19JUL2015'd,'19JUL2016'd,'ACT/ACT')
YRDIF(start,end,basis);
YRDIF(start,end,basis);calculatesthenumber
ofyearsbetweentwodates.Itisalmostalwaysmoreaccuratethanusingmathematicalapproximation,dependingonthebasisusedandthedesiredresult.startisthestartingdate,whichcanbeadateconstant,anumericvariable,oraSASexpression.endis
theendingdate,alsoadateconstant,anumericvariable,oraSASexpression.basisisacharacterconstantorvariablethattellsSAShowtocalculatethedifference.basishasfivepossiblevalues,ascomparedwiththetwopossibilitiesintheDATDIF()function:
1.'30/360',whichsetseachmonthto30days,andtheyearto360days,regardlessofhowmanydaysareineachmonthoryearinthespanbetweenthetwodates.Ifadayisattheendofa
month(forexample,February28/29orMarch31),itwillbeconsideredasthe30thofthemonth.
2.'ACT/ACT',whichusestheactualnumberofdaysineach
monthandyearinthespanbetweenthetwodates.ThiswasthedefaultbasisthroughSASversion9.2.Youcanusethealias"Actual,"not'ACT.'
3.'ACT/360',whichusesthe
actualnumberofdaysbetweenthetwodatestocalculatethenumberofyears,butitusesa360-dayyear,regardlessofhowmanydaysareineachyear,sotheresultisnumberofdaysdividedby360.
4.'ACT/365',whichusestheactualnumberofdaysbetweenthetwodatestocalculatethenumberofyears,butusesa365-dayyear,regardlessofhowmanydaysareineachyear,
sotheresultisnumberofdaysdividedby365.
5.'AGE',whichisusedtocalculateaperson'sage.ThisisavailablestartingwithSASversion9.3,andasofthatrelease,'AGE'isnowthedefault.
SampleFunctionCall
YRDIF('07AUG1967'd,'24MAY2014'd,'30/360')
YRDIF('07AUG1967'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1967'd,'24MAY2014'd,'ACT/360')
YRDIF('07AUG1967'd,'24MAY2014'd,'ACT/365')
Asyoucansee,allfourresultsaredifferent,andthisisduetothewaytheywerecalculated.Priortoversion9.3,thisfunctionwasoftenusedtocalculateages,buteventhe'ACT/ACT'basisdoesn'tcalculateagesprecisely.The'ACT/ACT'basisaveragesleapyeardays
acrossthefouryears.Nowlet'sexaminetheYRDIFfunctionwhenthe'ACT/ACT'basisandthe'AGE'basisareused.
SampleFunctionCall
YRDIF('07AUG1967'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1967'd,'24MAY2014'd,'AGE')
ThislooksasiftheYRDIF()functionwillyieldthesameresultforboththe'AGE'basisandthe'ACT/ACT'basis.Whereisthedifference?Let'slookatanotherseriesofdates.
SampleFunctionCall
A YRDIF('07AUG1968'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1968'd,'24MAY2014'd,'AGE')
B YRDIF('07AUG1969'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1969'd,'24MAY2014'd,'AGE')
C YRDIF('07AUG1971'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1971'd,'24MAY2014'd,'AGE')
D YRDIF('07AUG1972'd,'24MAY2014'd,'ACT/ACT')
YRDIF('07AUG1972'd,'24MAY2014'd,'AGE')
IngroupingsAandD,youseethatthebasismakesadifference,whileingroupingsBandC,the'ACT/ACT'and'AGE'returnidenticalresults.WhatmakesgroupingsAandDsodifferent?Theseareleapyears,andthe
leapdayisaccountedforasawholedayforthatgivenyear,asopposedtotheaveragingofaquarterdayperyearperformedbythe'ACT/ACT'algorithm.
(U.S.andCanadaOnly)HOLIDAY(holiday,year
HOLIDAY(holiday,year);providesthedateofselectedholidaysinanygivenyearasaSASdatevalue.ThisfunctionisvalidforU.S.andCanadaholidaysonly.holidaycanbeacharacterstringenclosedinquotationmarksoracharactervariablecontainingoneofthe
argumentslistedbelow.Thevalidvaluesofholidayarelistedinthetablebelow.Note:Ifyouuseacharactervariableinsteadofastring,yourvariableshouldbeatleast18characterslongtoaccommodatethelongestargument.
ArgumentUsedinFunction
BOXING
CANADA
CANADAOBSERVED
CHRISTMAS
COLUMBUS
EASTER
FATHERS
HALLOWEEN
LABOR
MLK
MEMORIAL
MOTHERS
NEWYEAR
THANKSGIVING
THANKSGIVING
THANKSGIVINGCANADA
USINDEPENDENCE
USPRESIDENTS
VALENTINES
VETERANS
VETERANSUSG
VETERANSUSPS
VICTORIA
SampleFunctionCall
HOLIDAY("EASTER",2014)
HOLIDAY("EASTER",2019)
HOLIDAY("EASTER",2026)
HOLIDAY("EASTER",2039)
HOLIDAY("THANKSGIVINGCANADA",2014)
HOLIDAY("THANKSGIVINGCANADA",2019)
HOLIDAY("THANKSGIVINGCANADA",2026)
HOLIDAY("THANKSGIVINGCANADA",2039)
HOLIDAY("USINDEPENDENCE",2014)
HOLIDAY("USINDEPENDENCE",2019)
HOLIDAY("USINDEPENDENCE",2026)
HOLIDAY("USINDEPENDENCE",2039)
5.5TheBasicsofSASIntervals
SomeoftheSASfunctionsdescribedinsection5.4,suchasDATDIF,areverygoodatcalculatingtheexactamountofelapsedtimebetweentwoSASdates,andasdemonstratedinsomeoftheaboveexamples,youcanseethedifferencebetweenthefunctionandsimplemath.Therearen't
functionstoprojectfuturedates,becauseitwouldseemsimpleenough:youjustaddanumberofdays,hours,orminutes,andyoucomeupwithananswer.
However,wefrequentlyneedtorefertounitsoftimethatarenotuniform,suchas
months,whichcanbe28,29,30,or31dayslong.SASprovidesfunctionstocalculateintervalsbecause,inmanycases,simplemathisstillonlyanapproximation.SAShasseveralstandardintervaldefinitionsthatareusedwithdates,times,anddatetimesthatrepresentmanyof
thenormalperiodsoftimethatwereferto,suchasweeksorquarters.Youarenotrestrictedtotheintervalsgiveninthestandarddefinitions,becauseyoualsohavetheabilitytoeasilymodifythem.Youcanusemultipliersand/orashiftindexinconjunctionwiththe
standardintervals.Multipliersenableyoutodefineintervalsthataremultiplesofastandardintervalandarenotalreadydefined,suchasadecadeoracentury.Ashiftindexenablesyoutodefineintervalsthatdonotcorrespondwiththestartingvaluesusedbyaninterval(standard
ORwithamultiplier),suchasafiscalyearthatbeginsinJulyinsteadofJanuary,or,togiveyouanexamplewithamultiplier,adecadethatstartsinyearsendinginthenumber'5,'insteadofyearsendingin0.Section5.6willdiscusstheconceptsofmultipliersandthe
shiftindexindetail.Ifyouneedintervalsthatcannotbedescribedbyusingmultipliersand/orashiftindexwiththestandardSASintervals,SAShasthecapacityforyoutodefineyourownintervals,andthisiscoveredindepthinSection5.7.
Fortheremainderofthisbook,whentheterm"interval"isusedinafunctiondefinition,itmeansaSASintervalname,alongwithanymultiplierand/orshiftindexunlessexplicitlyspecifiedotherwise.Wewillbeginourdiscussionofintervalsbyprovidingalistofallthestandard
intervaldefinitionsandtheperiodsthattheydescribeinTable5.5.
Table5.5SASIntervalDefinitionsUsedwithDates,Times,andDatetimes
Category IntervalName
Date DAY
WEEK
WEEKDAYdaysW
TENDAY
SEMIMONTH
MONTH
QTR
SEMIYEAR
YEAR
Datetime DTDAY
DTWEEK
DTWEEKDAYdaysW
DTTENDAY
DTSEMIMONTH
DTMONTH
DTQTR
DTSEMIYEAR
DTYEAR
DTSECOND
DTMINUTE
DTHOUR
Time SECOND
MINUTE
HOUR
5.5.1TheIntervalCalculation
Functions:INTCK()andINTNX()TheintervalcalculationfunctionsINTCK()andINTNX()useSASintervaldefinitions.INTCK()countsthenumberofintervalsbetweentwogivendates,times,or
datetimes.INTNX()calculatesthedate,time,ordatetimethatresultsafteragivennumberofintervalshavebeenaddedtoaninitialdate,time,ordatetimevalue.
ThesyntaxfortheINTCKfunctionisasfollows.
INTCK(interval,start-of-period,end-of-period,method);intervalistheSASdesignationforaperiodoftime,andcanbeacharacterliteralorcharactervariablethatcorrespondstooneofthedefinedtimeintervals(seeTable5.5).start-of-periodis
thebeginningdate,time,ordatetimevalue,whileend-of-periodistheendingone.Bothstart-of-periodandend-of-periodcanbeanythingthatevaluatestoavalidSASdate,time,ordatetimevalue.
AsofSASversion9,methoddetermineshow
SASisgoingtocounttheintervals.Therearetwopossiblevalues:CONTINUOUS(orCorCONT)andDISCRETEor(DorDISC).ThedefaultisDISCRETE,andthishasbeenhowintervalshavetraditionallybeencalculatedinSAS.WhenmethodisDISCRETE,theINTCK()
functioniscountingthenumberoftimesthattheperiodintervalbeginsbetweenstart-of-periodandend-of-period,inclusive.Itdoesnotcountthenumberofcompleteintervalsbetweenstart-of-periodandend-of-period.Thisalsomeansthatthecountdoesnotbeginwithstart-of-
period,butatthebeginningofthefirstintervalafterthat.ThefollowingexampledemonstrateshowINTCK()countsusingtheDISCRETEmethod.Forexample,takethedatesSaturday,December31,2011,andSunday,January1,2012.
Example5.2:HowtheINTCK()FunctionCountsbyDefault(methodIsDISCRETE)
FunctionCall
INTCK('DAY','31dec2011'd,'01jan2012'd);
INTCK('WEEK','31dec2011'd,'01jan2012'd)
INTCK('MONTH','31dec2011'd,'01jan2012'd)
INTCK('YEAR','31dec2011'd,'01jan2012'd)
Alloftheintervalsareequalto1eventhoughonlyonedayhaspassed!January1,2012,isthestartofday,week,month,andyearintervals.ThestartingdayoccurredonDecember31,andtheendingdaybeganonJanuary1,soitis
obviousthattheresultfortheDAYintervalshouldbe1,becausetheDAYintervalboundarywascrossedonJanuary1.However,whenitcomestotheWEEKinterval,Sundayisthebeginningoftheweek.Therefore,theweekcontainingDecember31ststartedonSunday,
December25.Sunday,January1,isthebeginningofthenextweek,soyoucrosstheWEEKintervalboundaryatJanuary1.ThismeansthatoneWEEKintervalhaselapsedbetweenthestartoftheweekinDecemberandthestartoftheweekinJanuary,sothatcausestheresult
forWEEKtobe1.Similarly,themonthcontainingDecember31startedonDecember1,2011,andthemonthforJanuary1,2012,startedonJanuary1.YouarecrossingtheMONTHintervalboundaryonJanuary1,sooneMONTHintervalhaselapsedbetweenthestartofthe
intervalsforthetwodates,andtherefore,thatresultis1aswell.Finally,theyearforDecember31,2011,startedonJanuary1of2011,whiletheyearforJanuary1,2012,startsonthesamedate.YoucrosstheYEARintervalboundaryatJanuary1,whichcausestheYEAR
intervalresulttobe1.Allofthevaluesareequalto1becausetheINTCK()functioniscountingtheDAY,WEEK,MONTH,andYEARintervalboundary,whichoccursatSunday,January1,2012,andnotbecauseofthenumberofdays,weeks,months,oryearsthat
havepassed.
Nowlet'slookatthecorrespondingresultswhenyouuseCONTINUOUSforthemethod.
Example5.3:HowtheINTCK()FunctionCountsWhenmethodIsCONTINUOUS
FunctionCall
INTCK('DAY','31dec2011'd,'01jan2012'd,'C');
INTCK('WEEK','31dec2011'd,'01jan2012'd,'C')
INTCK('MONTH','31dec2011'd,'01jan2012'd,'C'
INTCK('YEAR','31dec2011'd,'01jan2012'd,'C')
Onedayhaspassed,asintheDISCRETEexample.However,this
looksmorelikewhatyoumightexpectwhenyouaskhowmanyweeks,months,andyearshavepassedbetweenDecember31,2011,andJanuary1,2012.Onlyonedayhaspassed,notanentireweek,month,oryear.TheCONTINUOUSmethodcalculatescontinuoustime,andit
usesthecalendardefinitionofaweek,month,oryear,startingonthedatesuppliedasthefirstargument.Let'schangetheendingdatesappropriatelytoreproducetheresultsinExample5.2.
Example5.4:HowtheINTCK()FunctionCountsWhenmethod
IsCONTINUOUS
FunctionCall
INTCK('DAY','31dec2011'd,'01jan2012'd,'C');
INTCK('WEEK','31dec2011'd,'07jan2012'd,'C')
INTCK('MONTH','31dec2011'd,'31jan2012'd,'C'
INTCK('YEAR','31dec2011'd,'31dec2012'd,'C')
NowthepictureshouldbealittlemoreclearthatusingCONTINUOUScausestheINTCK()functiontolookatcontinuouselapsedtime,notintervalboundaries.TofirmupthisdemonstrationoftheCONTINUOUSmethodfortheINTCK()function,let'slookat
howthedefinitionoftheMONTHintervalcanchange.
Example5.5:HowtheINTCK()FunctionCountsWhenmethodIsCONTINUOUS
FunctionCall
A INTCK('MONTH','01jan2012'd,'01feb2012'd,'C');
B INTCK('MONTH','01jan2012'd,'31jan2012'd,'C');
C INTCK('MONTH','01apr2012'd,'01may2012'd,'C');
D INTCK('MONTH','28feb2012'd,'28mar2012'd,'C');
E INTCK('MONTH','29feb2012'd,'28mar2012'd,'C');
F INTCK('MONTH','28feb2013'd,'28mar2013'd,'C');
RowsAandBlooknormal:31daysisa
month,while30daysisnotamonth.However,rowCstatesthat30daysisamonth.ThisisonlytrueforthemonthsofApril,June,September,andNovember.Finally,rowsDthroughFdemonstratethat,whenyouareusingtheCONTINUOUSmethod,theMONTHinterval
changesbasedonthemonthandtheyear.Inleapyears,aperiodof29daysacrossFebruaryisconsideredamonth(rowD).However,aperiodof28daysisnotconsideredamonthinleapyears(rowE).Ontheotherhand,ifitisnotaleapyear,28daysinFebruaryisamonth.
TheCONTINUOUSmethodisusefulforcalculatinganniversariesandmilestonestiedtodates,times,anddatetimes.Althoughthismethodseemsmuchmoreintuitivethanthetraditional(andstilldefault)waythatSAShandlesintervals,youwillhave
tobeverycautiousinchoosingwhichmethodyouuseandwhen.Itisnotrecommendedthatyoureplaceallofyourexistingcodetousethismethodinsteadofthedefault,becausethetwomethodsdifferintheirdefinitionofintervalboundaries.TheCONTINUOUSmethodshiftsthe
intervalbythestartingdateprovided.WiththeDISCRETEmethod,allvalueswithinanintervalboundaryareconsideredtobeequivalent.Thatmakesitpossibletogroupobservationsoccurringwithinanintervalforanalysis.
Sincethe
CONTINUOUSmethodismoreintuitivetothewaywetendtolookatperiodsoftime,theremainderofthissectionontheINTCK()functionwillbedevotedtothetraditionalDISCRETEmethod.PleaserememberthattheDISCRETEmethodisthedefault,andin
ordertousetheCONTINUOUSmethod,youwillhavetosupplythepropermethodargumentintheINTCK()function.Allofthefollowingexamplesrelyonthedefaultmethod,sothereisnomethodargumentusedinthefunctioncalls.
TocompletethepictureofhowthetraditionaluseoftheINTCK()functionworks,let'slookattheeffectthattheendingdatehasonINTCK().
Example5.6:HowtheINTCK()FunctionCounts
FunctionCall
INTCK('DAY','31dec2014'd,'06jan2015'd);
INTCK('WEEK','31dec2014'd,'06jan2015'd)
INTCK('MONTH','31dec2014'd,'06jan2015'd
INTCK('YEAR','31dec2014'd,'06jan2015'd)
Hereyoucanseethatalthough6dayshaveelapsed,stillonly1week,month,andyear
haveelapsedaccordingtoINTCK()!Thatisbecausethestartoftheweek,month,andyearintervalforJanuary6,2015,isstillJanuary1,2015,andthatiswhatINTCK()iscounting.HerearesomemoreexamplesoftheuseoftheINTCK()functionwithitsdefaultoftheDISCRETEmethod.
Example5.7:TheINTCKFunction:TheBasics
FunctionCall
INTCK('DAY','15jun2013'd,'22jun2013'd);
INTCK('WEEK','01jan2016'd,'01jan2017'd);
INTCK('DTDAY','01oct1872:08:00:00'dt,'20dec1872:18:00:00'dt);
INTCK('MONTH','05mar2000'd,'01may2000'd);
Example5.8:TheINTCKFunction:CountingBackward
FunctionCall
INTCK('YEAR','22dec2015'd,'16jul2010'd);
Inthisexample,thefromdateisafterthetodate,andtherefore,theanswerisnegative.
SinceINTCK()countsintervalboundaries,theansweris–5becauseitstartscountingatthestartofayear.ThestartoftheyearintervalforDecember22,2015,isJanuary1,2015,soitisnotcounted.January1,2014;January1,2013;January1,2012;January1,2011;and
January1,2010,aretheboundariesoftheYEARintervalsthatitiscounting,whichcorrespondstothebeginningdatesofeachyear.
Example5.9:TheINTCKFunction:CountingWeekdays
FunctionCall
A INTCK('WEEKDAY17W','12JAN2014'd,'14JAN2014'd);
B INTCK('WEEKDAY17W','13JAN2014'd,'14JAN2014'd);
C INTCK('WEEKDAY17W','17JAN2014'd,'18JAN2014'd);
Ifyouarecountingthenumberofworkweekdaysthathaveelapsed,youmustbecarefultorememberthatINTCK()counts
intervalboundariesandthatthestartingdateisnotcountedintheanswer.RowAaboveseemsperfectlyreasonable.YouwouldexpectthattherewouldbetwoweekdaysbetweenSunday,January12,2014,andTuesday,January14,2014.Eventhoughthestartingboundaryfor
WEEKDAY17WisMonday,thestartingdateisSunday,January12,2014,soitcountsMondayandTuesday.However,youmightthinkthattherearetwoweekdaysinthespanMonday,January13,2014,toTuesday,January14,2014.InrowB,theINTCK()functioniscounting
only1weekday,becauseitdoesn'tincludeMonday,January13,2014(thestartargumentusedinthefunction),whenitcountstheintervalboundaries.WhyisrowCequaltozerothen?First,Fridayisthestartingday,andthestartingdayisneverincludedinthecount.
January18,2014,isaSaturday,andsincewe'vedefinedtheweekenddaysasSaturdayandSunday,thosedaysareoutsideofanyintervalboundaries,sobydefinition,nointervalboundarieshavebeenpassed.
Example5.10
illustratesthedifferencebetweenthethreemethodsthathavebeendiscussedforcalculatingelapsedyearsusingSAS.WewillusetheYRDIF()functionusingboththe'AGE'basisand'ACT/ACT'basis.SincetheINTCK()functionalsocountselapsedintervals,wewilluseit
andshowboththeDISCRETEandCONTINUOUSmethods,andcomparethosewithmathematicalestimation.
Example5.10:TheYRDIF()FunctionasOpposedtoMathematical
EstimationandINTCK()Thisusesthesamedates,August7,1963,andMay8,2014,forallfivemethods,butrowAusestheYRDIF()functionwith'ACT/ACT,'rowBusesthesamefunction,butwiththe'AGE'basis.Thetwovaluesare
equivalentwiththeYRDIF()function,butaswehaveseenearlier,'AGE'and'ACT/ACT'onlyyielddifferentresultswhentheyearbeingtestedisaleapyear.Themathematicalapproximationdividesthenumberofdaysbetweenthetwodatesby365.25,andalthoughthe
discrepancyisminuteinthisexample,thedifferenceiscausedbythefactthatthenumberofleapyearsintheperiod(11)isnotevenlydivisibleby4,renderingthevalue365.25anapproximation.TheINTCKfunctionusingtheDISCRETEmethodcountsinterval
boundariesfromtheirbeginning,soitiscountingthenumberofJanuaryfirstsbetweenJanuary1,1963,andJanuary1,2015.Ineffect,unlessyouwerebornonJanuary1,usingtheDISCRETEmethodwithINTCK()tocalculateyouragewillmakeyouoldbeforeyourtime!Itis
moreappropriateinthistypeofscenariotousetheCONTINUOUSmethodwiththeINTCK()function,whichyieldstheanswer50yearsold.
Calculationmethod
A UsingYRDIF()withactualdaysinmonth,actualyear
B UsingYRDIF()withAGEbasis
C Using('08may2014'd-'07aug1963'd)/365.25
D UsingINTCK('YEAR','07aug1963'd,'08may2014'd,'DISCRETE')
E UsingINTCK('YEAR','07aug1963'd,'08may2014'd,'CONTINUOUS')
ThosearesomeexamplesoftheuseoftheINTCK()function.
Remember,asofSASversion9,theINTCK()functionhasanadditionalargumentthatyoucanusetochangethewaythatINTCKcountsintervalboundaries.However,anyexistingcodeusingINTCK()doesnotneedtobechanged,becausethedefaultmethodisthe'DISCRETE'method,
whichishowINTCK()hasalwaysworked.Onceagain,itisnotagoodideatochangeexistingcodewithoutconsideringhowINTCKisbeingused,becausethemethodsdiffersignificantlyintheircalculations.
Thenextoftheintervalfunctionsthatwewill
consideristheINTNX()function.ThisfunctiontakesagivenSASdate,time,ordatetimevalueandcalculatesanewvaluebyincrementingbythegivennumberofintervals.WhereINTCK()calculatesthenumberofintervalsbetweenanytwodate,time,ordatetimevalues,INTNX()takes
thestartoftheperiodandincrementsitbyanumberofintervalstogivetheendoftheperiod.ThesyntaxoftheINTNX()functionisasfollows:
INTNX(interval,start-from,number-of-increments,alignment);INTNX(interval,start-
from,number-of-increments,alignment);isoneoftheSASintervalsdefinedinTable5.5andcanbeacharacterliteralorcharactervariablethatevaluatestooneofthedefinedintervals.start-fromisthestartingdate,time,ordatetimevalue,whichcanbeaconstant,numeric
variable,oraSASexpression.number-of-incrementsisanintegerconstantoranumericvariablethatindicateshowmanyintervalstoadvance.Ifitisnotaninteger,onlytheintegerportionofthevaluewillbeused.alignmentsetsthereturneddate,time,ordatetimevalue
accordingtooneoffourpredefinedsettings.Thefunctioncalculatesthedatesatthebeginningoftheintervalperiod,andthenthealignmentargumentadjuststheresult.Thevaluesare:BeginningorB,MiddleorM,EndorE,andSameorS(Samedayisalsoacceptableasan
alias).ThedefaultvalueforalignmentisBeginning.TheSamedayargumentcannotbeusedwiththeDTQTR,DTSEMIYEAR,orDTYEARintervals,andithasnoeffectontimevalues.
Thenextseriesofexamplesdemonstrates
varioususesandeffectsoftheINTNX()function.Thefirstexampleisthedefaultuseofthefunctionwitheachofthedate,time,anddatetimeintervals,whilethesecondshowswhathappenswhenyouuseanon-integerastheincrementtothefunction.Example5.14illustratestheuseof
thealignmentargumentstoyieldspecificdates.
Example5.11:TheINTNX()FunctionwithDefaultAlignmentEachoftheexamplesbelowincrementsthedate,time,ordatetimevalueby3ofthe
intervalshowninbolditalics.Fordatesanddatetimes,thestartdateisthesame:Thursday,November6,2014.Theonlydifferenceisthatdatetimeintervals(intervalnamesstartingwithDT)returndatetimevalues,notdates.Theintervalvaluesfordatetime
valuesarecalculatedinseconds,notdays.Bydefault,theINTNX()functionreturnsthebeginningoftheintervalgiven.Ifyouwanttochangethis,usethealignmentargumentdiscussedabove.
FunctionCall
INTNX('DAY','06NOV2014'd,3)
INTNX('DTDAY','06NOV2014:15:00:00'dt,3)
INTNX('WEEKDAY17W','06NOV2014'd,3)
INTNX('DTWEEKDAY17W','06NOV2014:15:00:00'dt,3)
INTNX('WEEK','06NOV2014'd,3)
INTNX('DTWEEK','06NOV2014:15:00:00'dt,3)
INTNX('TENDAY','06NOV2014'd,3)
INTNX('DTTENDAY','06NOV2014:15:00:00'dt,3)
INTNX('SEMIMONTH','06NOV2014'd,3)
INTNX('DTSEMIMONTH','06NOV2014:15:00:00'dt,3)
INTNX('MONTH','06NOV2014'd,3)
INTNX('DTMONTH','06NOV2014:15:00:00'dt,3)
INTNX('QTR','06NOV2014'd,3)
INTNX('DTQTR','06NOV2014:15:00:00'dt,3)
INTNX('SEMIYEAR','06NOV2014'd,3)
INTNX('DTSEMIYEAR','06NOV2014:15:00:00'dt,3)
INTNX('YEAR','06NOV2014'd,3)
INTNX('DTYEAR','06NOV2014:15:00:00'dt,3)
INTNX('SECOND','8:00:00AM't,3)
INTNX('MINUTE','8:00:00AM't,3)
INTNX('HOUR','8:00:00AM't,3)
Example5.12:TheINTNX()Function:UsingNon-IntegerIncrements
INTNX('HOUR','16:45't,2.5)
Whenthenumberofincrementsargumentis
notaninteger,SASwilltaketheintegerpartasthevalue.Inthiscase,2.5becomes2.Thebeginningofthefirsthourincrementis17:00,andthesecondis18:00.SincealignmentisthedefaultvalueofBorbeginning,thatsetstheanswertothebeginningofthehour,
whichgivestheresultof18:00.
Example5.13:CountingBackwardwiththeINTNX()Function
INTNX('DAY','29NOV2014'd,-4)
INTNX()alwaysaddsthenumberofintervalstothestartingdate,
time,ordatetime.Ifyouwanttofindapriordate,thenuseanegativeincrement.
Example5.14:TheINTNX()FunctionwithAlignmentArguments
INTNXCall
INTNX('WEEK','02NOV2014'd,3,'
INTNX('WEEK','02NOV2014'd,3,'
INTNX('WEEK','02NOV2014'd,3,'
INTNX('WEEK','02NOV2014'd,3,'
AlthoughthealignmentargumentsdochangethevaluereturnedbytheINTNX()function,itmustbereiteratedthatthefunction
performsthecalculationbasedonthebeginningoftheinterval,andtheadjustmenttothefinalresultonlyoccursafterthatfirstcalculationhasbeendone.
5.6ModifyingSASIntervals
ThedefaultSASintervalsdon'tmatcheverysituation.However,therearetwowaystocustomizeSASintervals:YoucanmodifytheexistingSASintervalswithmultipliersandashiftindex,oryoucancreateyourownintervalsfromaSASdataset.Thissection
willdiscussmultipliersandtheshiftindex.Section5.7willdiscusscreatingyourownintervals.
TheintervalfunctionINTCK(interval,start-of-period,end-of-period,method)countsthenumberofintervalsbetweentwogivenSASdates,times,or
datetimes,whiletheINTNX(interval,start-from,number-of-increments,alignment)functionadvancesagivendate,time,ordatetimebyaspecifiednumberofintervals.BothfunctionsusethestandardSASintervaldefinitions.(SeeTable5.6,below.)WiththeDISCRETEmethod,the
INTCK()functioncountsatthestartingpointofagiveninterval,whiletheCONTINUOUSmethodadjuststhestartingpointoftheintervalbasedonthestartingdateandcountsfromthere.Eachmethodhasitsmerits,andwhichoneyouusewilldependonyour
analysisorreportingneeds.
TheINTNX()functionalwaysadvancestothebeginningofthegiveninterval.ThealignmentargumentavailablewithINTNX()willadjusttheresulttothemiddle,end,orthesamedayoftheinterval.Nonetheless,
theintervalsarestillmeasuredfromtheirstartingpoint,andtheadjustmentisonlyappliedafterINTNX()hasmovedthespecifiednumberofintervals.
Thisbehaviorcanleadtoproblemswhenyourdefinitionofanintervaldoesn'texactlymatch
thestandardSASdefinitionofthatsameinterval.Forexample,thestandardSASdefinitionofyearhasthefirstdayoftheyeardefinedasstartingJanuary1.WhathappensifyourfiscalyearstartsonJuly1,andthatishowyouwanttomeasureyouryear?Whatifyour
semi-monthperiodistruly14dayslong?
Ashiftindexandintervalmultipliersenableyoutodothis.Youhavetheabilitytodefinethestartofanintervaldefinitionbyaddingashiftindextoit.Theshiftindexdefinesthenumberofshiftpointstomovethe
startoftheinterval.Thereisonerestrictiononthevalueoftheshiftindex:Itmustbelessthanthenumberofshiftpointswithintheinterval.Forexample,youcanshiftthestartofaYEARintervalbyupto12months,butnot13,asthereareonly12monthsinayear.Thismakessense
asifyouweretoshiftayearby13months,youhaveshiftedintothenextYEARinterval,andthisismuchlessintuitivethanadding1yeartothestartingdate(s)thatyousendtotheintervalfunction.
Table5.6showstheSASintervalname,definition,andtheshift
incrementperiodforeachone.
Table5.6:SASIntervalsandTheirShiftPoints
Category Interval
Date DAY
WEEK
WEEKDAY<daysW>
TENDAY
SEMIMONTH
MONTH
QTR
SEMIYEAR
YEAR
Datetime DTDAY
DTWEEK
DTWEEKDAY<daysW>
DTTENDAY
DTSEMIMONTH
DTMONTH
DTQTR
DTSEMIYEAR
DTYEAR
DTSECOND
DTMINUTE
DTHOUR
Time SECOND
MINUTE
HOUR
Forourfirstexample,let'susethestandardcaseofafiscalyearthatstartsonJuly1.Technically,ashiftindexsaysthatyouaremovingthestartoftheintervaltothebeginningofoneofthesubperiodswithinthat
interval.Yearsaresubdividedintomonths,sothatistheshiftunit.Thestartpointisalwaysincludedinthecountofsubperiodstobeshifted.Theeasiestwayformetorememberthisisthatshiftinganintervalbyonesubperiodisthesameastheunshiftedbase
interval.Thinkofthisanotherway:whilethestartoftheyearisJanuary1,thebeginningofthefirstmonthintheyearisalsoJanuary1.Ifweuseashiftindexof1withourYEARinterval,weareshiftingtothebeginningofthefirstmonthintheyear.
Therefore,inordertomoveyourYEARintervalbysevenmonths,youneedtomoveittothebeginningoftheseventhsubperiod.(January1,February1,March1,April1,May1,June1,July1—that'sseven).Theshiftvalueisaddedtotheintervalnameby
appendingitwithadecimalpoint.
Therefore,inordertoadvancethestartoftheYEARintervalbysevenmonthstoJuly1,youwouldusetheinterval"YEAR.7,"asillustratedbythefollowing:
Example5.15:
MovingtheStartofaYearIntervalfromJanuary1toJuly1 SampleFunctionCall
A INTCK('YEAR','01jan2013'd,'06jul2014'd,'DISCRETE');
B INTCK('YEAR','01jan2013'd,'06jul2014'd,'CONTINUOUS');
C INTCK('YEAR.7','01jan2013'd,'06jul2014'd,'DISCRETE');
D INTCK('YEAR.7','01jan2013'd,'06jul2014'd,'CONTINUOUS');
INTCK()countsthestartofintervalboundarieswiththeDISCRETEmethod(rowsAandC).Whentheintervalis"YEAR,"itismeasuringfromJanuary1,2013,until
January1,2014(thestartoftheyearcontainingJuly6,2014).Whentheintervalis"YEAR.7,"youhaveshiftedthebeginningoftheYEARintervalby7months,whichdeclaresthattheyearstartsonJuly1.Intheexampleabove,thatshiftcausesthemeasurementtobegin
onJuly1,2012(thestartoftheshifted"year"containingJanuary1,2013)andendonJuly1,2014,whichisthestartoftheyearcontainingJuly6,2004.ThatiswhythevaluereturnedinrowCis2,not1.WiththeCONTINUOUSmethod,theshiftedyearstartsonJuly1,2013,sothe
startdateisbeforethestartofthemeasurement.Therefore,theonlyintervalboundarycrossedisonJuly1,2014,sotheanswerinrowDis1.
WhileashiftindexenablesyoutomovethestartingpointofanygivenSASinterval,
anintervalmultiplierenablesyoutodefinethelengthofyourownintervals.Youdefineyournewintervalbyapplyingamultipliervaluetoaninterval.Forexample,ifyouwanttomeasurebiweekly(14-day)periods,youwouldtaketheWEEKintervalandmultiplyitby2.
YouaddthenumericmultipliertotheendoftheSASintervalname,sointhiscaseyourintervalnamewouldbe"WEEK2."Itmeasures14-dayperiodsstartingonSundaybecausetheregularSASintervalWEEKstartsonSunday.Example5.16demonstratesthecreationanduseofa
custominterval,byusingtheexampleofamultiplierof2fortheWEEKinterval.Italsoillustratessomeofthefeaturesofcustomintervals.
Example5.16:UsinganInterval
MultipliertoCreateaCustomIntervalSampleFunctionCall
INTNX('WEEK','09feb2014'd,2,'S');
INTNX('WEEK2','09feb2014'd,2,'S');
Intheaboveexample,thestartoftheWEEKintervaltwoweeksfromFebruary9isFebruary23,soitmakessensethatthestartofthesecondbiweeklyperiodfromFebruary9isMarch9,
becauseFebruary2014has28days,whichisthesameastwoofyourWEEK2intervals.Thisisnotassimpleasitseems.WhenusingSASintervalswiththeINTNX()function,youmustkeepinmindthatintervalsarealwaysmeasuredfromthebeginningofthestartingintervaltothe
beginningoftheendinginterval.Thisisindependentofthestartingandendingdatesthatyousupply.Let'smovethestartingdateinExample5.16backwardbyoneweektoFebruary2,2014.
SampleFunctionCall
1 INTNX('WEEK','02feb2014'd,2,'S');
2 INTNX('WEEK2','02feb2014'd,2,'S');
AdvancingbytwoWEEKS(row1)isstilladifferenceof14days,asexpected.What
happenedinrow2?Shouldn'tyouget28daysinsteadof21?No,becausethestartoftheWEEK2intervalcontainingFebruary2,2014,isJanuary24,2014,andthatiswheretheINTNX()functionbeginsitscount.Hereisasampleprogramtoproducethestartingdatesoftheintervals:
Example5.17:WEEK2IntervalsfromJanuary1,2014
DATAtricky;DOintervals=0TO5;interval_start=INTNX('WEEK2','01jan2014'd,intervals);OUTPUT;END;RUN;
PROCREPORTDATA=tricky
NOWDSPLIT='\';COLUMNSintervalsinterval_start;DEFINEintervals/DISPLAY"NumberofWEEK2\intervalsfrom\January1,2014"STYLE={CELLWIDTH=1.25inTEXT_ALIGN=C};DEFINEinterval_start/FORMAT=weekdate32."StartingDateofInterval";RUN;
TheaboveprogramcreatesatablethatshowsthestartingdatesforthefirstfiveWEEK2intervalsof2014.Ifthedate(s)suppliedfallbetweenthestartingdatesofanytwoboundaries,theintervalcount(orincrementing)willbeginfromthestartingdateoftheprevious
interval.ThisiswhymovingthestartingdateoftheINTNXfunctionbyoneweekdoesn'tnecessarilymovetheresultbyoneweek.Youcanmoveupto14dayswithinaWEEK2intervalbeforeyouchangetheintervalboundary.
NumberofWEEK2intervalsfromJanuary1,2014
StartingDateofInterval
0 Sunday,December29,2013
29,2013
1 Sunday,January12,
2014
2 Sunday,January26,
2014
3 Sunday,February9,
2014
2014
4 Sunday,February23,
2014
5 Sunday,March9,2014
HowdoesSASdeterminewhatthe
startingdateofagivenintervalisifyouuseamultiplier?Ittakesthemultipliedintervalthatyou'vecreatedandstartscountingbeginningwithJanuary1,1960.ThisistrueforallmultipliedintervalsexceptmultipliedWEEKintervals.MultipliedWEEKintervalsarecounted
startingfromSunday,December27,1959,becauseweeksaredefinedasstartingonSundays,andJanuary1,1960,wasaFriday.
Youcanalsouseamultiplierandashiftindicatortogetherifneeded.Intervalmultipliersaredirectlyappendedtothe
intervalname(forexample,WEEK2),andshiftindicatorsareappendedtotheintervalnamewithaleadingdecimalpoint(forexample,WEEK.5).Touseboththemultiplierandashiftindex,youfirstappendthemultipliertotheintervalnametocreateanewintervalname
(forexample,WEEK2),andthenyouappendtheshiftindicatortotheintervalname.Givenamultiplierof2,andashiftof5,theintervalnamebecomes"WEEK2.5."Again,youcannotuseashiftindexthatisgreaterthanthenumberofshiftpointsintheinterval.InthecaseofaWEEK2
interval,youwouldnotbeabletouseashiftindexgreaterthan14,asthatwouldplacethestartingpointofyourintervalintothenextWEEK2interval.Inthatcase,itwouldbemoreintuitivetochangethestartingdate(s)thatyouwillsupplytotheintervalfunction.
Todemonstrate,let'sexpandonthescenariousedinexample5.17.WhatifyouwantedyourbiweeklyperiodstostartonJanuary1,2014?January1,2014,wasaWednesday,soyouwanttomovethestartingdatetothefourthdayoftheweek(Sunday=1,therefore,Wednesday=4).Now
we'llgeneratethesametableasabove,usingashiftindicatorof4daysinadditiontothebiweeklyintervalofWEEK2.
Example5.18:UsingBothanIntervalMultiplierand
ShiftIndextoCreateaCustomInterval
DATAtricky;DOintervals=0TO5;plain_interval_start=INTNX('WEEK2','01jan2014'd,intervals);shifted_interval_start=INTNX('WEEK2.4','01jan2014'd,intervals);OUTPUT;END;RUN;
PROCREPORTDATA=trickyNOWDSPLIT='\';COLUMNSintervalsplain_interval_startshifted_interval_start;DEFINEintervals/"NumberofWEEK2\intervalsfrom\January1,2014"STYLE={CELLWIDTH=1.25inTEXT_ALIGN=C}DISPLAY;DEFINEplain_interval_start/."StartingDateofWEEK2Interval"FORMAT=weekdate32.;
DEFINEshifted_interval_start/"StartingDateofWEEK2.4Interval"FORMAT=weekdate32.;RUN;
NumberofWEEK2Intervalsfrom
StartingDateof
StartingDateof
January1,2014
WEEK2Interval
WEEK2.4Interval
0 Sunday,December29,2013
Wednesday,January1,
1 Sunday,January12,2014
Wednesday,January15,
2 Sunday,January
Wednesday,January29,
January
26,2014
January29,
3 Sunday,February9,2014
Wednesday,
4 Sunday,February23,2014
Wednesday,
5 Sunday,March9,
Wednesday,March12,
2014
Whenyouuseamultiplier,youalsohavetheabilitytodefineyourshiftswithintheentireintervalcreatedbythemultiplier.Forexample,let'screateadecadeintervalby
usingYEAR10astheinterval.Rememberthatintervalsstartatthebeginningoftheboundary,sothedecadeswouldstartatthebeginningofthefirstyearofthedecade.WhatcanyoudoifyouwanttodefinethedecadeasstartinginMayofthemiddleyearinthedecade(for
example,Mayof1955asopposedtoJanuaryof1950)?
Toshiftintervalsacrossyears,youneedtousethefirstnestedintervalwithintheYEARinterval,whichisMONTH.Soyouwoulduse(numberofyearstoshift*12)tocalculatethenumberofmonths
thatyouneedtoshift.Ifyouwantedtoshift5years,youwoulduse5*12=60.Add5tothat,whichshiftsthestartingmonthfromJanuarytoMay,andyourintervaldefinitionisnowYEAR10.65.ThatwouldbedecadesstartinginMayofyearsthatendin5.Thecodebelowshowstheeffect
ofmovingtheintervalby65months.
Example5.19:ShiftingaMultipliedInterval
DATAtricky3;DOintervals=0TO7;plain_interval_start=INTNX('YEAR10','01sep1950'd,intervals);shifted_interval_start
=INTNX('YEAR10.65','01sep1950'd,intervals);OUTPUT;END;RUN;
odsrtffile="c:\book\2ndEd\examples\ex5.6.5.rtf";
PROCREPORTDATA=tricky3NOWDSPLIT='\';COLUMNSintervalsplain_interval_startshifted_interval_start;DEFINEintervals/DISPLAY"Numberof\intervals
from\September1,1950"STYLE={CELLWIDTH=1inTEXT_ALIGN=C};DEFINEplain_interval_start/FORMAT=weekdate32."StartingDateofYEAR10Interval";DEFINEshifted_interval_start/FORMAT=weekdate32."StartingDateofShiftedYEAR10Interval";RUN;
NumberofIntervalsfromSeptember1,1950
StartingDateofYEAR10Interval
0 Sunday,January1,
1950
1 Friday,January1,
January1,
1960
2 Thursday,January1,
1970
3 Tuesday,January1,
1980
4 Monday,January1,
1990
5 Saturday,January1,
2000
6 Friday,January1,
2010
7 Wednesday,January1,
2020
ThefirstthingtonoteisthateventhoughthedatethatwespecifiedisSeptember1,thestartingdateoftheintervalisJanuary1,becausethatisthestartoftheYEARinterval.Inthesecondcolumn,youcanseethatthe
intervalhasbeenshifted.EventhoughthestartingdateoftheYEAR10.intervalisJanuary1,1950,theshiftedintervalitselfstartsonTuesday,May1,1945(bolditalicsadded),notMay1,1955.Why?BecauseitisthestartoftheintervalthatcontainsJanuary1,1950.
Thenextexamplewilldemonstratetheimportanceofmakingsurethatyouusethecorrectshiftindexandthatyouhavetobeawareofthestartingdateand/ordatetimeforyourshifted,multipliedinterval.
Example5.20:
TheInteractionbetweentheStartingDateandtheIntervalStartingPoint:The"WorkingShift"IntervalAcompanyhasa24-hourproductioncyclethatconsistsofthree8-
hourworkingshiftsperday.ItiseasytocreateanintervalthatrepresentseachshiftbyusingHOUR8asyourbaseinterval,butshiftsdonotstartatmidnight,8a.m.,and4p.m.,whichwouldbethedefaultfortheHOUR8interval.ThetablebelowshowswhentheHOUR8
intervalstartsbasedonthedefault.
FunctionCall
INTNX('HOUR8','00:00't,0)
INTNX('HOUR8','00:00't,1)
INTNX('HOUR8','00:00't,2)
However,inthiscase,theactualshiftsstartat6a.m.,2p.m.,and10p.m.,sowewillneedtouseashiftindextoalignourHOUR8intervalwiththeactualshifthours.Itisimportanttorememberthatwhenyouare
shiftingintervals,ashiftindexof1movesthestartoftheintervaltothestartofthefirstsubperiodwithintheinterval—whichisalwaysthesameasthestartoftheunshiftedinterval.Lookatthefollowingtable,whichwilltelluswhatintervalshiftwillgiveusthestartingpointat
6a.m.
FunctionCall
INTNX('HOUR8','6:00't,0);
INTNX(HOUR8.1,'6:00't,0)
INTNX(HOUR8.2,'6:00't,0)
INTNX(HOUR8.3,'6:00't,0)
INTNX(HOUR8.4,'6:00't,0)
INTNX(HOUR8.5,'6:00't,0)
INTNX(HOUR8.6,'6:00't,0)
INTNX(HOUR8.7,'6:00't,0)
Noticethatintheabovetable,we'veused6a.m.asourreferencetimeintheINTNX()
functioncall,andwegetthestartingpointoftheintervalbyadding0intervalstoourreferencepoint.Thismethodworksforfindingthestartingpointofanyintervalinrelationtothereferencepoint.Nowwe'llrepeatourfirsttable,showingthestartingpointsfora24-
hourperiodstartingat6a.m.,withourHOUR8.7intervaltodemonstratethateverythingiscorrect.
FunctionCall
INTNX('HOUR8.7','06:00't,0)
INTNX('HOUR8.7','06:00't,1)
INTNX('HOUR8.7','06:00't,2)
Althoughitmightseemoddthatashiftindexof7isneededtogetachangeof6hours,youmustrememberthat
theshiftindexisthenumberofsubperiodswithintheintervaltomove.Theshiftisalwaystothebeginningofeachsubperiodwithintheinterval.Therefore,thefirstsubperiodwithinanintervalalwaysstartsatthebeginningoftheinterval.Inthiscase,theHOUR8interval
startsatmidnight,andthefirsthourwithintheHOUR8intervalalsostartsatmidnight.Thatiswhytheshiftindexnecessaryis7,not6.
Insummary,themostimportantthingtorememberaboutusingintervals,multipliers,andtheshiftindexis
thatallintervals,nomatterhowtheyaredefined,aremeasuredfromtheirbeginning.IfyouareusingtheINTCK()function,thedefinitionof"beginning"isdependentuponthemethodthatyouuse,DISCRETEorCONTINUOUS.WithDISCRETE,itis
consideredtobethebeginningoftheintervalboundary,butwithCONTINUOUS,beginningisdefinedbasedonthestartdateprovided.TheINTNX()functionmeasuresthebeginningfromtheintervalboundary;ifitiseasiertothinkofINTNXasalwaysusingtheDISCRETEmethod,
thenyoucandothat.However,rememberthatthealignmentarguments"B","M","E",and"S"fortheINTNX()functiondonotadjustthedateuntilafterthefunctionhasexecutedandcalculateditsstart-of-intervalresult(alsorememberthatthealignmentargumentsonlyworkwiththe
INTNX()function).Nomatterwhat,youcanusetheintervalmultipliersandashiftindextomovethestartingpointofaninterval,andyoucanusethemanywherethatyoucanuseadate,time,ordatetimeinterval.
5.7CreatingYourOwnSASIntervalsAnotherwaytocreateintervalsforusewithintervalfunctionsisbycreatingaSASdatasetthatdefinestheboundariesofyourinterval.Thisdatasetdefinesthedurationofperiodswithintheintervalandtheperiod
acrosswhichtheintervalappliesaswell,whichisanimportantconceptthatwillbediscussedwhenitcomestoerrorswithusinguser-definedintervals.User-definedintervalsenableyoutocreateintervalsthatdonotcorrespondwithshiftedand/ormultipliedSAS
intervals,suchasintervalswithirregularboundaries,thosethatdonotencompassanentirepredefinedSASinterval,orintervalsthatarespecifictoyourjob,company,orindustry.However,ifyouneededtocountworkingshiftsinasituationwheretherearetwo10-hourwork
shiftsperdaywithafour-hourbreakin-betweenwhilethemachineryresets,youcouldnotdoitbyusingmultipliersandashiftindex.
Youcanalsoredefineaninterval.Forexample,theshiftpointforadayistheday;whathappensifyou
wantyour"day"tostartat6a.m.insteadofmidnight?DTHOUR24.7wouldcreateanintervalthatruns24hoursstartingat6a.m.(Seeexample5.20,whichdoesthesameforanHOUR8interval.Theonlydifferenceisthatthereare24-hour-longsubperiodsina
DTHOUR24interval.)Unfortunately,theoriginalquestionwastoshiftaDAYintervalby6hours,butyoucan'tdothatwithadatevalue.DTHOURintervalsonlyapplytodatetimevalues.Youwouldhavetoconvertallofyourdatedatatodatetimedatainordertousethatinterval.
Definingyourownintervalwheredaysstartatthedesiredtimewouldsolvethisproblem.
TheSASdatasetyouhavetocreateconsistsofatleastonevariablenamedbegin.Itcanalsohavetwootheroptionalvariables,endandseason.Ifyoudo
notincludetheendvariable,itisassumedtobeonelessthanthestartofthenextperiodwithinthatinterval;forexample,ifyouruser-definedintervalisbasedondays,theendwillbethedaybeforethebeginvalueforthenextrecord.Whileseasonalityisatimeseriesconceptoutside
ofthescopeofthisbook,itcanbeaccountedforwiththevariableseason.Oneadditionalrequirementisthatbegin(andend,ifpresentinthedataset)musthaveanappropriatedate,time,ordatetimeformatassignedatthetimethatthedatasetiscreated.Inorderto
associatethisdatasetwithauser-definedinterval,youneedtousetheINTERVALDSsystemoption.
OPTIONSINTERVALDS=(interval-name1,dataset-with-interval-records1,interval-name2,dataset-with-interval-records2…)
Thisiswhereyounameyouruser-definedintervalandtellSASwhichdatasettouseforthatinterval.Youcanspecifyasmanyuser-definedintervalsasyouneedinasingleOPTIONSINTERVALDSstatement.interval-namemustconformtostandardSASnamingconventions,andit
cannotbeaSASreservedword.Ifyoutrytouseareservedword,youwillgetanerrorattheOPTIONSstatement.ThisappliestonamesofexistingintervalsdefinedbySASaswell.YoucannotchangethedefinitionofanexistingSASintervalbycreatingoneofyour
ownwiththesamename.dataset-with-interval-recordsisastandardSASdatasetreferenceofthetypelibref.dataset-name.Sincethisstatementmerelyidentifiesadatasetforassociationwithyourintervalname,datasetoptionsarenotallowed.
Forourfirstexample,let'sdefineaSEMESTERinterval,basedonanacademiccalendarwithtwosemestersandasummersession.Thesessionsaredefinedasfollows:ThefallsemesterbeginsthedayfollowingthefirstMondayinSeptemberandendsonthethird
FridayinDecember.ThespringsemesterbeginsonthesecondMondayinJanuary,unlessthatdayfallsontheMartinLutherKing,Jr.,holiday.Inthatcase,itbeginsonthedayfollowingtheholiday.ThesummersessionstartsonthelastTuesdayinMayandproceedsthrough
thethirdFridayinAugust.ThefollowingexampleusesboththeNWKDOM()andHOLIDAY()functionsdescribedinsections5.3and5.4,respectively.
Example5.21:AcademicCalendar:
CreatingaSEMESTERInterval
OPTIONSINTERVALDS=(semester=semester);❶
DATAsemester;
DOyear=2014TO2017;❷
/*FallSemester*/begin=NWKDOM(5,2,8,year);/*LastMondayinAugust*/
end=NWKDOM(3,6,12,year);/*ThirdFridayinDecember*/OUTPUT;
/*SpringSemester*/begin=NWKDOM(2,2,1,year+1);/*SecondMondayinJanuaryoffollowingcalendaryear*/ifbegineqHOLIDAY('MLK',year+1)then/*IfMLKday,thenTuesday*/
begin=begin+1;end=NWKDOM(2,6,5,year+1);/*SecondFridayinMay*/OUTPUT;
/*SummerSession*/begin=NWKDOM(1,2,6,year+1);/*FirstMondayinJune*/end=NWKDOM(3,6,8,year+1);/*ThirdFridayinAugust*/OUTPUT;END;FORMATbeginend
WEEKDATE.;/*Required*/RUN;
❶tellsSASthatwearedefininganintervalnamed"semester,"anditistobebasedonthedatasetWORK.SEMESTER.
❷setsadefinitelimitontheinterval,fromthestartofthe2014academicyear
throughthe2017academicyear,whichendsinAugust2018.Belowistheresultingdataset:
begin end
Monday,August25,
2014
Friday,December19,2014
Monday,January12,
2015
Friday,May8,2015
Monday,June1,2015
Friday,August14,
2015
Monday,August31,
2015
Friday,December18,2015
Monday,January11,
2016
Friday,May13,2016
Monday,June6,2016
Friday,August12,
2016
Monday,August29,
2016
Friday,December16,2016
Monday,January9,
2017
Friday,May12,2017
Monday,June5,2017
Friday,August11,
2017
Monday,August28,
2017
Friday,December15,2017
Monday,January8,
2018
Friday,May11,2018
Monday,June4,2018
Friday,August10,
2018
YoucanthenusetheSEMESTERintervalthatyouhavecreated
intheINTCKorINTNXintervalfunctions.ThefollowingtableshowshowmanysemestershaveelapsedfromSeptember15,2014,totherespectiveenddatesshown.
Example5.22:UsingaUser-DefinedInterval
withINTCKFunctionCall
INTCK('SEMESTER',"15SEP2014"d,"22JUN2015"d);
INTCK('SEMESTER',"15SEP2014"d,"24NOV2016"d);
INTCK('SEMESTER',"15SEP2014"d,"01MAY2018"d);
Forasecondexample,let'sconsideracasewhereweneedto
counttheactualnumberofworkingdaysforeachyear.TheWEEKDAYintervalisausefulapproximation,butitdoesn'taccountforholidays,soifyouneedtoknowtheexactnumberofworkingdaysbetweentwodates,thiswillsolvethatproblem.
Example5.23:CustomizedCompanyWorkingDays
OPTIONSINTERVALDS=(WorkingDays=Workdays);DATAworkdays(KEEP=begin);/*Endvariablenotneeded*/start='01JAN2014'D;stop='31DEC2015'D;nweekdays=INTCK('WEEKDAY',start,stop);
/*BasedonMon-Friweekdays*/DOi=0TOnweekdays;begin=INTNX('WEEKDAY',start,i);year=YEAR(begin);
/*Company-specificholidays*/
/*Companyclosesdayafterthanksgiving*/xthanks=HOLIDAY("THANKSGIVING",year)+1;/*ChristmasEve*/xmaseve=
HOLIDAY('CHRISTMAS',year)-1;/*FridaybeforeEaster*/sprng=HOLIDAY("EASTER",year)-2;/*FoundersDayCompanyHoliday.Ifonweekend,moveforwardorback*/
founders=MDY(8,6,year);SELECT(WEEKDAY(founders));WHEN(6)founders=founders-1;WHEN(1)founders
=founders+1;OTHERWISEfounders=founders;END;
/*Excludedatesofstandardandcompanyholidaysfromintervaldataset*/IFBEGINneHOLIDAY("NEWYEAR",year)ANDBEGINneHOLIDAY("MLK",year)ANDBEGINneHOLIDAY("USPRESIDENTS",year)AND
BEGINneHOLIDAY("MEMORIAL",year)ANDBEGINneHOLIDAY("USINDEPENDENCE",year)ANDBEGINneHOLIDAY("LABOR",year)ANDBEGINneHOLIDAY("VETERANS",year)ANDBEGINneHOLIDAY("THANKSGIVING",year)ANDBEGINneHOLIDAY("CHRISTMAS",year)AND
BEGINnexmaseveANDBEGINnexthanksANDBEGINnesprngANDBEGINnefoundersTHENOUTPUT;END;FORMATbeginDATE9.;RUN;
Thefollowingcodegeneratesatableshowingthedifference
betweenthenumberofcalendardays,thenumberofweekdays,andthenumberofworkingdaysforthiscompanyforthecalendaryear2014.
DATACountDays;start='01JAN2014'D;stop='01JAN2015'D;ActualDays=INTCK('DAYS',start,stop);Weekdays=
INTCK('WEEKDAYS',start,stop);ProductionDays=INTCK('WORKINGDAYS',start,stop);LABELActualDays="ActualDays"Weekdays="Weekdays"ProductionDays="ProductionDays"start="StartingDate"end="EndingDate";FORMATstartstopDATE9.;RUN;
PROCPRINTDATA=CountDaysNOOBS;RUN;
start stop
01JAN2014 01JAN2015
Howmuchofadifferencecanthismake?Considerthatthiscompanyhassixproductlinesandthe
timetomanufactureeachproductvaries.Acustomercomesinwithalargeorderandwantstoknowwhatthedeliverydatewouldbeforeachproduct.Itiscriticalthatthedeliverybeguaranteedtotheday,sothecontractcallsforasubstantialdiscountifthedeliverydateisnot
met.Inthefollowingtable,theorderdateisJune27,2014.WeusetheINTNX()functiontoaddthecorrespondingnumberofproductiondaysforeachproducttotheorderdate.TheapproximatedeliverydateiscalculatedusingtheSASWEEKDAYinterval,whilethetrue
deliverydateusesouruser-definedWORKINGDAYSinterval.
DATAproduction_lines;LENGTHproduct$40;orderDate="27JUN2014"d;Product="StdProduct1";days_from_order=23;OUTPUT;Product="StdProduct2";
days_from_order=32;OUTPUT;Product="StdProduct3";days_from_order=35;OUTPUT;Product="CustomProduct1";days_from_order=33;OUTPUT;Product="CustomProduct2";days_from_order=42;OUTPUT;Product="CustomProduct3";
days_from_order=56;OUTPUT;FORMATorderdateweekdate.;RUN;
DATAordertime;SETproduction_lines;deliveryDate=INTNX('WORKINGDAYS',orderdate,days_from_order,'S');approx_deliveryDate=INTNX('WEEKDAY',orderdate,days_from_order,'S');FORMATdeliverydateapprox_deliveryDateweekdate.;RUN;
PROCREPORTDATA=ordertimeNOWDSPLIT='\';COLUMNSproductdays_from_orderapprox_deliveryDatedeliveryDate;DEFINEproduct/"Product";DEFINEdays_from_order/"ProductionDays\Required"STYLE={TEXT_ALIGN=C};DEFINEapprox_deliveryDate/STYLE={TEXT_ALIGN=L}
"~S={text_align=c}ApproximateDeliveryDate\usingWEEKDAYSInterval";DEFINEdeliveryDate/"~S={TEXT_ALIGN=C}ActualDeliveryDate\usingCustom\WORKINGDAYSInterval"STYLE={TEXT_ALIGN=L};RUN;
ApproximateDelivery
Product
ProductionDaysRequired
DateUsingWEEKDAYSInterval
StdProduct1
23July30,2014
StdProduct2
32
StdProduct3
35 Friday,August
CustomProduct1
33
CustomProduct2
42
2
CustomProduct3
56September15,
Thereisonespecificproblemtobeawareofwhenyouareworkingwithuser-definedintervals.Ifaspecific
date,time,ordatetimeisnotcoveredintheintervaldataset,andyoutrytouseoneofthesevaluesinafunction,oroneofthesevaluesistobereturnedbyafunction,youwillnotgettheanswerthatyouexpect.Suchunexpectedresultscanbeavoidedbyensuringthatthe
datesthatyoudefineinthedatasetencompassallthedatesthatyoumayencounter.Thenexttwoexampleswilldemonstratewhathappenswhenyouuseadatethatisoutoftherangeofyouruser-definedinterval.WewillusetheWORKINGDAYSintervalasdefinedin
thepreviousexample.Thatintervalisonlydefinedforaperiodof2years,fromJanuary1,2014,throughDecember31,2015.WhathappensifyoutrytocalculatethenumberofworkingdaysusingtheINTCK()functionwithendingdatesoutsideofthatrange,oryoutryto
projectadateusingtheINTNX()functionthatwouldbebeyondthatrange?
Example5.24:Out-of-IntervalCalculationUsingINTCK()and
"WORKINGDAYS"CustomIntervalObs startDate endDate
1 Wednesday,December23,2015
Thursday,December24,2015
2 Wednesday,December
Friday,December
23,2015 25,2015
3 Wednesday,December23,2015
Saturday,December26,2015
4 Wednesday,December23,2015
Sunday,December27,2015
5 Wednesday,December
Monday,December
23,2015 28,2015
6 Wednesday,December23,2015
Tuesday,December29,2015
7 Wednesday,December23,2015
Wednesday,December30,2015
8 Wednesday,December
Thursday,December
23,2015 31,2015
9 Wednesday,December23,2015
Friday,January1,
10 Wednesday,December23,2015
Saturday,January2,
11 Wednesday,December
Sunday,January3,
23,2015
12 Wednesday,December23,2015
Monday,January4,
13 Wednesday,December23,2015
Tuesday,January5,
14 Wednesday,December
Wednesday,January6,
23,2015
15 Wednesday,December23,2015
Thursday,January7,
Rows1through4makesense.TherearenoworkingdaysfromThursdaythroughSunday,asDecember24isacompany
holiday.Rows5through8countaworkingdayforMondaythroughThursdayasyouwouldexpect.Friday,January1,2016,isalsoacompanyholiday.Therefore,youwouldnotexpectittocountasaworkingday,norwouldyouexpectthefollowingSaturdayand
Sundaytocountasworkdays.ButwhataboutthatfirstfullweekinJanuary,rows12through15?Thosedaysaren'tcompanyholidays,sowhyaren'ttheybeingcountedasworkingdays?
Theansweristhattheyaren'tpartoftheWORKINGDAYS
interval.ThedefinitionoftheintervalendedonDecember31,2015.Becausetheyarenotinthedataset,anydatesbeforeorafterthedatesspecifiedinthedatasetwillnotbeconsideredworkingdays.Thismakessensewhenyouconsiderhowweinitiallycreatedthecompanyholidays.We
didnotincludethosedatesinthedatasetthatcreatedtheinterval.Therefore,thisproblemactuallystartswithJanuary1,2016.ItismerelycoincidentalthatJanuary1stisaholiday,andthe2ndand3rdareweekenddays;thatisnotwhatispreventingthemfrom
beingcountedasworkingdays.Theirabsencefromthedatasetweusedtocreatetheintervalistheonlyreasonthattheyarenotbeingcounted.ThisnextexampleshowsthetypeofproblemthatcanarisewhenusingtheINTNX()functioninasimilarfashion.
Example5.25:Out-of-IntervalCalculationwithINTNX()and"WORKINGDAYS"CustomIntervalObs
1 INTNX('workingdays','26dec2015'd,1,'S');
2 INTNX('workingdays','26dec2015'd,2,'S');
3 INTNX('workingdays','26dec2015'd,3,'S');
4 INTNX('workingdays','26dec2015'd,4,'S');
5 INTNX('workingdays','26dec2015'd,5,'S');
6 INTNX('workingdays','26dec2015'd,6,'S');
7 INTNX('workingdays','26dec2015'd,7,'S');
8 INTNX('workingdays','26dec2015'd,8,'S');
Whathappenedhere?Rows1through4counttheworkingdaysasexpected,Monday
throughThursday.However,ifyoutrytoincrementthestartingdatebymorethan4workingdays,thefunctioncallreturnsamissingvalue.SAScannotdothecalculationbecausetheresultisundefined;itranoutofpossibleresultstoreturnatDecember31,2015,
becauseyoudidnotprovideanyinthedataset.
TheabilitytodefineyourownintervalswillcoversituationswhenthecombinationofstandardSASintervals,amultiplier,andashiftindexdoesnotsuffice.Itisnotdifficulttocreatethedataset
uponwhichSASwillbaseyouruser-definedinterval,butbeawarethatdatesthatarenotincludedintheintervalcancauseproblemswhenyoutrytousetheintervalsthatyoucreate.Ifyouseeunexpectedresultsfromusingyouruser-definedinterval,thefirstthingto
investigateistomakesurethattherangethatyouhavedefinedforyourintervalencompassestherangeofpossibleresults.
5.8IntervalFunctionsaboutIntervals
SAShasaseriesoffunctionsthatprovideinformationaboutintervalsthatarebeingused.Theycantellyouwhichintervalisthebestfitbetweentwoorthreedates,orsuggestaformatforagiveninterval.Thereisafunctiontotellyoutheshiftpointineffectforagiveninterval.(For
basicintervals,thisreturnsthevaluesinTable5.5,butintervalmultiplierscanchangethereturnedvalue.)Thereisalsoafunctionthatwilltellyouiftheintervalnamethatyouareusingisvalid.Thiscanallowforincreasedautomationandbuildingrobustapplications.
5.8.1INTFIT(argument-1,argument-2,type)INTFIT(argument-1,argument-2,type)takestwodate,datetime,orobservationnumbersasthefirsttwoargumentsandreturnstheintervalbetweenthemdeemed
tobe"thebestfit."Thisfunctionassumesthatthealignmentis"SAME,"sothattheexactvaluesarematchedbetweenthetwoarguments.typecanbeoneofthreecase-insensitivevalues:
IntervalName Definition
D UsewhenthetwoargumentsareSASdatevalues.Thesecanbedateliteralsorvariablescontaining
SASdatevalues
DT UsewhenthetwoargumentsareSASdatetimevalues.Thesecanbedatetime
literalsorvariablescontainingSASdatetimevalues
OBS Usethiswhenyouwanttofindtheinterval
betweentwoobservationsbyprovidingobservationnumbers.Thiswillreturnanintervalwiththebasenameof"OBS."
Youcanusethisfunctiontogiveyoutheintervalbetweentwopointsintime.Theintervalreturnedmightcontainamultiplierand/orashiftindex.Asyoucanseeinthetablebelow,someoftheintervalsarenotasyoumightanticipate.
start end
A Tuesday,April1,2014
Wednesday,April2,2014
B Tuesday,April1,2014
Thursday,April3,2014
C Tuesday,April1,2014
Friday,April4,2014
D Tuesday,April Saturday,April
1,2014 5,2014
E Tuesday,April1,2014
Sunday,April6,2014
F Tuesday,April1,2014
Tuesday,April8,2014
G Tuesday,April1,2014
Wednesday,April9,2014
H Tuesday,April Friday,April
1,2014 11,2014
I Tuesday,April1,2014
Sunday,April13,2014
J Tuesday,April1,2014
Tuesday,April15,2014
K Tuesday,April1,2014
Wednesday,April16,2014
L Tuesday,April1,2014
Thursday,April17,2014
M Tuesday,April1,2014
Saturday,April19,2014
N Tuesday,April1,2014
Monday,April21,2014
O 5/1/20149:00AM
5/1/20142:00PM
P 5/1/20149:00AM
5/1/20148:45PM
Q 5/1/20149:00AM
5/2/20143:30AM
Theitalicizedrowsshowexamplesofintervalsthatcanbepuzzling.Rememberthatthefunction
providestheexactintervalsbetweenthepairofdatesordatetimes,andthelowestcommondenominatorwillbeusedforbaseinterval.Inaddition,thedatesaremeasuredusingthesamedayalignment,whichmeansthattheintervalismeasuredfromthebeginningof
theinterval,andthenadjusted.Atfirstglance,theDAY5.5resultinrowEdoesn'tseemtoberight;Tuesdayisonlythethirddayoftheweek,soshouldn'ttheshiftbe3asitisfortheDAY3andDAY4intervals?ThestartofDAY5intervalsareSunday,thenFriday.Ifyou
wanttomeasureaDAY5intervaltoaSundayfromaTuesday,thenyouwillhavetomeasurefromtheFriday,whichgivesyouashiftof5.RowsPandQdemonstratethatitmightbecomeevenmoreconfusingwithtimesand/ordatetimes,asthebaseintervalshiftpointsbecome
minutesand/orseconds,sotheresultingmultipliersandshiftindicesmightbelargeenoughsothatyoulosethecontextofthereferencepoint.
ThefollowingtableshowsasampleresultofusingtheINTFIT()functionwiththe'OBS'type.Therecordsare
fromasequentialdatasetwithWednesday,April2,2014,asthefirstdate.Sincethedatesarekeyedbyobservation,theresultoftheINTFIT()functionshowstheintervalastherelationshipbetweenobservations,nottheactualdatevaluesthemselves.
SampleFunctionCall Date
INTFIT(1,1,'OBS') Wednesday,April2,2014
INTFIT(1,4,'OBS') Saturday,April5,2014
INTFIT(1,5,'OBS') Sunday,April6,2014
INTFIT(1,10,'OBS') Friday,April11,2014
INTFIT(1,12,'OBS') Sunday,April13,2014
INTFIT(1,13,'OBS') Monday,April14,2014
INTFIT(1,14,'OBS') Tuesday,April15,2014
INTFIT(1,16,'OBS') Thursday,April17,
2014
INTFIT(1,19,'OBS') Sunday,April20,2014
5.8.2INTFMT('interval','size')
INTFMT('interval','size')
takestheintervalthatyougiveandreturnsasuggestedformatfordate,time,ordatetimevaluesusingthisinterval.intervalcanbeanystandardSASinterval(withmultipliersand/orashiftindexifdesired),orauser-definedintervalthatyouhavecreated,asshownin
Section5.6.Ifintervalisrepresentedbyacharacterstring,thenitmustbeenclosedinquotationmarks,butyoucanuseacharactervariablecontainingthenameofanintervalinstead.sizereferstowhethertheformatreturnedwillhaveatwo-digityear('short'/'s')orafour-
digityear('long'/'l').Thisargumentmustbeenclosedinquotationmarksalso,butaswiththeintervalargument,youcanuseacharactervariablefortheargument.Thereisoneimportantusagenoteaboutthesizeargument:Ifyoudonotuselowercase,thefunctionmightreturn
anunpredictableresult(seeRowA)intheexampletablebelow:
SampleFunctionCall
A INTFMT('WEEK','LONG')
B INTFMT('WEEK','long')
C INTFMT('MONTH','long')
D INTFMT('QTR','short')
E INTFMT('QTR','long')
F INTFMT('YEAR','long')
G INTFMT('YEAR10','l')
H INTFMT('YEAR100','l')
I INTFMT('DTMONTH','l')
J INTFMT('DTYEAR','l')
K INTFMT('HOUR','l')
L INTFMT('WORKINGDAYS','l')
ThisfunctionismostusefulwhenyouusetheINTFITorINTGETfunctionstodetermine
theintervaldynamically,sothatyouwillalwaysdisplayaresultinthepropercontext.Seeexample5.23toseehowthiscanbeusedtodynamicallyformatresults.
5.8.3INTGET(argument1,argument2,argument3)
INTGET(argument1,argument2,argument3determinesanintervalfromthreedateordatetimevaluesthatyouprovide.Theargumentscanbevariablesordate/datetimeliterals,buttheymustbeofthesametype;youcannotmixdatesanddatetimesasarguments.The
functioncalculatesallintervalsbetweenthefirsttwoarguments,andthenbetweenthesecondandthirdarguments.Iftheintervalsarethesame,itwillreturnthatinterval.Iftheintervalsarenotthesame,thenthefunctionwilltesttheintervalbetweenthesecondandthird
argumentstoseewhetheritisamultipleoftheintervalbetweenthefirsttwoarguments.Ifthisistrue,thenthefunctionwillreturnthesmallerofthetwointervals.Ifneitherofthesecasesaretrue,thentheINTGET()functionwillreturnamissingvalue.
SampleFunctionCall
A INTGET('05SEP2013'd,20SEP2013'd,05OCT2013'd)
B INTGET('15JAN2014'd,15APR2014'd,15OCT2015'd)
C INTGET('15JAN2014'd,15APR2015'd,15OCT2015'd)
D INTGET('09JUL2015'd,09SEP2015'd,09MAR2016'd)
E INTGET('09JUL2015'd,29AUG2015'd,15SEP2015'd)
InrowA,theperiod
betweenthedatesis15days,whichcorrespondstotheSEMIMONTHinterval.RowBdemonstratesthatthedatesdonothavetohavethesameinterval.ThegapbetweenJanuaryandAprilisonequarter,butthegapbetweenAprilandOctoberofthefollowingyearis
fivequarters.Sincetheintervalforthesecondpairofargumentswouldbe'QTR5,'sinceitisamultipleoftheQTRinterval,thefunctionreturnstheunmultipliedinterval.WhathappenedinrowC?Simply,theintervalbetweenJanuary2014andApril2015isnowQTR5,buttheinterval
betweenAprilandOctober2015isQTR2.SinceQTR2isnotamultipleofQTR5,theresultismissing.RowDshowsthatiftheintervalbetweentwoargumentsisitselfamultipliedinterval(MONTH2versusMONTH6),thefunctionwillreturntheintervalwiththesmallest
multiplier,whilerowEshowstheingenuityofthefunction:TheDAY17intervalworksifitisshiftedby15days.
5.8.4INTSHIFT('interval')INTSHIFT('interval')takestheintervalthatyougiveandreturns
theshiftpointforthatinterval.intervalcanbeanystandardSASinterval(withmultipliersand/orashiftindexifdesired).Ifintervalisrepresentedbyacharacterstring,thenitmustbeenclosedinquotationmarks,butyoucanuseacharactervariablecontainingthenameof
anintervalinstead.Ifyoutrytousethisfunctionwithauser-definedintervalthatyouhavecreated,thefunctionwillreturnamissingvalue.
SampleFunctionCall
INTSHIFT('WEEK')
INTSHIFT('MONTH')
INTSHIFT('QTR3.4')
INTSHIFT('YEAR')
INTSHIFT('YEAR10.5')
INTSHIFT('YEAR100')
INTSHIFT('DTMONTH')
INTSHIFT('DTYEAR.7')
INTSHIFT('HOUR')
INTSHIFT('WORKINGDAYS')
5.8.5INTTEST('interval')INTTEST('interval')takestheintervalthatyougiveandreturnsa1ifitisavalidintervalname,or0ifitisnot.Youcanusethistodeterminewhetheryouhavecreatedavalidintervalwithmultipliersand/ora
shiftindex.intervalcanbeanystandardSASinterval(withmultipliersand/orashiftindexifdesired).Ifintervalisrepresentedbyacharacterstring,thenitmustbeenclosedinquotationmarks,butyoucanuseacharactervariablecontainingthenameofanintervalinstead.If
youtrytousethisfunctionwithauser-definedintervalthatyouhavecreated,thefunctionwillreturnamissingvalue.
SampleFunctionCall
INTTEST('WEEK')
INTTEST('QTR.1')
INTTEST('QTR3.13')
INTTEST('YEAR.7')
INTTEST('YEAR10.14')
INTTEST('DTMONTH')
INTTEST('HOUR2.3')
INTTEST('WORKINGDAYS')
5.9RetailCalendarIntervalsandSeasonalityThissectioncoversintervalsandfunctionsthataremostfrequentlyusedwithtimeseriesanalyses.Althoughthetopicoftimeseriesanalysisisbeyondthescopeof
thisbook,theseintervalsandfunctionsaredescribedherebecausetheintervalscanbeusedwithINTNX()andINTCK(),whilethefunctionsareapartofBaseSAS.However,theyarepresentedwithoutcontext.
5.9.1RetailCalendarIntervalsSAShasaddedintervalsthatarespecificallydesignedfortheretailindustry.TheseintervalsareISO8601compliant,andcanbeusedwithanyoftheintervalfunctions.They
facilitatecomparisonsacrossyears,becausetheweeksremainconsistentbetweenyears.Inordertofacilitatethis,someyearswillhaveleapweeks.YeardefinitionsarebasedontheISO8601definitionofaweek,whichisthefirstMondayprecedingJanuary4,whichin
somecasesmightplacethebeginningoftheweekinDecember.Theseintervalsenableyoutodefinethestructureofyour52-weekyear,expectingthatforthefirst13-weekperiodofyourinterval,therewillbe1monththathas5weeksinit.Thismeansthatyoucansetthemonth
patternto5-4-4,4-5-4,or4-4-5.Youcanworkwithyears,months,orquartersinthisfashion.ThefulllistofretailintervalsisgiveninTable5.7.
Table5.7:RetailCalendarIntervals
Interval Description
YEARV Specifies
ISO8601yearlyintervals.TheISO8601yearbeginsontheMondayonorimmediately
precedingJanuary4.NotethatitispossiblefortheISO8601yeartobegininDecemberofthe
precedingyear.Also,someISO8601yearscontainaleapweek.Thebeginningsubperiod
iswritteninISO8601weeks(WEEKV).
R445YR IsthesameasYEARVexceptthatintheretailindustrythe
beginningsubperiodis4-4-5months(R445MON).
R454YR IsthesameasYEARVexceptthatintheretail
industrythebeginningsubperiodis4-5-4months(R454MON).
R544YR IsthesameasYEARVexceptthat
intheretailindustrythebeginningsubperiodis5-4-4months(R544MON).
R445QTR Specifies
retail4-4-5quarterlyintervals(every13ISO8601weeks).Somefourthquarterscontaina
leapweek.Thebeginningsubperiodis4-4-5months(R445MON).
R454QTR Specifiesretail4-5-4
quarterlyintervals(every13ISO8601weeks).Somefourthquarterscontainaleapweek.
Thebeginningsubperiodis4-5-4months(R454MON).
R544QTR Specifiesretail5-4-4quarterly
intervals(every13ISO8601weeks).Somefourthquarterscontainaleapweek.The
beginningsubperiodis5-4-4months(R544MON).
R445MON Specifiesretail4-4-5monthly
intervals.The3rd,6th,9th,and12thmonthsarefiveISO8601weekslongwiththe
exceptionthatsome12thmonthscontainleapweeks.AllothermonthsarefourISO8601weeks
long.R445MONintervalsbeginwiththe1st,5th,9th,14th,18th,22nd,27th,31st,35th,40th,
44th,and48thweeksoftheISOyear.Thebeginningsubperiodis4-4-5months(R445MON).
R454MON Specifiesretail4-5-4monthlyintervals.The2nd,5th,8th,and11thmonthsarefiveISO
8601weekslongwiththeexceptionthatsome12thmonthscontainleapweeks.R454MON
intervalsbeginwiththe1st,5th,10th,14th,18th,23rd,27th,31st,36th,40th,44th,and49thweeks
oftheISOyear.Thebeginningsubperiodis4-5-4months(R454MON).
R544MON Specifies
retail5-4-4monthlyintervals.The1st,4th,7th,and10thmonthsarefiveISO8601weekslong.All
othermonthsarefourISO8601weekslongwiththeexceptionthatsome12thmonths
containleapweeks.R544MONintervalsbeginwiththe1st,6th,10th,14th,19th,23rd,27th,32nd,
36th,40th,45th,and49thweeksoftheISOyear.Thebeginningsubperiodis5-4-4months
(R544MON).
WEEKV SpecifiesISO8601weeklyintervalsofsevendays.EachweekbeginsonMonday.
Thebeginningsubperiodsiscalculatedindays(DAY).NotethatWEEKVdiffersfromWEEKin
thatWEEKV.1beginsonMonday,WEEKV.2beginsonTuesday,andsoon.
5.9.2SeasonalityFunctionsSeasonalityisusedintimeseriesanalysisandcanbeusedinSAS/ETS.Ithelpstoaccountfornormalseasonalvariationsinpatternsinsideananalysis.Whileitisnot
strictlyadateandtimematter,itdoesuseintervals.Therefore,theseasonalityfunctionsaredocumentedhere,butwithoutcontext.Formoreinformationaboutseasonalityanditsapplication,youcanrefertotheSAS/ETSdocumentation,andsupport.sas.comisa
greatplacetofindmorehelponthistopic.
INTCINDEX('interval',argument)INTCINDEX('interval',argumentreturnstheindexoftheseasonalcyclebasedonintervalforargument,whereargumentisaSASdate,time,ordatetimevalue.intervalcanbeanystandard
SASinterval(withmultipliersand/orashiftindexifdesired).
INTCYCLE('interval',seasonality)INTCYCLE('interval',seasonalityreturnstheintervaloftheseasonalcycle.intervalcanbeanystandardSASinterval(withmultipliersand/orashiftindexif
desired).seasonalityisanoptionalargumentthatenablesyoutodefineseasonalcycles,anditcanbeanumberoracycle(suchas'YEAR').Forexample,youcanusetheseasonalityargumenttospecifyyouryearashaving53weeksinsteadof52.
INTINDEX('interval',argument,seasonality)INTINDEX('interval',argument,seasonalityreturnstheseasonalindexwhengivenaninterval,aSASdate,time,ordatetimeoftheseasonalcycle.intervalcanbeanystandardSASinterval(withmultipliersand/orashiftindexifdesired.argumentisaSASdate,
time,ordatetimevalue.Notethattheintervalspecifiedmustbeappropriatefortheargument.seasonalityisanoptionalargumentthatenablesyoutodefineseasonalcycles,anditcanbeanumberoracycle(suchas'YEAR').TheINTINDEXfunctionreturnstheseasonalindex,while
theINTCINDEXfunctionreturnsthecycleindex.
INTSEAS('interval',seasonality)INTSEAS('interval',seasonalityreturnsthenumberofintervalsinaseasonalcycle.intervalcanbeanystandardSASinterval(withmultipliersand/ora
shiftindexifdesired).seasonalityisanoptionalargumentthatenablesyoutodefineseasonalcycles.Thisisagoodfunctiontobeawareofifyouarenotfamiliarwithconceptsofseasonality,becausethenumberofintervalsinaseasonalcyclemightnotbeintuitive.Forexample,whileyou
mightexpectthenumberofintervalsfortheQTRintervaltobe4(becausethereare4quartersinayear),thenumberofintervalsforaDAYintervalis7,forthenumberofdaysintheweek.Thiscanhelpyoucheckyourexpectations.
Chapter6DeeperintoDatesandTimeswithSAS
6.1Macro
VariablesandDates6.2GraphingDates6.3TheBasicsofPROCEXPAND6.4InternationalDate,Time,andDatetimeFormatsandInformats
6.5NLSDate,Time,andDatetimeConversionFunctions6.6DateFormatsandInformatsforOtherCalendars6.7OtherSoftware
andTheirDates(Excel,Oracle,DB2)6.8Conclusion
6.1MacroVariablesandDatesThereisahigh
potentialforconfusionwhenitcomestothesubjectofmacrovariablesanddates.AlthoughyouhaveaccesstodatesandtimesintheSASmacrolanguagewiththeautomaticmacrovariables&SYSDATE,&SYSDATE9,&SYSDAY,and&SYSTIME,thedisplay
ofthesevaluesisfixed,andthereforetheydonotgiveyouthepowerofSASformats,orofSASdateandtimefunctions.
6.1.1AutomaticMacroVariablesNoneoftheseautomaticmacrovariablescanbe
assignedvalueswith%LETorCALLSYMPUT(),orbyanyothermeans.Theyareread-onlyandworkbyreadingtheoperatingsystemclockwhenaSASsessionisstarted.ThismeansthattheydonotchangewithinagivenSASsession.
&SYSDATE
&SYSDATEcannotbemodifiedanddisplaysthesystemdateasaSASdatevalueformattedwiththeDATE7.format.IfthedateaccordingtotheoperatingsystemwhentheSASsessionstartsisJuly17,2014,then&SYSDATEwouldbeequalto"17JUL14."
&SYSDATE9&SYSDATE9isidenticalto&SYSDATE,exceptthatitformatsthesystemdatewiththeDATE9.formatandisthereforeY2K-compliant.IftheoperatingsystemdateisNovember22,2015,then&SYSDATE9wouldbeequalto
"22NOV2015."
&SYSDAY&SYSDAYdisplaysthenameofthedaythattheSASsessionbegan(accordingtotheoperatingsystem).IfyoustartedaSASjoborsessiononMonday,April14,2014,&SYSDAYwouldbe
equalto"Monday."
&SYSTIME&SYSTIMEdisplaysthesystemtime(accordingtotheoperatingsystem)inTIME5.format.Ifthesystemtimeis3:36p.m.whenyoustartSAS,then&SYSTIMEwouldbeequalto"15:36."
6.1.2PuttingDatesintoTitlesOneoftheprimeusesofdatesinmacrovariablesisforcustomtitlesandfootnotes.Touseamacrovariableinatitle,youjustneedtoenclosetheTITLEorFOOTNOTEstatementthatcontainsthemacrovariablewithdouble
quotationmarkslikethis:
TITLE"Today'sDateis&SYSDATE9";
Toseethisincontext,lookatthefollowingprogram:
Example6.1:UsingAutomaticMacroVariablesinaTitle
TITLE"Thisishowtoputamacrovariableinatitle:Today'sDateis&SYSDATE9";ODSRTFFILE="examples\title.rtf";PROCPRINTDATA=sashelp.company(OBS=5);IDjob1;VARdepthead;RUN;ODSRTFCLOSE;
Hereistheresultingoutput:
Whiletheautomaticmacrovariables&SYSDATE,&SYSDATE9,&SYSDAY,and&SYSTIMEmightgiveyoutheinformationthatyouneed,theirformatsarefixedand
cannotbechanged.Giventhemultiplewaysthatdates,times,anddatetimescanbedisplayed,itwouldbegoodifyoucouldusetheformatsandfunctionstogetthedisplayofdatesandtimesthatyouwantinyourtitles.
6.1.3Using%SYSFUNC()toCreateDates,Times,andDatetimesinMacroVariablesManyofthedateandtimefunctions,aswellasformats,areavailableintheSAS
macrolanguagethroughthe%QSYSFUNC()and%SYSFUNC()macrofunctions.Whenyouareusingoneofthesemacrofunctionswithdatesandtimes,youcanusetwoarguments:Thefirstisthedate,time,ordatetimefunctionthatyouwishtouse.Thesecond
argumentisoptional,butyoucanspecifytheformatthatshouldbeappliedtotheresult.
Example6.2:DateFunctionswith%SYSFUNC()Thisexampleputstheformattedvalueoftoday'sdateintothemacrovariable&DATE
anddemonstratesthedifferencebetweenunformattedandformatteddatesinmacrovariables.Thedatevaluein&RAWDATEisstoredinmacrospaceasatextstringandwillneedtobeconvertedifyouwanttouseitforanycalculations.&DATEisalsoatext
stringinmacrospace,butitshowsthattheWORDDATE.formathasbeenappliedtothevalue.
%LETrawdate=%SYSFUNC(DATE());%LETdate=%SYSFUNC(DATE(),WORDDATE32.);
TITLE"Today'sSASDateValueis&rawdate";TITLE2"Formatteddate:&date";
ODSRTFFILE="c:\book\2ndEd\examples\title2.rtf";PROCPRINTDATA=sashelp.class(OBS=5);IDname;VARage;RUN;ODSRTFCLOSE;
Nowyoucanusetheresultinatitleorfootnote.
YoucanalsousethisasapartofanoutputfilenameorExcelworksheetname.
Example6.3:PuttingaDateValueintoanOutputFileName
%LET
filedate=%SYSFUNC(DATE(),yymmddd10.);
ODSRTFFILE="Car_Report_&filedate..rtf";PROCPRINTDATA=sashelp.carsNOOBSLABEL;RUN;ODSRTFCLOSE;
Whenyoutrythisathome,youwillseethatyouhavegeneratedanRTFfilenamed"Car_report_yyyy-mm-
dd.rtf."
Example6.4:NamingWorksheetswiththeDateInthisexample,wecreateacustomformattodisplaydatesasthefullmonthnameand4-digityearandapplyittoacopyofthedatevariableinthedataset.
ThenweusethatvariableastheBYvariableinthePRINTprocedure.Notonlydoesthisputthenameoneachworksheet,butitalsofiltersthedatesintotheircorrectworksheetwithoutmuchextracodingrequired.Therearemanyotherwaysthatyoucanaccomplish
thistask,butthisisstraightforwardandsimple.Ifyouhaveagreatdealofdata,youmightwanttoinvestigateamoreefficientmethodthancreatinganadditionalvariableinadataset.Lines1–5createtheformatusingthePICTUREstatementinPROCFORMATand
datedirectivesdiscussedinsection2.6,andlines6–13createourduplicatevariablewithourcustomformatandalsosubsetthedataset.NotethedateliteralsusedasvaluesintheBETWEENoperatorinline10.WeremovethedefaultBYlinefromtheoutputinline14.
TheSHEET_NAMEoptionallowsustousetheBYvaluetoken(#BYVAL1)asthenameoftheworksheet.
1PROCFORMAT;2PICTUREnamefmt3LOW-HIGH='%B%Y'(DATATYPE=date)4;5RUN;
6PROCSQL;7CREATETABLEsubset
AS8SELECTdateassheet_dateFORMAT=namefmt15.,*9FROMsashelp.citiday10WHEREdateBETWEEN'01JAN1988'dAND'31AUG1988'd11ORDERBYDATE12;;;;13QUIT;
14OPTIONSNOBYLINE;15ODSTAGSETS.EXCELXPFILE="ex6.1.4.xml"OPTIONS
(SHEET_NAME="#BYVAL1");16PROCPRINTDATA=subsetLABELNOOBS;17BYsheet_date;18RUN;19ODSTAGSETS.EXCELXPCLOSE;
Thisistheresultingworkbook:
6.1.4UsingDatesinMacrosWhileSAScanhandledates,times,anddatetimevaluesasnumbers,gettingthemacroprocessortoacceptthemasnumbersmightinvolveanextrasteportwo.Let'slookatthefollowingcode:
1%MACROdate_loop;2%DOI='05JUN2014'd%TO'12JUN2014'd;3TITLE"HappyKidsIceCreamCo.Salesfor&i";4PROCPRINTDATA=sample.dailysales;5IDdistrict;6VARsales;7WHERE
dateEQ&i;8RUN;9%END;10%MEND;
Wehaveusedtwodateliteralstoprovidetheperiodoverwhichwewantthereportrunanduseditinthetitleaswell.Whathappenswhenthisissubmitted?
ERROR:Acharacter
operandwasfoundinthe%EVALfunctionor%IFconditionwhereanumericoperandisrequired.Theconditionwas:'05JUN2014'd
ERROR:The%FROMvalueofthe%DOIloopisinvalid.
ERROR:Acharacteroperandwasfoundinthe%EVALfunctionor%IFconditionwhereanumericoperandisrequired.Theconditionwas:'12JUN2014'd
ERROR:The%TOvalueofthe%DOIloopisinvalid.
ERROR:ThemacroDATE_LOOPwillstopexecuting.
Tothemacroprocessor,thedateliteralsareonlytext.TheydonotfunctionastheydointherestofSAS.Howcanwegetaroundthis?Byusing
the%SYSEVALF()macrofunctiontoforcetheinterpretationofthedateliterals.Let'sreplaceline2withthefollowingline:
%DOi=%SYSEVALF('05JUN2014'd)%TO%SYSEVALF('12JUN2014'd);
Nowtheloopwillexecuteproperly.
However,thedateinthetitledoesnotlookgoodatall.
Thedateinthetitledoesn'tlooklikeadate.Weneedtomakeonemoremodificationtotheprogramtogetour
titletolookright.The%LETstatementaddedinline3createsaformattedvalueofthedateinthemacroloopforuse.ThePUTN()functionisusedhereinsteadofthePUT()functionbecauseyoucan'tusethePUT()functionwith%SYSFUNC()orQSYSFUNC().
1%MACROdate_loop;2%DOI=%SYSEVALF('05JUN2014'd)%TO%SYSEVALF('12JUN2014'd);3%LETTITLEDATE=%SYSFUNC(PUTN(&i,WORDDATE.));4TITLE"HappyKidsIceCreamCo.Salesfor&titledate";5PROCPRINTDATA=sample.dailysales;6IDdistrict;
7VARsales;8WHEREdateEQ&i;9RUN;10%END;11%MEND;
Andnowwegetthedesiredresult.
Ourfinalexampleofusingdatesinmacrosdemonstrateshowtogetadatefromadatasetintoamacro.Forthisexample,wewanttoputthelatestdatefromagivencolumnintoamacrovariablesothatitcanbeusedinatitle.Let'slookatsometimingvariablesfromthissampledata
set.Wewanttoputthelatestdateandtime(whichisinrecord4)fromthevariableMODDATE(nicelyformatted,ofcourse)onthetitleofeachpage.
Method1:UsingCALLSYMPUTTheCALLSYMPUT()andSYMGET()functionsarealsousedtocommunicate
betweentheDATAstepandthemacroworld.CALLSYMPUT()takesavalueandstoresitinmacrospacefromwithinaDATAstep,whileSYMGET()takesamacrovariableandenablesyoutouseitinaDATAstep.Inthissituation,IrecommendthatyouuseCALLSYMPUTX()insteadof
CALLSYMPUT(),becauseCALLSYMPUTX()suppressesanytrailingblanksinthemacrovariablecreated,andthepresenceoftrailingblanksmightaffectthejustificationofyourtitleorfootnote.Thedifferencebetweenrun-timeandcompiletimeisveryimportant.You
cannotusea%LETstatementtostoremacrovaluesthataredefinedduringexecutionofaDATAstep.Youalsocannotuseamacrovariablereference(withanampersand[&])inthesameDATAstepwherethemacrovariableiscreatedwithCALLSYMPUT().Thenext
exampleuseswhatwasdiscussedinsection6.1.2toshowhowyoucanobtainadatevaluefromaSASdatasetandthenputitinamacrovariabletouseinatitle.SincetheDATETIME.formatisn'tformalenoughforthisreport,we'regoingtocreateaRPTDATE.customformat.
PROCFORMAT;PICTURErptdate(DEFAULT=32).-.Z='Missing'LOW-HIGH='%B%d,%Yat%I:%0M%p'(DATATYPE=DATETIME);RUN;
/*Getthemaximumdateinthevariable*/PROCMEANSDATA=sample.pmdataMAXNOPRINT;VARmoddate;OUTPUTOUT=tmpMAX=max;RUN;
/*TransferittoamacrovariableusingCALLSYMPUTX()*/DATA_NULL_;SETtmp;CALLSYMPUTX('lastmod',STRIP(PUT(max,rptdate.)));RUN;
%PUTlastmod=&lastmod;
PartialLog42%PUTlastmod=&lastmod;lastmod=February7,2014at4:18PM
Method2:UsingPROCSQLForsomethingassimpleasthehighest(orlowest)valueinadateordatetimevariable,youdon'thavetouseaSASprocedureandaDATAstep.PROCSQLcantaketheplaceofboth.
PROCSQLNOPRINT;
SELECTDISTINCTSTRIP(PUT(MAX(moddate),rptdate.))LENGTH=32INTO:lastmodFROMsample.pmdata;QUIT;
%PUTlastmod=&lastmod;
TheLog1PROCSQLNOPRINT;2SELECTDISTINCTSTRIP(PUT(MAX(moddate),rptdate.))LENGTH=32INTO3!:lastmod4FROMsample.pmdata;5QUIT;
NOTE:PROCEDURESQLused(Totalprocesstime):realtime0.08secondscputime0.00seconds
67%PUTlastmod=&lastmod;lastmod=February7,2014at4:18PM
Whichevermethodyouchoose,themacrovariable&LASTMOD,containingthevalue"February7,2014at4:18PM",isreadytouseinyourreporttitle.
6.2GraphingDatesWhenyouusedates,times,ordatetime
valuesinyourSASgraphics,youhavetorememberthattheyarenumbers.Thishasalargeimpactontheaxesandlabelingofyourgraphics.Attemptingtographaresultoveraperiodoftimewithoutusingformatsorintervalswillusuallyresultinagraphthatisnotclear
orwell-defined.ThegoodnewsisthatyoucanuseallthefeaturesassociatedwithSASdatestoimproveyourgraphics,suchasformatsandintervals.Thefollowingseriesofexampleswillillustrate.Example6.5willdemonstratethegraphingofdateswithSAS/GRAPH,while
Example6.6willuseODSgraphicstoproduceaseriesplot.
Johnny'sSavingsAccountWhenJohnnyturned10yearsoldonSeptember1,1975,hetookallthemoneythathehadinhispiggybankanddepositedit
intoabankaccountthatpaid3.5%interestannually,compoundeddaily.Hepromisedhimselfthathewouldaddtwodollarsattheendofeachweekandthathewouldtakethemoneyoutwhenhereachedtheripeoldageof50.Whenhewas10,Johnnythoughthemighthave$4,000by
thetimehereachedage50.Hekeptthatpromise,solet'slookatJohnny'searningsfromthetimehewas10untilhewas50usingthefollowingprogram:
Example6.5:SAS/GRAPH
TITLE"Johnny's50thBirthdayFund";PROCGPLOT
DATA=book.graph1;PLOTfund*date/VREF=5000LV=1CV=blue;RUN;
Hereistheresultinggraph:
Unfortunately,theresultofthissimpleexampleisn'thelpful.WecanseethatJohnnystartedaround6000,andheturned50somewherearound20000.Whatdoesthat
mean?Thisshouldbeeasyenoughtofix.Don'twejustneedtoaddaFORMATstatement?
TITLE"Johnny's50thBirthdayFund";PROCGPLOTDATA=book.graph1;PLOTfund*date/VREF=5000LV=1CV=blue;FORMATdatemmddyy10.;/*AddFORMATstatement*/RUN;
HereisthenewGPLOTgraphwiththeFORMATstatement:
WhathashappenedhereisthatSASchosetheboundariesandfiguredoutmajorandminortickmarks.Inthisexample,ithasselectedmajorintervalsatdecadeboundaries,
andminoronesatyearboundaries.That'snotabadchoiceforthisexample,butSAS/GRAPHdoesn'talwaysmakesuchagoodchoicewhenselectingtheboundariesofanaxis.Can'tyoudefinethehorizontalaxisyourself?Ofcourse,youcan!Johnnywas
borninSeptember,soitwouldmakesensetocharthisprogressathisbirthdaysandrestrictthespanofthehorizontalaxistotheperiodduringwhichhe'scontributing.
TITLE"Johnny's50thBirthdayFund";PROCGPLOTDATA=book.graph1;PLOTfund*date/
VREF=5000LV=1CV=blueHAXIS='01SEP1975'dTO'01SEP2015'dbyYEAR;FORMATdatemmddyy10.;RUN;
HereisthenewgraphthatwegetfromusingtheHAXISoptioninthePLOTstatementtospecifytheaxisrange:
Whathappened?Wedefinedthehorizontalaxisashavingtickmarkseveryyear,soSASaccommodatedourrequest.Sincetherewasnotenoughroomtodisplaythevalues
horizontally,SASautomaticallyrotatedthevalues90degrees.Unfortunately,thatleftlessspaceforthegraphitself.Weneedbetterspacingonourhorizontalaxis.
Sincedecadesseemedtoworkwell,let'susethoseasourintervals,butwewanttostarton
Johnny's10thbirthday,anddefinethemajorhorizontalaxispointsatSeptember1,1975,September1,1985,September1,1995,September1,2005,andSeptember1,2015.Anintervalmultiplierof10willcreatethedecadeinterval,andashiftoperatorof69(60[monthsin5years]
plus9[monthsfromJanuarytoSeptember])willmovethestartingdateofthe10-yearintervaltoSeptember1975sothatitmatchesthestartingpointofthehorizontalaxis.Notethattheonlychangefromthepreviousversionisintheintervaldefinition.
TITLE"Johnny's50thBirthdayFund";PROCGPLOTDATA=book.graph1;PLOTfund*date/VREF=5000LV=1CV=blueHAXIS='01SEP1975'dTO'01SEP2015'dbyYEAR10.69;FORMATdatemmddyy10.;RUN;
Hereisthefinalproduct:
Nowthat'swhatwewanted.Thisdemonstratesthatyouhavealloftheintervaltypes,aswellastheirmultipliersandshiftoperators,availablewhenyouaredefining
axesthatinvolvedate,time,anddatetimevaluesinSAS/GRAPH.Itmakesdefiningtheexactscopeofthegraphmucheasier,nottomentioncomprehendingwhatyou'vegraphed.
Example6.6:ODSGraphics
WewillcontinuetouseJohnny's50thbirthdayfundfortheSGPLOTseriesofexamples.TheSGPLOTprocedurehasawayofassigningatimescaletoanaxisbysettingtheaxisTYPEoptionintheXAXISstatementequaltoTIME,andtheSERIESstyleofplotisperfectforgraphsof
longitudinaldata.
Here'sthebasicSGPLOTfromtheabovecode.
AswiththeGPLOTexample,an
unformatteddatevariableisn'tveryuseful.However,eventhoughwegotourgraph,SGPLOTdidnotrunsmoothly.Inordertoproducethisgraph,theproceduremadesomeadjustmentsinordertoproducethegraph.Let'slookatthelogfromtheprogramthatproducedthe
abovegraph.
3TITLE"Johnny's50thBirthdayFund";4PROCSGPLOTDATA=book.graph1;5XAXISTYPE=time;6SERIESX=dateY=fund;7RUN;
NOTE:PROCEDURESGPLOTused(Totalprocesstime):realtime1.20
secondscputime0.09seconds
NOTE:Timeaxiscanonlysupportdatetimevalues.TheaxistypewillbechangedtoLINEAR.❶NOTE:Therewere2435observationsreadfromthedatasetBOOK.GRAPH1.
Note❶istellingusthatyoucan'tusethe
TYPEvalueofTIME.Butaren'twegraphingdates?TheSGPLOTprocedurereliesonformatstodeterminethatthedatabeinggraphedaredatesortimes.Withoutit,SGPLOTerrsonthesideofcautionandjustassumesthatyouaregraphinglineardata.Thiswillcreateaplot
fordatagraphedalongasequence(suchasdates),soitlooksright,butitisnotclearthatyouaregraphingdates.
Let'saddthemissingformattoourSGPLOT:
TITLE"Johnny's50thBirthdayFund";PROCSGPLOTDATA=book.graph1;XAXISTYPE=time;
SERIESX=dateY=fund;FORMATdatemonyy7.;RUN;
Thatlooksbetter,eventhoughSASdidnotusetheMONYY7.formatthatyourequestedand
substitutedoneofitsownasseeninnote❶below.
51TITLE"Johnny's50thBirthdayFund";52PROCSGPLOTDATA=book.graph1;53XAXISTYPE=time;54SERIESX=dateY=fund;55FORMATdatemonyy7.;56RUN;
NOTE:PROCEDURESGPLOT
used(Totalprocesstime):realtime0.90secondscputime0.20seconds
❶NOTE:ThecolumnformatMONYY7isreplacedbyanauto-generatedformatontheaxis.
Thisisreallythesameproblemaswith
SAS/GRAPHwhenyouhaven'tdefinedthetickmarksontheXaxisproperly.TheVALUES=optionintheXAXISstatementallowsustodefineourscaleinthesamewaythattheHAXIS=optioninthePLOTstatementdoesinSAS/GRAPH.Fora50-yearperiod,let'stry5-
yearintervals,startingwhenJohnnymadehispromiseonSeptember1,1975.
TITLE"Johnny's50thBirthdayFund";PROCSGPLOTDATA=book.graph1;XAXISTYPE=timeVALUES=('01sep1975'dTO'01sep2015'dBYYEAR5);SERIESX=dateY=fund;FORMATdatemonyy7.;RUN;
Nowthedisplaylooksmuchnicer,andwehaveourMONYY7.formatdisplayed.
6.3TheBasicsof
PROCEXPANDTheEXPANDprocedureisapartofSAS/ETS,whichisusedtopreparetimeseriesdataforfurtheranalysis.ItcreatesaSASdatasetanddoesnotproduceprintedoutput.
6.3.1
CapabilitiesofPROCEXPANDPROCEXPANDwillchangethesamplingfrequencyofthedatathatyouhaveandconvertittoadifferentone.Itcaninterpolatevaluesintimeseriesdata,forexample,whenyouhavequarterlydatathatyou
needtoreportoranalyzeonamonthlybasis.Itcanperformthereverseoperation,thatis,toaggregate(collapse)datafromahighersamplingfrequencytoalowerone,suchastakingmonthlydataandturningitintoquarterlydata.PROCEXPANDcaninterpolatemissing
valuesevenifyouaren'tchangingthesamplingfrequency.ItalsoprovidesforextensivedatatransformationsandperformsallofthesefunctionswithoutalotofDATAstepprogramming.TheSAS/ETSdocumentationprovidesdetailonthe
procedure,itsstatements,andtheoptionsforthosestatements.ThereareotherproceduresavailableinSAS/ETS,suchasTIMESERIESandTIMEDATA,thatcanbeusedtomanipulatetimeseriesdata,andifyouneedtoworkwithtimeseriesdataonaregularbasis,
youshouldinvestigatetheSAS/ETSproductanditsdocumentationmorecarefully.
PROCEXPANDusesSASintervaldefinitions.Thisincludesintervalmultipliersandtheshiftindex.Foradetailedexplanationofintervals,interval
multipliers,andtheintervalshiftindex,seeSections5.5and5.6ofthisbook.Whenyouusetheseintervaldefinitions(plusanyshiftindexand/ormultipliers),PROCEXPANDwillautomaticallyadjustforanycalendareffects(leapyears,varyingnumberofdaysina
month).Aswithanythingthatusestheseintervaldefinitions,allmeasurementsandcalculationsareconsideredtobeatthebeginningoftheinterval(s)specified.ItispossibletochangethatdefinitionwithoptionsinoneofthePROCEXPAND
statements,andthosearediscussedinSection6.3.5.
PROCEXPANDSampleDataThefollowingdatasetwillbeusedfortheexamplesinthissection.Thisismonthlytotallightrailridershipdataobtainedfromthe
AmericanPublicTransportationAssociationfortheyears2003and2004andisusedwiththeirpermission.ThevaluesforOctoberandNovember2003wereremovedfromthedatatodemonstratesomeofthecapabilitiesofPROCEXPAND.
DateRiders
(thousands)
JAN2003 2679.9
FEB2003 2421.9
MAR2003 2704.6
APR2003 2778.3
MAY2003 2718.6
JUN2003 2618.2
JUL2003 2999.0
AUG2003 3504.7
SEP2003 3329.4
OCT2003 .
NOV2003 .
DEC2003 2888.6
JAN2004 3132.9
FEB2004 2814.3
MAR2004 3067.3
APR2004 2928.8
MAY2004 2958.3
JUN2004 2966.3
JUL2004 3000.8
AUG2004 3071.2
SEP2004 2958.9
OCT2004 2992.8
NOV2004 3017.5
DEC2004 3038.4
6.3.2UsingPROCEXPANDtoConverttoaHigherFrequency
YoucanusePROCEXPANDtoconvertdatafromalowersamplingfrequencytoahighersamplingfrequency(forexample,convertingmonthlydatatodailyorweeklydata).Itdoessobyinterpolation,andthesyntaxtoconverttoahighersamplingfrequencyisasfollows:
Example6.7:ConvertingtoaHigherSamplingFrequency
1PROCEXPANDDATA=book.monthOUT=seven_daysFROM=MONTHTO=WEEK;2IDdate;3CONVERTriders;4RUN;
ThePROCEXPAND
statementinline1specifiestheoutputdataset(SEVEN_DAYS)andexplainshowthedatainBOOK.MONTHshouldbeconverted,fromMONTHintervalstoWEEKintervals.TheIDstatementinline2indicatesthevariablethatidentifiesthetimeofeachrecord.SincetheWEEKinterval
beginsonSunday,thedateswillbealignedonSundays.Ifyouwantthedatestoaligntoadifferentdayoftheweek,useashiftindicator.TheWEEK.2intervalwillalignthedatestoMondays;theWEEK.3intervalalignstoTuesdays,andsoon.
Youwillusuallyusean
IDstatementwithPROCEXPAND.Otherwise,SASwillcreateanIDvariablefortheinputrecordsandusethestartingpointofJanuary1,1960,whichmightnotbewhatyouwant.TheCONVERTstatementidentifiesthevariable(s)toconvert.Youcanalsorename
thevariable(s)beingconvertedintheoutputdatasetlikethis:CONVERTinput-var=output-var;HerearethefirsteightobservationsfromthedatasetSEVEN_DAYSproducedbytheabovecode:
Riders
date (thousands)
29DEC2002 2770.23
05JAN2003 2573.57
12JAN2003 2449.76
19JAN2003 2393.52
26JAN2003 2391.24
02FEB2003 2429.29
09FEB2003 2494.03
16FEB2003 2571.86
Whenyouinterpolatetimeseriesdatatoahigherfrequency,considerthattheinterpolatedvaluesdonotaddanynewinformationtothedatabecausetheyhavebeen
derivedmathematically,notobserved.Therefore,anystatisticalanalysesperformedwiththeseinterpolateddatashouldbeviewedwithcaution.
6.3.3UsingPROCEXPANDtoConverttoa
LowerFrequencyYoucanconvertdatatoalowerfrequencywithPROCEXPANDintwoways:First,youcanusethesamesyntaxaswithconvertingtoahighersamplingfrequency,exceptthattheTO=intervalwouldbeofalowersampling
frequency.Whenyouconvertyourdatathisway,PROCEXPANDperformsinterpolationformissingvaluesusingacurve-fittingmethod,whichallowsforconversionbetweenintervalsthataren'tnested.Anestedintervalisonethatfitswhollyinsideanotherinterval(forexample,
daysnestwithinweeks,becausethereareexactlysevendaysinaweek,butweeksdonotnestwithinmonths,becausemostmonthshavepartialweeks).Thefollowingprogramwillinterpolateanymissingvaluesinourdatabyfittingacubicsplinefunctionthroughtheexistingdatabefore
convertingthedatafromamonthfrequencytoaquarterfrequency.
Example6.8:ConvertingtoaLowerFrequency
PROCEXPANDDATA=book.monthOUT=quarterlyFROM=MONTHTO=QTR;IDdate;CONVERTriders;
RUN;
Obs date
Riders(thousands)After
Interpolation
1 01JAN2003 2679.90
2 01APR2003 2778.30
3 01JUL2003 2999.00
4 01OCT2003 2993.28
5 01JAN2004 3132.90
6 01APR2004 2928.80
7 01JUL2004 3000.80
8 01OCT2004 2992.80
TheresultingdatasetQUARTERLY(above)haseightobservations,fourforeachyear,
synchronizedontheQTRintervalboundaries.Asyoucansee,thedatathatweremissingfromouroriginaldataset(forOctober2003)areinterpolated.
Thesecondmethodenablesyoutoperformsimpleaggregation(addition)without
interpolationofmissingvalues.TheAGGREGATEmethodalwaysproducesanexactresultwithoutinterpolation,anditrequiresthattheintervalsbenested.Thisprogramshowstheresultofasimpleaggregationonoursampledata:
Example6.9:PerformingAggregationwithoutInterpolation
PROCEXPANDDATA=book.monthOUT=annualFROM=MONTHTO=YEAR;IDdate;CONVERTriders/METHOD=AGGREGATE;RUN;
dateRiders(thousands)
2003 . Thereare2missingobservationsforthisyear,whichyieldsamissing
result.
2004 35947.5 Totalacrossall12months.
Example6.10:TheImportanceoftheIDStatementinPROCEXPANDThefollowingPROC
EXPANDstephasnoIDstatement.Let'srunitsothatwecanseetheassumptionsthatSASmakesinitsabsence.ThisillustrateswhytheIDstatementisalmostalwaysusedwiththisprocedure:
PROCEXPANDDATA=book.monthOUT=ANNUALFROM=MONTHTO=YEAR;
CONVERTriders;RUN;
dateRiders(thousands)
01JAN1960 2679.9
01JAN1961 3132.9
Howdidwewindupwithdatafor1960and
1961whenweuseddatafrom2003and2004?IfthereisnoIDvariabletoindicatethedates,SASwillcreateIDvaluestolabeltheinputrecords,anditwillstartfromitszeropoint,January1,1960.
6.3.4UsingPROCEXPAND
toInterpolateMissingValuesPROCEXPANDcanalsobeusedtointerpolatemissingvalueswithoutconvertingfrequencies.Therearetwowaystodothis;usetheonethatfitsyoursituation.Ifyouareinterpolatingmissingvaluesat
specificpointsintime,leaveofftheFROM=andTO=options,butmakesurethatyouuseanIDstatementtoindicatethevariablethatcontainsthetimepointsoftheobservedvalues.Thetimepointsdonothavetobeevenlyspaced,nordoyouneedarecordforeachtimepointwithin
theinterval.PROCEXPANDwillreadthevaluessuppliedintheIDvariableandwillfitasplinefunctionthroughtheavailabledatapoints.Itthenfillsinthemissingvaluesbasedonthatfittedspline.RememberthatthedataforthemonthsofOctoberandNovemberaremissing
inoursampletable.Thefollowingprogramdemonstrates:
Example6.11:InterpolatingMissingValues
PROCEXPANDDATA=book.monthOUT=nomiss;IDdate;CONVERTriders;RUN;
TheboldedanditalicizedvaluesinthefollowingtablearetheresultoftheinterpolationperformedbyPROCEXPAND.
dateRiders(thousands)
01JAN2003 2679.90
01FEB2003 2421.90
01MAR2003 2704.60
01APR2003 2778.30
01MAY2003 2718.60
01JUN2003 2618.20
01JUL2003 2999.00
01AUG2003 3504.70
01SEP2003 3329.40
01OCT2003 2993.28
01NOV2003 2788.68
01DEC2003 2888.60
Thesecondmethodinterpolatesmissingvaluesinatimeserieswithoutconvertingthe
observationfrequency.Usethiswhenyouwanttofillinthemissingvaluesandmaintainthesameobservationfrequency.ItrequirestheFROM=option,butleaveofftheTO=option,asshownhere:
PROCEXPANDDATA=book.monthOUT=nomiss2FROM=MONTH;
IDdate;CONVERTriders;RUN;
Bydefault,theinterpolationisperformedbyfittingthepointstoacubicsplinecurve.YoucanrequestothermethodsofinterpolationwiththeMETHOD=optionintheCONVERT
statement,andthesearedetailedintheSAS/ETSdocumentation.PROCEXPANDwillignoreobservationsthathavemissingvaluesfortheIDvariable,eveniftherearedatapointsfortheCONVERTvariable(s).Table6.1isasummaryofwhatPROCEXPANDdoes
whentherearemissingvaluesfortheIDvariableand/orCONVERTdatapoints.
Table6.1:HowPROCEXPANDHandlesInterpolationofMissingValuesinInputData
IDVariable Data
PROCEXPANDWill
Missing Missing Interpolate
NotMissing
Missing Interpolate
Missing NotMissing
Ignore
6.3.5TheOBSERVED=
OptionfortheCONVERTStatementinPROCEXPANDAswiththeotherusesofSASdate,time,anddatetimeintervals,thedefaultforPROCEXPANDistoconsiderthevaluesasbeingfromthebeginningof
theintervalsprovidedintheFROM=andTO=options.Thisisnotalwaysthecasewithreal-worlddata,anditcancauseverydifferentresults,especiallyifthevaluesarenotmeasuredatthebeginningofthegiveninterval(s),ortheydonotrepresentasingleobservedvaluefora
specificpointintime.YoucancontrolhowtheSASintervalsareusedwiththeOBSERVEDoptionintheCONVERTstatement.TherearesixpossiblevaluesfortheOBSERVED=option,asshowninTable6.2:
Table6.2:Valuesforthe
OBSERVED=Option
Values Description
BEGINNING Beginningoftheperiod
MIDDLE Middleoftheperiod
END Endofthe
period
TOTAL Totalsfortheperiod
AVERAGE Averagesacrosstheperiod
DERIVATIVE Onlyvalidasthe'to'
valuewhenthecubicsplinefunctionistheconversionmethod
ThesyntaxoftheOBSERVED=optionis:
1.OBSERVED=valueOR
2.OBSERVED=(from-value,to-value)
valueisoneofthekeywordsintable6.2,fromindicatesthecharacteristicsofthedatafromwhichyou
areconverting,andtorepresentsthecharacteristicsofthedataresultingfromtheconversion.Usingform1isthesameasspecifyingthesamevalueforbothfromandto;thatis,OBSERVED=AVERAGEisthesameasOBSERVED=(AVERAGE,AVERAGE).
Again,ifyoudonotsupplyanOBSERVEDoptionfortheconversion,itisthesameasusingOBSERVED=(BEGINNING,BEGINNING).
Examples6.12and6.13demonstratehowdifferentcombinationsoftheOBSERVED=optionaffectour
sampledatawhenweincreaseanddecreasethesamplingfrequency.Theprogrambelowshowsthecodetoincreasethesamplingfrequency.ItalsoshowshowtorenametheoutputvariablesintheCONVERTstatementbyplacinganequalsign(=)afterthedataset
variableandprovidingthenewvariablenameafterward.
Example6.12:EffectofDifferentValuesforOBSERVED=OptiononIncreasedFrequency
/*TheeffectofthedifferentvaluesfortheOBSERVEDoptionoftheCONVERTstatement
inPROCEXPANDonincreasedsamplefrequency*/
PROCEXPANDDATA=book.monthOUT=seven1FROM=MONTHTO=WEEK;IDdate;CONVERTriders=beginning/OBSERVED=BEGINNING/*Default*/;RUN;PROCEXPANDDATA=book.monthOUT=seven2FROM=MONTHTO=WEEK;
IDdate;CONVERTriders=middle/OBSERVED=MIDDLE;RUN;PROCEXPANDDATA=book.monthOUT=seven3FROM=MONTHTO=WEEK;IDdate;CONVERTriders=end/OBSERVED=END;RUN;PROCEXPANDDATA=book.monthOUT=seven4FROM=MONTHTO=WEEK;IDdate;
CONVERTriders=total/OBSERVED=TOTAL;RUN;PROCEXPANDDATA=book.monthOUT=seven5FROM=MONTHTO=WEEK;IDdate;CONVERTriders=average/OBSERVED=AVERAGE;RUN;PROCEXPANDDATA=book.monthOUT=seven6FROM=MONTHTO=WEEK;IDdate;CONVERTriders=begend/
OBSERVED=(BEGINNING,END);RUN;PROCEXPANDDATA=book.monthOUT=seven7FROM=MONTHTO=WEEK;IDdate;CONVERTriders=avetot/OBSERVED=(AVERAGE,TOTAL);RUN;
DATAcompare_lo;MERGEseven1seven2seven3seven4seven5seven6seven7;BYdate;LABEL
beginning="BEGINNING"middle="MIDDLE"end="END"average="AVERAGE"total="TOTAL"begend="BEGINNING,END"avetot="AVERAGE,TOTAL";;;FORMATbeginning--avetot7.2;RUN;
PROCREPORTDATA=compare_loNOWDSPLIT='\';COLUMNSdate('OBSERVED=\OptionValue'beginningmiddleend
averagetotal);FORMATdateDATE9.;DEFINEdate/display;WHEREDATELT'01MAR2003'd;RUN;
PROCREPORTDATA=compare_loNOWDSPLIT='\';COLUMNSdate('OBSERVED=\OptionValue'begendavetot);FORMATdateDATE9.;DEFINEdate/display;WHEREDATELT'01MAR2003'd;
RUN;
OBSERVED=OptionIstheSameforFROM=andTO=:
date BEGINNING
29DEC2002 2770.19
05JAN2003 2573.61
12JAN2003 2449.83
19JAN2003 2393.59
26JAN2003 2391.28
02FEB2003 2429.28
09FEB2003 2493.99
16FEB2003 2571.80
23FEB2003 2649.08
Asyoucansee,theOBSERVED=optionhasaverylargeeffectontheresultsthatPROCEXPANDyields.TheBEGINNINGcolumnisthedefault,andthatistheinterpolationcalculatedifthenumbersaremeasuredatthebeginningofthemonthandconvertedtothe
BEGINNINGoftheweek.MIDDLEandENDdothecalculationasifthenumbersweremeasuredandconvertedatthemiddleandtheendofthemonth,respectively.Thatiswhytheinterpolatedvaluesaremissinginthosecolumnsintheabovechart.Thenumbersare
notavailableuntilthebeginningoftheinterval(thebeginningoftheweekcontainingthemiddleandend,respectively,ofthemonth).
Ifyouaremeasuringtotals(whichweare,sincethisismasstransitridershipdata),thevaluesareradically
different.TOTALmeansthatthenumberbeinginterpolatedisnotrepresentativeofasinglepointintheFROM=interval,butthatitisobtainedacrossthedurationoftheFROM=interval.Therefore,thenumbersinthatcolumnoftheabovetablerepresentthenumberofriders
perweek,sincethatistheintervaltowhichweareconvertingourdata.AVERAGEconsidersthenumberstobeaveragesforboththeFROMandTO=intervals.
ItgetsalittlemoreinterestingwhenweusedifferentvaluesfortheOBSERVEDoption,
butitisextremelyimportanttorememberthatthesearemathematicallyderivedandnotdata-based,soyouneedtoexercisesomecautionandjudgmentastotheusefulnessofthesenumbers.TheBEGINNING,ENDcombinationtakestheoriginalvalueasthe
valueatthebeginningoftheMONTHinterval,andthen(using,inthiscase,thedefaultSPLINEmethod)returnsthevaluefromthatcurveattheendoftheWEEKinterval.Similarly,theAVERAGE,TOTALcombinationconsiderstheoriginalvaluetobethemonthlyaverage
andcalculatesaweeklytotalbasedonthedefaultSPLINEmethod.Thereareothermethodsavailabletouseintheconversionofintervals,andIencourageyoutoreadtheSAS/ETSdocumentationformorein-depthinformationaboutconvertingtoahigher
samplingfrequency.
DifferentFROMandTOValuesintheOBSERVED=Option
date BEGINNING,END
29DEC2002 2573.61
05JAN2003 2449.83
12JAN2003 2393.59
19JAN2003 2391.28
26JAN2003 2429.28
02FEB2003 2493.99
09FEB2003 2571.80
16FEB2003 2649.08
23FEB2003 2712.25
IncontrasttoExample6.12,Example6.13willshowtheeffectoftheOBSERVED=optiononalowersamplingfrequency.Remember,sinceouroriginaldatahadmissingvalues,someinterpolationwilltakeplace.
Example6.13:EffectofDifferentValuesfor
OBSERVED=OptiononLoweredFrequency
/*TheeffectofthedifferentvaluesfortheOBSERVEDoptionoftheCONVERTstatementinPROCEXPANDwithadecreasedsamplefrequency*/PROCEXPANDDATA=book.monthOUT=annual1FROM=MONTHTO=YEAR;IDdate;
CONVERTriders=beginning/OBSERVED=BEGINNING/*Default*/;RUN;PROCEXPANDDATA=book.monthOUT=annual2FROM=MONTHTO=YEAR;IDdate;CONVERTriders=middle/OBSERVED=MIDDLE;RUN;PROCEXPANDDATA=book.monthOUT=annual3FROM=MONTHTO=YEAR;IDdate;
CONVERTriders=end/OBSERVED=END;RUN;PROCEXPANDDATA=book.monthOUT=annual4FROM=MONTHTO=YEAR;IDdate;CONVERTriders=total/OBSERVED=TOTAL;RUN;PROCEXPANDDATA=book.monthOUT=annual5FROM=MONTHTO=YEAR;IDdate;CONVERTriders=average/
OBSERVED=AVERAGE;RUN;PROCEXPANDDATA=book.monthOUT=annual6FROM=MONTHTO=YEAR;IDdate;CONVERTriders=begend/OBSERVED=(BEGINNING,END);RUN;PROCEXPANDDATA=book.monthOUT=annual7FROM=MONTHTO=YEAR;IDdate;CONVERTriders=avetot/OBSERVED=(AVERAGE,TOTAL);
RUN;
DATAcompare_hi;MERGEannual1annual2annual3annual4annual5annual6annual7;BYdate;LABELbeginning="BEGINNING"middle="MIDDLE"end="END"average="AVERAGE"total="TOTAL"begend="BEGINNING,END"avetot="AVERAGE,TOTAL";;;FORMATbeginning--avetot11.2;
RUN;
PROCREPORTDATA=compare_hiNOWDSPLIT='\';COLUMNSdate('OBSERVED=\OptionValue'beginningmiddleendaveragetotal);FORMATdateYEAR4.;DEFINEdate/display;RUN;
PROCREPORTDATA=compare_hiNOWDSPLIT='\';COLUMNSdate
('OBSERVED=\OptionValue'begendavetot);FORMATdateYEAR4.;DEFINEdate/display;RUN;
OBSERVED=OptionIstheSameforFROM=andTO=:
date BEGINNING MIDDLE
2003 2679.90 2764.22
2004 3132.90 2972.48
BEGINNING,MIDDLE,andENDdon'tgiveusaverygoodideaofyearlyridership,becausetheyareconsideringtheentireridershipasoccurringonthebeginning,middle,orendofeach
observationintheFROM=interval.TOTAListhevaluefortheentireyear,andAVERAGEiscalculatedonthemonthlyvalues.However,allofthesevaluesarecalculatedwithinterpolationofthemissingvaluesinOctoberandNovember2003.Below,theinterpolationforthose
missingvaluesisstillperformedeventhoughweareusingdifferentvaluesforthefromandtoobservationcharacteristics.OfspecialinterestistheAVERAGE,TOTALcolumn.Itconsidersthemonthlydatatobetheaveragemonthlyridership,soPROCEXPANDinterpolates
forthemissingdataandthenprovidesaridershiptotalforeachyearbasedonthataveragemonthlyridership.
DifferentFROMandTOValuesintheOBSERVED=Option
OBSERVED=OptionValue
date BEGINNING,END
2003 3132.90
2004 3153.51
PROCEXPANDhasmanymorecapabilities,andtheprecedingexamplesgiveonlythemostbasicinformationabouthowtousethis
powerfulprocedurewithtimeseriesdata.YoucanrefertothedocumentationforSAS/ETStogetamuchmorecompleteexplanationofPROCEXPANDanditsoptions.
6.4International
Date,Time,andDatetimeFormatsandInformatsVersion9ofSAShasformatsfordatesandtimesinlanguagesotherthanU.S.English.ItisincludedinBaseSASasapartofNationalLanguageSupport(NLS).Thekey
toNLSisintheLOCALE=orDFLANG=systemoptions.ThedefaultvaluefortheLOCALEoptionisdefinedintheSASconfigurationfileandissetduringinstallation,butitcanbechangedwithanOPTIONSstatementorinsidetheOPTIONSwindow.The
LOCALE=optionimplicitlysetstwootheroptionsthatcanaffectdates,times,anddatetimevaluesinSAS.ItwillsettheDATESTYLE=option,whichdetermineshowtheANYDTinformatswillinterpretcharacterstringswheretheorderofmonth,day,andyearisambiguous.The
DFLANG=optiondefinesthedefaultlanguagethatSASwilluse.
ThereareafewspecificdateformatsforTaiwanese,Japanese,andHebrew,butyoucanconsiderthemajorityofinternationalformatsandinformatsasfalling
intooneoftwoinformalcategories:the"EUR"categoryortheNLScategory.Ingeneral,itisrecommendedthatyouusetheNLSformatsandinformatsbecauseyoudonothavetowritecodespecifictoalanguage.ChanginglanguagesusingtheNLSfacilityinSASisa
matterofchangingthevalueoftheLOCALE=option,whichbringstheformatsinlinewiththerestoftheSASsession.However,the"EUR"categorycanbeuseful.YoucanselectthelanguagebasedoneithertheDFLANG=systemoptionorbyreplacingthe"EUR"intheformatnamewitha
specificlanguageabbreviation.Usingthelanguageabbreviationsishandyifyouareworkingwithmanylanguagesonthesameoutput,becausetheyenableyoutospecifythelanguagewithoutregardtoasystemoption,andyoucanusethemexactlywhereyouneedthem,foras
longasyouneedthem.
6.4.1"EUR"FormatsandInformatsEachoftheseformatsandinformatscorrespondtoanEnglishlanguageformatorinformat.However,the
minimum,maximum,anddefaultwidthsfortheformatorinformataredependentuponthelanguagebeingusedatthetime.Tables6.3and6.4listtheEnglishlanguageformatsandtheirEURformatnames,andtheEURinformats.
Table6.3:International
FormatNamesandTheirEnglishLanguageEquivalents
EnglishLanguageFormatName
InternationalFormatName
DATE. EURDFDE.
DATETIME. EURDFDT.
DDMMYY. EURDFDD.
DOWNAME. EURDFDWN.
MONNAME. EURDFMN.
MONYY. EURDFMY.
WEEKDATX. EURDFWKX.
WEEKDAY. EURDFDN.
WORDDATX. EURDFWDX.
Table6.4:InternationalInformatNamesandTheirEnglishLanguageEquivalents
Informat Description
EURDFDEw. Readsinternationaldatevaluesintheform
ddmonyy(yy),whereddrepresentsthedayofthemonth,monisthethree-lettermonthabbreviationinthe
language
specifiedbytheDFLANG=systemoptionorbytheappropriatethree-letterprefix,and
yy(yy)isthetwo-orfour-digityear.
EURDFDTw. Readsinternationaldatetimevaluesintheformddmonyy
hh:mm:ss.ssorddmonyyyyhh:mm:ss.ss.
EURDFMYw. Readsmonthandyeardatevaluesintheformmonyyormonyyyy.
Youreplace"EUR"withaspecificthree-letterlanguageprefixinanyoftheaboveformatsorinformatstodefinethelanguagethatyouwanttouse.ThisoverridestheDFLANG=systemoptionandisagoodwaytodisplaydatesinmultiplelanguagessimultaneously.Table
6.5isalistofallthevalidlanguageswiththeirthree-letterprefix.Inaddition,we'llshowtheeffectofusingeachthree-letterprefixontheEURDFWKX.formatbyusingthereferencedateofTuesday,February18,2014.Asacomparison,thetablealsoincludesthereferencedate
formattedastheEnglishequivalentusingtheWEEKDATX.format.
Table6.5:InternationalDateFormatswithLanguageAbbreviations
LanguagePrefix Language
AFR Afrikaans
CAT Catalan
CRO Croatian
CSY Czech
DAN Danish
NLD Dutch
FIN Finnish
FRA French
DEU German
HUN Hungarian
ITA Italian
MAC Macedonian
NOR Norwegian
POL Polish
PTG Portuguese
RUS Russian
ESP Spanish
SLO Slovenian
SVE Swedish
FRS Swiss_French
DES Swiss_German
6.4.2NLSFormatsTheoutputfromtheNLSseriesofformatsisdefinedbytheLOCALE=systemoption.Unlikethe"EUR"series,you
cannotspecifyalanguage;thelanguageisdefinedbythecurrentvalueoftheLOCALE=option.Usetheseformatswhenyouroutputmightbegeneratedinseverallocationsaroundtheworld,butyoudon'thavetodisplaymultiplelanguageswithinthesameoutput.
TheseformatsworkbyconvertingaSASdate,time,ordatetimevaluetothatofthespecifiedlocaleandthenformattingtheresult.Theseformatsarealsonoteworthyinthattheresultisleft-justified,asopposedtotheright-justificationofmostoftheotherdate,time,anddatetimeformats.
ThisistrueforallODSdestinationsaswellasfortraditionalcolumn-basedoutput.Ofcourse,withODSdestinations,thejustificationofthecolumnwillbeperformedaccordingtoanySTYLEineffect.
Tables6.6,6.7,and6.8listtheNLSformats
availablefordates,datetimes,andtimes,respectively.EachtablewillgivetheNLSformatname,adescriptionoftheoutputcreatedbytheformat,thedefaultformatwidth,andwidthrange.Thedescriptionoftheoutputcanalsocontainarecommendedwidth,
whichmightdifferfromthedefault.Therecommendedwidthistheminimumformatwidthnecessarytodisplayallpossibledate,datetime,ortimevalues,becausethelengthoftheoutputmightexceedthedefaultwidthinthegivenformatforsomelocaleandencoding
combinations.Ifyouusetherecommendedwidthsgiveninthetable(s)below,youwillalwaysgetaccurateoutput.Otherwise,youroutputcouldhaveaseriesofasterisks(*****)inplaceofthedatestringthatyouexpected.Ingeneral,itisalwaysbettertospecifyaformatwidth
thatistoolongratherthanonethatistooshort.ODSwillhandlemostjustificationissuesarisingfromoverestimatinghowmanycharacterswillbereturnedfromaformat.Notethatthewidthspecificationsfordatetimeandtimeformatscanaccommodate
fractionalseconds(w.d),andtheywillbedisplayedwiththelocale-specificdecimalseparator.BecausetherearesomanyNLSformatsavailable,AppendixBwillshowthedifferenceinoutputresultingfromdifferentLOCALEsettingsusingaspecificdate,datetime,andtimeas
appropriateforeachoftheNLSformatsinthefollowingthreetables.
Table6.6:NLSDateFormats
FormatName Description
NLDATEw. Displaysthedateasmonthname,day,and
yearinlocalformat.SASwilluseDATE.inlocalformatorabbreviatethemonthnametofittheformatwidthspecified.Itis
recommended
thatyouuseaminimumformatwidthof25toensureaccurateoutputacrossallsupportedlanguages.
NLDATELw. Displaysthedateasmonthname,day,andyearinlocalformat.SASwillabbreviatemonthnameoruseonlynumbersand
delimiterstofittheformat
widthspecified.
NLDATEMw. Displaysthedateasthelocalabbreviation
formonthalongwiththedayandyear,butwilluseonlynumbersanddelimiterstofittheformatwidthspecified.
NLDATEMDw. Displaysmonthnameandday(noyear)fromadatevalue.SASwillusethelocalabbreviationforthemonthnameifthe
formatwidthcannotaccommodatethefullmonth
name.
NLDATEMDLw. Displaysthefullmonthnameandday
(noyear)fromadatevalueinlocalformat.SASwillabbreviatethemonthnameoruseonly
numbersanddelimitersfor
themonthanddayiftheformatwidthcannotaccommodatethefullmonthname.
NLDATEMDMw. Displaysthelocal
abbreviationforthemonthnameandtheday(noyear)fromadatevalue.SASwilluseonlynumbersanddelimitersfor
themonthanddaytofittheformatwidthspecified.
NLDATEMDSw. Displaysthemonthandday(noyear)fromadatevalue
usingonlynumbersanddelimiters.
NLDATEMNw. Displaysthemonthnamefromadatevalueinlocalformat.SASwillabbreviate
themonthnametofittheformatwidthspecified.
NLDATESw. Displaysthedateinlocalformatusingnumbersanddelimiters
only.
NLDATEWw. Displaysadatevalueasdayoftheweekanddateinlocalformat.SASwillabbreviateday-of-week,and/ormonth
nameasnecessarytofittheformat
widthgiven.
NLDATEWNw. Displaysadatevalueasthedayoftheweekinlocal
format.SASwillabbreviateasnecessarytofittheformatwidthgiven.
NLDATEYMw. Displaysmonthnameandyearfromadate
valueinlocalformat.SASwillabbreviatemonthnameand/oruse2-digityearasnecessarytofit
theformatwidth.
thatsomeformatwidthsmightbetoosmalltoaccommodatetheabbreviations.Inthatcase,aseriesof
asterisks(*****)willbe
displayed.
NLDATEYMLw. Displaysadatevalueasthefullmonthnameandtheyearinlocalformat.If
necessary,SASwillabbreviatethemonthnameoruseonlynumbersanddelimitersforthemonthandyearand/ora2-
digityeartofittheformatwidthspecified.
NLDATEYMMw. Displaysadatevalueasthelocalabbreviationformonth
nameandtheyear.Ifnecessary,SASwilluseonlynumbersanddelimitersforthemonthandyearand/ora2-digityearto
fittheformatwidth
specified.
NLDATEYMSw. Displaysthemonthandyearfromadatevalueusingonlynumbersand
delimitersinlocalformat.Willuse2-digityearifformatwidthis5or6.
NLDATEYQw. Displaysadatevalueascalendar
quarterandyear.Itisrecommendedthatyouuseaminimumformatwidthof20toensureaccurateoutputacross
allsupported
languages.
NLDATEYQLw. Displaysadatevalueasthefulllengthforthecalendarquarterandtheyear(forexample,"3e
trimestre2014").Awidthof4willdisplaya2-digityear.SASwillabbreviate
asnecessarytofittheformatwidth
specified.
NLDATEYQMw. Displaysadatevalueasaquarterabbreviationandtheyear(forexample,"T32015").SASwilluse
onlynumbersanddelimiterstofittheformatwidthifnecessary.Awidthof4willdisplaya2-
digityear.
NLDATEYQSw. Willdisplaytheyearandcalendarquarterfromadatevalueinlocalformatusingonlynumbersanddelimiters.A
widthof4willdisplaya2-digityear.
NLDATEYRw. Willdisplaythe2-or4-digityearfromadatevalue.
NLDATEYWw. Displaysadate
valueastheweeknumberandtheyear(forexample,"Week152014").weekalgorithmisused(U,V,or
W)variesbasedonthevalueofthe
LOCALE=option.theWEEKU.,WEEKV.,andWEEKW.format
discussionsinSection2.4.1DateFormats,formoreinformationabouttheweekalgorithms.
Table6.7:NLSDatetimeFormats
FormatName Description
NLDATMw.d Displaysadatetimevalueasadatetimeinlocalformat.
NLDATMAPw.d Displaysadatetimevalueasmonthname,day,year,andtimeinlocalformat.SASwillabbreviateas
necessarytofittheformatwidthspecifiedandmaysubstitutenumbersanddelimitersforthemonthname,day,
andyear.
NLDATMDTw.d Displaysthedatefromadatetimevaluewiththemonthname,day,andyearinlocalformat.SAS
willabbreviatethemonthnameorsubstitutenumbersanddelimitersinlocalformatforthemonthname,day,
andyearasnecessaryto
fitthesuppliedformatwidth.
NLDATMLw.d Displaysthedatefromadatetimevaluewiththe
monthname,day,andyearinlocalformat.SASwillabbreviatethemonthnameorsubstitutenumbersand
delimitersinlocalformatforthemonth
name,day,andyearasnecessarytofitthesuppliedformatwidth.
NLDATMMw.d Displaysthedateandtimefromadatetimevalueusingtheabbreviationformonthname.SAS
willusenumbersanddelimitersforthedateifthe
formatwidthisnotwideenoughandwillfurtherabbreviatethe
timetohours:minutes,thenjusthoursifnecessary.
NLDATMMDw.d Displaysthemonthanddayfroma
datetimevalue.SASwillabbreviatethemonthnameorusenumbersanddelimitersinlocalformat
(noyear)iftheformatwidthcannotaccommodatethefullmonthname.
NLDATMMDLw.d Displaysthemonthanddayfroma
datetimevalue.SASwillabbreviatethemonthnameorusenumbersanddelimitersin
localformat
(noyear)iftheformatwidthcannotaccommodatethefullmonthname.
NLDATMMDMw.d Displaystheabbreviatedmonthname
anddayfromadatetimevalue.SASwillusenumbersanddelimitersinlocalformat(noyear)iftheformat
widthcannotaccommodatethefullmonthname.
NLDATMMDSw.d Displaysthemonthanddayfromadatetimevalueas
numbersanddelimitersonly(forexample,mm/ddordd/mm).
NLDATMMNw.d Displaysthemonthnameinlocalformat
fromadatetimevalue.SASwillabbreviateifthefullmonthnamewillnotfitintheformatwidth
supplied.
NLDATMSw.d Displaysadatetimevalueasnumbersanddelimitersonly,inlocalformat(forexample,
17/05/201413:47:06).
NLDATMTMw.d Displaystimeofdayfromadatetimevalueinlocaltimeformat.
NLDATMTZw.d Displaystime
ofdayfromadatetimevalueinhoursandminutesandthetimezoneoffsetforthelocale.
NLDATMWw.d Displaysadatetime
valueasdayoftheweek,date,andtimeinthelocalformat.Itisrecommendedthatyouuseaminimumformatwidth
of49toensureaccurateoutputacross
allsupportedlanguages.
NLDATMWNw.d Displaysthedayofthe
weekfromadatetimevalueinlocalformat.SASwillabbreviateiftheformatwidthistoosmallto
accommodatethefulldayofweekname.
NLDATMWZw.d Displaysdayoftheweekanddatetimeinlocalformat.SASwill
abbreviateasnecessary.Itisrecommendedthatyouuseaminimumformatwidthof55to
ensureaccurate
outputacrossallsupportedlanguages.
NLDATMYMw.d Displaysthemonthnameandyearfromadatetimevalue.SASwill
abbreviatethemonthnameand/orusea2-digityeartofittheformatwidthspecified.
NLDATMYMLw.d Displaysthemonthname
andyearfromadatetimevalue.SASwillabbreviatethemonthnameorusethemonth
number,and
usea2-digityearifnecessarytofittheformatwidthspecified.
NLDATMYMMw.d Displaystheabbreviated
monthnameandyearfromadatetimevalue.SASwillusethemonthnumberanda2-digityearifnecessaryto
fittheformatwidthspecified.
NLDATMYMSw.d Displaysthemonthandyearfromadatetimevalueusingnumbersand
delimitersonly.SASwillusea2-digityearifnecessarytofittheformatwidthspecified.
NLDATMYQw.d Displaysthe
yearandquarteroftheyearfromadatetimevalueinlocalformat.SASwillabbreviatequarterand
usea2-digityearifnecessaryto
fittheformatwidthspecified.Itisrecommendedthatyouuseaminimum
formatwidthof20toensureaccurateoutputacrossallsupportedlanguages.
NLDATMYQLw.d Displaysthe
yearandquarteroftheyearfromadatetimevalueinlocalformat.SASwillabbreviatequarter,use
numbersanddelimitersonly,andusea2-digityearifnecessarytofittheformat
widthspecified.
NLDATMYQMw.d Displaystheyearandquarteroftheyearfromadatetimevalueasanabbreviationinlocalformat.SAS
willusenumbersanddelimitersonlyandusea2-digityearifnecessarytofittheformatwidthspecified.
NLDATMYQSw.d Displaystheyearandquarteroftheyearfromadatetimevalueinlocalformatasnumbersanddelimiters
only.SASwillusea2-digityearifnecessarytofittheformatwidthspecified.
NLDATMYRw.d Displaystheyearfroma
datetimevalue.SASwillusea2-digityearifnecessarytofittheformatwidthspecified.
NLDATMYWw.d Displaysa
datetimevalueastheyearandnameoftheweek.SASwillabbreviateweekand/orusea2-digit
yearifnecessaryto
fittheformatwidthspecified.
NLDATMZw.d Displaysadatetimevalueasadatetime
stringinlocalformatwiththetimezoneoffset.
Table6.8:NLSTimeFormats
FormatName Description
NLTIMAPw.d Displaysa
timevalueasthetime,followedbyAMorPMinlocalformat.Itisrecommendedthatyouuseaminimum
formatwidth
of22toensureaccurateoutputacrossallsupportedlanguages.
NLTIMEw.d Displaysatimevalueas
thetimeinlocalformat.
Similartothe"EUR"informats,youcanuseNLSinformatstoprocessdataaccordingtotheLOCALE=systemoption.Table6.9showstheNLSinformatsavailable,theirdefaultwidth
specification,thewidthrange,andtheEnglishlanguageinformattowhichitissimilar.
Table6.9:NLSTimeInformats
CategoryFormatName
Date NLDATEw.
Datetime NLDATMw.
Time NLTIMAPw.
NLTIMEw.
ThewholepointofNLSformatsandinformatsisthatyoudonothave
toworryaboutthespecificlanguagethatwillbeusingtheformatorinformat.TheLOCALE=systemoptionwilltakecareofit.Inthisway,thesameSASprogramcanbeusedanywhere,andtheoutputwillbeappropriatetothelocallanguageaslongastheLOCALE=system
optionhasbeensetcorrectly.ItisimportanttounderstandthatNLSformatsandinformatsworkjustaswellwiththeEnglishlanguageaswithanyotherlanguage,sothere'snoneedtouseSASprogramcodebeyondtheLOCALE=optiontoswitchbetween
Englishlanguageformats/informatsandotherlanguages,unlessyouneedaspecificformatthatdoesnothaveanNLSequivalent.Also,bearinmindthatanyPICTUREformatsyoucreatefordatesandtimesareNLS-compatiblebydefault,andthedisplayofdate
ortimecomponentssuchasmonthnamearelocale-sensitive.
6.5NLSDate,Time,andDatetimeConversionFunctions
Therearethreefunctionstohelpyouworkwithdate,time,anddatetimevaluesandprovideoutputinthelocallanguagebasedontheLOCALE=systemoptionineffect.TheNLDATE(),NLTIME(),andNLDATM()functionstakeadate,time,ordatetimevalue,
respectively,andcreateastringvariableaccordingtoaseriesofdateandtimedirectives.ThisisthesameprocessthatoccursifyoucreateacustomformatusingthePICTUREstatement(seeSection2.6),andthencreateacharactervariablebyusingthePUTfunctionwithyour
custompictureformatandadate,time,ordatetimevalue.
Example6.14:CreatingaCharacterValueUsingaCustomPictureFormatandthePUT()
FunctionPROCFORMAT;PICTUREwordmonth(DEFAULT=15)LOW-HIGH='%B%Y'(DATATYPE=DATE);RUN;
DATApicdate;INPUTdate:mmddyy10.;month_and_year=PUT(date,wordmonth.);FORMATdatedate11.;DATALINES;05/15/2016
08/01/201210/31/201303/27/2014;RUN;
ODSRTFFILE="ex6.5.1.rtf";PROCPRINTDATA=picdateNOOBSLABELSPLIT='\';labeldate="OriginalDate"month_and_year='MonthandYear\CharacterValue';RUN;
Thisistheresultingdataset.Notethatthenumericdatevariable,whichhasbeenformattedusingtheDATE.format,isright-justified,whilethecharacterstringwecreatedisleft-justified.
OriginalDate
MonthandYearCharacterValue
15-MAY-2016
May2016
01-AUG-2012
August2012
31-OCT-2013
October2013
27-MAR-2014
March2014
Essentially,thethreeNLSfunctionsdothesamething,butwithouthavingtocreatethepictureformatusingtheFORMATprocedure.
Youputthedescriptionoftheoutputstringdirectlyintothefunctionasanargument,whichiscalledthedescriptor.Thedescriptorcanalsocontainfixedtextwiththedatedirectives,butthisissomewhatcountertothepurposeofthesefunctions,asthefixedtextyouinsert
willnotchangewiththeLOCALE=optionsetting.
TherearemoredatedirectivesavailablewiththesefunctionsthanwiththePICTUREstatementoftheFORMATprocedure.FollowingisthelistofdatedirectivesyoucanusewiththeNLDATE(),
NLTIME(),andNLDATM()functions.Althoughseveralofthedirectivesmayseemidenticaltothoseusedwithpictureformats,thesedirectivesallinsertaleadingzerobydefault,sokeepthatinmindwhenusingthesefunctions.Youwillreceiveanerrorifyoutrytouseatime
directivewithNLDATE(),oradatedirectivewithNLTIME().
Table6.10:NLDATE(),NLTIME(),andNLDATM()DateDirectives
DateDirective Description
# removesthe
leadingzerofromtheresult.
%% Specifiesthepercent(%)character.
%a Locale'sabbreviated(3-character)
weekdayname.
%A Locale'sfullweekdayname.
%b Locale'sabbreviated(3-character)
monthname.
%B Locale'sfullmonthnamewithoutpadding.Whenyouspecify'%B
%d,'therewillalwaysbeonespacebetweenthemonthandday.
%C Locale'sfullmonthnamewithblank
padding.Whenyouspecify'%C%d,'therewillbeoneormorespacesbetweenthemonthand
day,dependinguponthelengthofthemonth'sname.
%d Zero-paddednumericaldayofthe
month.Use'#d'tosuppresstheleadingzero.
%e Blank-paddednumericaldayofthe
month.Use'#e'tosuppresstheleadingblank.
%F Locale'sfullweekdayname,paddedwith
blanks.Ifyouonlywantasinglespacebetweentheweekdaynameandthenextitem,use
'%A'.
%j Zero-paddeddayoftheyearasadecimalnumber(001–366).Use'#j'tosuppressany
leadingzeroes.
%H Zero-paddedhour(24-hourclock)asadecimalnumber(00–23).Use'#H'tosuppress
theleadingzero.
%I Zero-paddedhour(12-hourclock)asadecimalnumber(01–12).Use'#I'tosuppress
theleadingzero.
%m Zero-paddedmonthasadecimalnumber(01–12).Use'#m'tosuppressthe
leadingzero.
%M Zero-paddedminuteasadecimalnumber(00–59).Use'#M'tosuppresstheleadingzero.
%o Blank-paddedmonthasadecimalnumber(1–12).Use'#o'tosuppresstheleadingblank.
%p Locale'sequivalentofa.m.orp.m.
%S Zero-paddedsecondasadecimalnumber(00–59).Use'#S'
tosuppresstheleadingzero.
%u Weekdayasanumberintherange1–7,where1isMondayand
Sundayis7.
%U Zero-paddedweek-number-of-year(00–53)usingtheUalgorithm,whereSundayis
consideredthefirstdayoftheweek.
%V Zero-paddedweek-number-of-year(00–53)usingtheISO8601-
standardValgorithm,whichdefinesthefirstweekoftheyearascontainingbothJanuary4
andthefirstThursdayoftheyear.Therefore,ifthefirstMondayoftheyearfallsonJanuary2,3,or4,
theprecedingdaysofthecalendaryearareconsideredtobeapartofweek53ofthe
previouscalendaryear.
%w Weekdayasanumberintherange0–6where0isSundayand6is
Saturday.
%W Zero-paddedweek-number-of-year(00–53)usingtheWalgorithm,whichusesMondayas
thefirstdayoftheweek.
%y Zero-paddedyearwithoutcenturyasadecimalnumber(00–99).
%Y Yearwithcenturyasadecimalnumber(4-digityear).Theyearrangesfrom1970to2069.
HerearetheNLSdatefunctions.Whenyouareusingtextforthedescriptor,thedatedirectivesmustbeenclosedinsinglequotes,orSASwilltrytointerpretthemasmacrocalls.
FunctionCall Explanation
NLDATE(SAS- Convertsa
date-value,descriptor)
SASdatevalueintoacharacterstringintheformdescribedbydescriptorwhichisa
combinationofthedirectivesintable6.10enclosedbysinglequotes.descriptormayalsobe
acharactervariablecontainingavaliddescriptorstring.
NLDATM(SAS-datetime-value,descriptor)
ConvertsaSASdatetime
valueintoacharacterstringintheformdescribedbydescriptorwhichisacombination
ofthedirectivesintable6.10enclosedbysinglequotes.descriptormayalsobeacharacter
variablecontainingavaliddescriptorstring.
NLTIME(SAS-time-value,descriptor)
ConvertsaSAStimevalueintoacharacter
stringintheformdescribedbydescriptorwhichisacombinationofthedirectivesin
table6.10enclosedbysinglequotes.descriptormayalsobeacharactervariablecontaininga
validdescriptorstring.
Table6.11showstheresultsfordifferentOPTIONSLOCALE=settingswhenyouusetheNLDATEfunctiontocreateacharacterstringcontainingthe
day-of-weekname(%A),thethree-letterabbreviatedmonthname(%b),numericalday(%d),andfour-digityear(%Y).
Table6.11:TheNLDATEFunction
SampleFunctionCall
NLDATE('26OCT2014'd,'%A%b%d%Y');
NLDATE('26OCT2014'd,'%A%b%d%Y');
NLDATE('26OCT2014'd,'%A%b%d%Y');
NLDATE('26OCT2014'd,'%A%b%d%Y');
NLDATE('26OCT2014'd,'%A%b%d%Y');
Table6.12showstheresultsfordifferentOPTIONSLOCALE=settingswhenyouusetheNLDATMfunctiontocreateacharacterstringcontainingtheabbreviatedday-of-
weekname(%a),numericaldaywithouttheleadingzero(%#d),thefour-digityear(%Y),andthecolon-delimited24-hourtimewithzero-paddedhoursandminutes(%H:%M).
Table6.12:TheNLDATMFunction
SampleFunctionCall
NLDATM('06MAY2014:14:30:00'd,'%a%#d%B%Y%H:%M');
NLDATM('06MAY2014:14:30:00'd,'%a%#d%B%Y%H:%M');
NLDATM('06MAY2014:14:30:00'd,'%a%#d%B%Y%H:%M');
NLDATM('06MAY2014:14:30:00'd,'%a%#d%B%Y%H:%M');
NLDATM('06MAY2014:14:30:00'd,'%a%#d%B%Y%H:%M');
Table6.13showstheresultsfordifferentOPTIONSLOCALE=settingswhenyouusetheNLTIMEfunctiontocreateacharacter
stringcontainingthecolon-delimited12-hourtimewithzero-paddedhoursandminutes(%I:%M)andthelocale'sAM/PMindicator(%p).
Table6.13:TheNLTIMEFunction
SampleFunctionCall
NLTIME('10:17:00'd,'%I:%M%p');
NLTIME('10:17:00'd,'%I:%M%p');
NLTIME('10:17:00'd,'%I:%M%p');
NLTIME('10:17:00'd,'%I:%M%p');
NLTIME('10:17:00'd,'%I:%M%p');
6.6DateFormatsandInformatsforOtherCalendarsSAShastheabilitytohandledatesfromnon-Juliancalendars,such
asHebrew,Japanese,andTaiwanese.ThedatevaluescontinuetobestoredasSASdates,whereJanuary1,1960,isequaltozero,buttheseformatshandletheconversiontotheothercalendarsforthecorrectdisplayofdates.
6.6.1Hebrew
DateFormats
HDATEw.HDATEw.displaysaSASdatevalueinHebrew.Youwillneedthecorrectcharacterencodinginstalledonyoursystemtodisplaythiscorrectly.TheSASdatewillbedisplayedasyyyymmmmmdd,
whereyyyyistheyear,mmmmmrepresentsthemonth'snameinHebrew,andddistheday-of-the-month.wcanbefrom9to17,withadefaultwidthof17,anditisright-justified.Useoddnumbersforwtogetthebestdisplay.
HEBDATEw.
HEBDATEw.displaysaSASdatevalueaccordingtotheJewishcalendar.Itisacombinedsolarandlunarcalendar.TheHebrewyeariscalculatedbyadding3761beginninginautumnofaspecifiedyearintheGregoriancalendar.wcanbefrom7to24,witha
defaultwidthof16,anditisright-justified.Therearethreeformsofthedisplay,long,default,andshort,dependentupontheformatwidthspecified.Again,youwillneedthecorrectcharacterencodinginstalledonyoursystem,oryouwillgetsubstitutionsfornonprinting
characters.
6.6.2JapaneseandTaiwaneseDateFormats
MINGUOw.MINGUOw.displaysaSASdatevalueasaTaiwanesedatevalueintheform
yy(yy)mmdd,whereyy(yy)istheyear,mmisthenumberofthemonth,andddisthedayofthemonth.wcanrangefrom1to10,withadefaultwidthof8,anditisleft-justifiedandzero-filled.TheTaiwanesecalendaruses1912asthebaseyear(thatis,01/01/01isJanuary1,1912).
Datespriortothiswilldisplayasaseriesofasterisks(*****).Also,theyearvaluescontinuetoincreasepast100;theydonotremaintwo-digityearsandcycle,muchlikeJuliandates.Forexample,January1,2012is"100/01/01,"not"00/01/01."
NENGOw.NENGOw.writesaSASdatevalueintheforme.yymmdd,whereeisthefirstletterofthenameoftheemperor(Meiji,Taisho,Showa,orHeisei),yyistheyear,mmisthemonth,andddisthedayofthemonth.wcanbefrom2to10,withadefault
widthof10,anditisleft-justified.SASwillomittheperiodifwisn'tbigenough.
6.6.3JapaneseandTaiwaneseDateInformats
JDATEMYDw.JDATEMYDw.allows
youtoconvertJapaneseKanjiintheformyy(yy)monddtoSASdatevalues,whereyy(yy)istheyear,monistheKanjirepresentationofthenameofthemonth,andddrepresentsthedayofthemonth.wcanbefrom12to32,withadefaultwidthof12.Youcanseparate
(yy)yy,mon,andddwithspecialcharactersorblanks,butyoumustmakesurethatthewidthspecificationallowsforanyblanksand/orspecialcharactersintheinputfield.Two-digityearswillbetranslatedaccordingtotheYEARCUTOFF=option.
JNENGOw.JNENGOw.readsJapaneseKanjidatevaluesintheformyymmdd,whereyyistheyear,mmistheKanjirepresentationofthenameofthemonth,andddrepresentsthedayofthemonth.Sinceyyistwodigitslong,thisinformatisalways
affectedbytheYEARCUTOFF=option.wcanbefrom16to32,withadefaultwidthof16.Youcanseparateyy,mon,andddwithspecialcharactersorblanks,butyoumustmakesurethatthewidthspecificationallowsforanyblanksand/orspecialcharactersin
theinputfield.
MINGUOw.MINGUOw.convertsaTaiwanesedatevalueintoaSASdatevalueintheformyy(yy)mmdd,whereyy(yy)istheyear,mmisthenumberofthemonth,andddisthedayofthemonth.w
canbefrom6to10,withadefaultwidthof6.Youmayuseseparatorssuchasblanks,dashes,orslashesbetweentheyear,month,anddayvalues,buttheymustbepresentbetweenallofthevalues.TheTaiwanesecalendaruses1912asthebaseyear(thatis,01/01/01
isJanuary1,1912).Inaddition,theyearvaluescontinuetoincreasepast100;theydonotcycle.January1,2012,is"100/01/01,"not"00/01/01."Youwillgetamissingvalueifyouusethisformattoreaddatestringswheretheyearcomponentislessthan1.
6.7OtherSoftwareandTheirDates(Excel,Oracle,DB2)MostsoftwarepackageskeeptheirdatesinsomesortofnumericalforminmuchthesamewaythatSASdoes,whileothershaveaspecialvariabletype
fordates.MicrosoftExcelstoresdatesasintegers,butitusesJanuary1,1900,insteadofJanuary1,1960,asdayzero.TimesarestoredinExcelasfractionsofdays,sonoonofagivendayis.5(exactlyone-halfofaday).DatetimevaluesarestoredinExcelasthe
dayrelativeto01/01/1900plusthefractionoftheday.InExcel,6p.m.onJanuary1,1900,isrepresentedas.75.Excelalsohasamajorlimitationonitsdatealgorithm:Itcannotstoreitsdatesasnegativenumbers.ThismeansthatanydatepriortoJanuary1,
1900,isgoingtoberepresentedbyacharacterstring,notanExceldatevalue.Therefore,ifyouhavehistoricaldatesinanExcelspreadsheet,youneedtobeawarethatyouwillhavetoprocessanycolumn(s)withhistoricaldatesascharactercolumns,andusetheINPUT()
functiontocreateyourSASdatevalues.TheANYDTinformatsmayalsoproveusefulinsituationslikethis.IfyourelyonanautomatedmethodofconversionfromExceltoSAS,thereisthepossibilitythatacolumnwithhistoricaldatesmightbetranslatedasanumeric
column.Ifthisoccurs,thenanydates(ordatetimes)priortoJanuary1,1900,willbemissinginyourSASdataset.YouwillrunintothesameproblemexportinghistoricaldatesintoExcelfromSAS.Youwillhavetoexportthecolumnasacharactercolumn,andyouwon'tbeableto
useanyoftheExceldateormathfunctionsoncellscontainingtheminsidethespreadsheet.
TheseareconversionissuesspecifictoExcelthatmayarisewhenyouaretryingtoimportorexportdatatoorfromExcel.Whenyouimportdatafrom
othersoftwarepackagesintoSASusingtheIMPORTprocedure,oneofthedatabaseengines,orwithpass-throughSQLprocessing,SASshouldunderstandandconvertthedates,eventhoughthereferencedatefortheothersoftwaremaydiffer.Thereareexceptionstothisrule,
oneofwhichisusingapass-thruWHEREclauseinsidePROCSQLforforeigndatabases.Youwillhavetoknowthedate,time,ordatetimeformatfortheforeigndatabasetoselectrecordsbasedondates,times,ordatetimes.TherearespecificcaseswhereSASdoesnot
haveaninformatforcertaindatetimestringsfromotherdatabasesandcannottranslatethosevaluesintotheirSASequivalent.Thegeneralstrategytopursueinthesecasesistoparsethedatetimestringandworkfromtherewithacombinationofinformatsand/or
functionstocreateyourSASdatetimevalues.Ifyouwillneedtodothisonaregularbasis,youcouldcreateamacroorusePROCFCMPtoprocessyourtroublesomedatetimestrings.
Sendingdatestootherdatabasesandsoftwarepackagesshouldbefine
ifyouusetheEXPORTprocedureoroneofthedatabaseengines.Ifyouaredeterminedtosenddatestoanotherdatabaseorsoftwarepackagethehardway,thenyouwillhavetoproduceSASdate,time,ordatetimevaluesascharacterstringsintheformatoftheothersoftwareand
thenimportthemusingthemethodsavailabletoothersoftwarepackages.YoucanuseapictureformatandthePUTstatementtoaccomplishthis,aslongasyouknowthecorrectrepresentationofthepackageforwhichyouarecreatingthedata.Fordetailsoncreatingpicture
formats,seeSection2.6.Example6.15showshowthisisdoneforaDB2database.
Example6.15:WritingDatetimeValuesforDB2UsingaPictureFormat
PROCFORMAT;
PICTUREdbdateLOW-HIGH='%Y-%0m-%0d:%0H:%0M:%0S'(DATATYPE=DATETIME).-.Z='0000-00-00:00:00:00';RUN;
DATA_NULL_;now='01JUL2014:20:18:32'dt;PUT"nowdisplayedasdatetimevalue:"@33now;PUT"nowdisplayedasdatetime19.:"@33nowDATETIME19.;
PUT"nowdisplayedasdbdate.:"@33nowDBDATE.;RUN;
TheResultnowdisplayedasdatetimevalue:1719865112nowdisplayedasdatetime19.:01JUL2014:20:18:32nowdisplayedasdbdate.:2014-07-01:20:18:32
6.7.1The
SASDATEFMT=SystemOptionThissystemoptioncanbeusefulwhenyouareworkingwithoneofthefollowingdatabases:Aster,DB2underUNIXandPCHosts,Greenplum,Impala,Informix,MicrosoftSQLServer,MySQL,Netezza,
ODBC,OLEDB,Oracle,PostgreSQL,SAPHANA,Sybase,SybaseIQ,Teradata,orVertica.ItenablesyoutochangethedateformatofacolumnintheDBMS.ItisusedtoavoiddatatypemismatchesbetweenSASdate,time,ordatetimevaluesandtheDBMSdatecolumns
whenimportingtoSASfromaDBMS,orexportingtoaDBMSfromSAS.Thesyntaxisasfollows:
OPTIONSSASDATEFMT=(DBMS-date-column1=SASdate-format1,DBMS-date-column2=SASdate-format2,…
DBMS-date-columnn=SASdate-formatn);DBMS-date-columnisthenameofadatecolumnintheDBMS,andSASdate-formatisthenameofaSASdate,time,ordatetimeformat.Thisformatmustalsohaveaninformatofthesamenametoworkinthis
option.Forexample,DATE9.isbothaformatandaninformat,soitwouldbevalid.
Inorderforthisoptiontohaveaneffect,theDBMScolumnmusthaveatypeofDATE,TIME,orDATETIME;anyotherdatatypewillbeignoredbythis
option.YouusethiswhenthedefaultSASdateformat(whichisDBMS-anddatatype-specific,seetheSAS/ACCESSdocumentationfordetails)doesnotmatchtheSASdateformatyouwantorvice-versa.
6.8ConclusionInsummary,whenworkingwithdatesandtimesanddatetimesfromothersoftware,youfirsthavetomakesurethatyouarenotworkingwithcharacterstringsmasqueradingasdates.Ifyouhaveacharacterstring,youwillhavetoconvertit
toaSASdate,time,ordatetimeyourselfwiththeINPUT()function(Section3.3.3).Thereversealsoholdstruewhenyouareexportingtootherdatabases.WhilemostofthemethodstotraversebetweendifferentsoftwareandSASwillhandletheimportandexportofdates,times,
anddatetimesaccurately,itisalwaysimportanttochecktheresultsatyourdestination.
AppendixA:AQuickReferenceGuidetoSASDate,Time,andDatetimeFormats
Thistableshowstheresultwhenthesamedate,time,ordatetimevalueisdisplayedwiththecorrespondingformat,usingthedefaultlengthforthegivenformat.
ThereferencedateforthistableisThursday,September18,2014.
IfYouWantYourDatetoLookLikeThis
UseThisFormat
18SEP14 DATE.
18 DAY.
18/09/14 DDMMYY.
180914 DDMMYYB.
18:09:14 DDMMYYC.
18-09-14 DDMMYYD.
18092014 DDMMYYN.
18.09.14 DDMMYYP.
18/09/14 DDMMYYS.
Thursday DOWNAME.
261 JULDAY.
14261 JULIAN.
09/18/14 MMDDYY.
091814 MMDDYYB.
09:18:14 MMDDYYC.
09-18-14 MMDDYYD.
09182014 MMDDYYN.
09.18.14 MMDDYYP.
09/18/14 MMDDYYS.
09M2014 MMYY.
09:2014 MMYYC.
09-2014 MMYYD.
092014 MMYYN.
09.2014 MMYYP.
09/2014 MMYYS.
September MONNAME.
9 MONTH.
SEP14 MONYY.
3 QTR.
III QTRR.
Thursday,September18,2014
WEEKDATE.
Thursday,18September2014
WEEKDATX.
5 WEEKDAY.
2014-W37-05
WEEKU.
2014-W38-04
WEEKV.
2014-W37-04
WEEKW.
September18,2014
WORDDATE.
18September2014
WORDDATX.
2014 YEAR.
2014M09 YYMM.
2014:09 YYMMC.
2014-09 YYMMD.
14-09-18 YYMMDD.
140918 YYMMDDB.
14:09:18 YYMMDDC.
14-09-18 YYMMDDD.
20140918 YYMMDDN.
14.09.18 YYMMDDP.
14/09/18 YYMMDDS.
201409 YYMMN.
2014.09 YYMMP.
2014/09 YYMMS.
2014SEP YYMON.
2014Q3 YYQ.
2014:3 YYQC.
2014-3 YYQD.
20143 YYQN.
2014.3 YYQP.
2014QIII YYQR.
2014:III YYQRC.
2014-III YYQRD.
2014III YYQRN.
2014.III YYQRP.
2014/III YYQRS.
2014/3 YYQS.
2014W37 YYWEEKU.
2014W38 YYWEEKV.
2014W37 YYWEEKW.
Thereferencetime
Thereferencetimeforthistableis2:45p.m.
IfYouWantYourTimetoLookLike UseThis
This Format
14:35 HHMM.
15 HOUR.
875 MMSS.
14:35:00 TIME.
2:35:00PM
TIMEAMPM.
14:35:00 TOD.
Thereference
Thereferencedatetimeforthistableis7:20p.m.onFriday,December12,2014.
IfYouWantYourDatetimetoLookLikeThis
UseThisFormat
12DEC14:07:20:00PM
DATEAMPM.
12DEC14:19:20:00 DATETIME.
12DEC14 DTDATE.
DEC14 DTMONYY.
Friday,12December2014
DTWKDATX.
2014 DTYEAR.
14:4 DTYYQC.
12/12/20147:20PM
MDYAMPM.
AppendixB:AQuickReferenceGuidetoNLSDate,Time,andDatetimeFormats
Thistableshowstheresultwhenthesamedate,time,ordatetimevalueisdisplayedwiththecorrespondingformat,usingthedefaultlengthforthegivenformat.
ThereferencedateforthistableisMonday,July7,2014.
FormatName OPTIONSLOCALE=
'English_UnitedStates'
NLDATE. July07,2014
NLDATEL. July7,2014
NLDATEM. Jul7,2014
NLDATEMD. July07
NLDATEMDL. July07
NLDATEMDM. Jul07
NLDATEMDS. 07/07
NLDATEMN. July
NLDATES. 07/07/2014
NLDATEW. Monday,July7,2014
NLDATEWN. Monday
NLDATEYM. July2014
NLDATEYML. July2014
NLDATEYMM. Jul2014
NLDATEYMS. 07/2014
NLDATEYQ. 3rdquarter2014
NLDATEYQL. 3rdquarter2014
NLDATEYQM. Q32014
NLDATEYQS. 2014/3
NLDATEYR. 2014
NLDATEYW. Week272014
➊-TheRussiantextistoolongforthedefaultformatwidth.
Thereferencetimeforthistableis11:20.
FormatName
OPTIONSLOCALE=
'English_UnitedStates'
NLTIMAP. 11:20AM
NLTIME. 11:20:00
ThereferencedatetimeforthistableisSaturday,September27,2014,05:45:00p.m.
FormatName OPTIONSLOCALE='English_UnitedStates'
NLDATM. 27Sep2014:17:45:00
NLDATMAP. September27,201405:45:00PM
NLDATMDT. September27,2014
NLDATML. September27,201405:45:00PM
NLDATMM. Sep27,201405:45:00PM
NLDATMMD. September27
NLDATMMDL. September27
NLDATMMDM. Sep27
NLDATMMDS. 09/27
NLDATMMN. September
NLDATMS. 09/27/201417:45:00
NLDATMTM. 17:45:00
NLDATMTZ. 17:45:00-0500
NLDATMW. Saturday,September
27,201405:45:00PM
NLDATMWN. Saturday
NLDATMWZ. Sat,Sep27,201405:45:00PM-0500
NLDATMYM. September2014
NLDATMYML. September2014
NLDATMYMM. Sep2014
NLDATMYMS. 09/2014
NLDATMYQ. 3rdquarter2014
NLDATMYQL. 3rdquarter2014
NLDATMYQM. Q32014
NLDATMYQS. 2014/3
NLDATMYR. 2014
NLDATMYW. Week382014
NLDATMZ. 27Sep2014:17:45:00-0500
➊-TheRussiantextistoolongforthedefaultformatwidth.
AppendixC:TroubleshootingDates101ThisappendixisintendedtobeaquicksolutionsguideforsomeofthemostcommonissuespeoplehavewithdatesandSAS.Ihopetokeepthe
discussiongoingonline,becausepeopleoftenremarktomehowdifficultdatesareinSAS,andtheyshouldn'tbe.Youcanfindoutmoreaboutthistroubleshootingprojectontheauthorpageforthisbook.Again,theseareintendedtobesimplesolutionstocommon
beginner'squestions.
Everypersonexperiencingaproblemwithdates,times,ordatetimesshouldimmediatelychecktoseeiftheyareworkingwithcharactervaluesornumericvalues.YoucandothisbyusingPROCCONTENTS,bylookingatthe
propertiesintheExplorerwindowininteractiveSAS,orbyusingtheDataSetAttributesTask(underTasks→Data)inSASEnterpriseGuide.UnlessyouareworkingwithISO8601durationsandintervals,youshouldbeworkingwithnumericvalues.Ifnot,thenthefirststep
youshouldtakeistoconvertthatcharactervalueintoaproperSASdate,time,ordatetimevalue.
Question1:HowdoIconvertmycharactervalueintoaSASdate,time,ordatetimevalue?
Case1:Ifyouare
readingaflatfile(CSV,tab-delimited,andsoon),youwillneedtousetheINPUTstatementwiththeappropriatedate,time,ordatetimeinformat.
SampleCodeOPTIONSDATESTYLE=MDY;DATAconvert_char;INFILE'char_dates.txt'
PADMISSOVER;INPUTid$date1:mmddyy10.date2:date9.date3:anydtdte.;RUN;
DataFile'char_dates.txt'
10104/17/201206dec20150627201410209/29/201415JUN201309feb201410311/12/20133mar201508/19/2015
Whenyouruntheprogramwiththedataabove,youwillgetthefollowingdataset.ThedatevariableshaveintentionallybeenleftunformattedsoyoucanseethatthedataintheflatfilehasbeenturnedintoSASdatevalues.TheANYDTDTE.informatwasusedtoreadintheDATE3
variabletodemonstratehowitcanbeusedifyoudon'tknowwhatyourcharacterdateslooklike,oriftheyareindifferentdateforms.Chapter3containsdetaileddescriptionsoftheinformatsthatyoucanuseinconjunctionwiththeINPUTstatement.
TheResultingDataSet
Case2:IfyoualreadyhaveyourdatainaSASdataset,thenyouwillhavetousetheINPUTfunctiontotranslateyourcharacterdatesinto
SASdates.
Hereisthedatasetwehavewithcharacterdates:
CodetoConvertCharacterDateValuesintoSASDateValues
1.OPTIONSDATESTYLE=MDY;
2.DATAfix_char;3.setalready_char;4.num_date1=INPUT(date1,mmddyy10.);5.num_date2=INPUT(date2,date9.);6.num_date3=INPUT(date3,anydtdte11.);7.RUN;
TheINPUTfunctionisusedinlines4,5,and6tocreatethenewvariablesnum_date1,num_date2,and
num_date3.Thereasonwearecreatingnewvariablesisthatyoucannotchangeanexistingvariablefromcharactertonumeric,soyoucannotusethevariablenamesdate1,date2,ordate3becausetheyexistinthedatasetALREADY_CHAR.TheINPUTfunctionusestheinformats
detailedinChapter3,justliketheINPUTstatement.
TheResultingDataSet
Ingeneral,whenyouaredealingwithSASdates,times,anddatetimes,youshould
beworkingwithnumericvariables.TheexceptiontothisruleisISOdurationsandintervals,whichiscoveredinChapter4.
Question2:WhydoIgetthelogmessage"Variablexxxxxxhasbeendefinedasbothcharacterandnumeric"?
YouaretryingtoconvertacharactervariableintoaSASdate,butyou'reusingthesamevariablenameintheINPUTfunctionandfortheresult.
date=INPUT(date,mmddyy10.);
Instead,youmustuseadifferentvariablename
tostoretheresultoftheINPUTfunction.
new_date=INPUT(date,mmddyy10.);
Question3:WhydoIgetthelogmessage"NOTE:InvalidargumenttofunctionINPUT"whenItrytousetheINPUTfunctiontoconverta
characterdateintoaSASdate?
Youareusingthewronginformatforthecharactersyouareconverting.Asanexample,ifyourcharactervalueslooklike"04MAY2015,"you'llgetthiserrorifyoudon’tusetheDATE.(orANYDTDTE.)
informat.
Quickestfix:Useoneofthe"ANYDATE"informats.ReadSection3.4.4fordetailsandthepossiblepitfallsofthisstrategy.
Bestfix:Findthecorrectinformatthatfitsthecharacterstringyou'reconverting.
Question4:WhydoIgeterrorswhenIamreadingaflatfilewithdates,andIknowI'musingthecorrectinformat?
Thisismostoftenanissueofnotreadingenoughcharactersinthefield,orofreadingtoomany.
Bestfix:Makesureyouspecifythecorrectlengthonyourinformat,andusethecolon(:)modifierforyourinformat(seeExample3.2).
Question5:Whydoesn'tmydatecomparisonwork?
Thisisgenerallya
problemwhenyouareimportingdatafromanotherdatabase.First,ensurethatthevariablesyouareworkingwitharenumeric.Second,manydatabasesstoretheirdatesasdatetimevalues,soevenifusingdatesworksinthedatabase,itwillnotworkwhenyoutryto
comparethatwithaSASdatevalue.
Bestfix:Onceyou'veverifiedthatyourdataaren'tcharacter,tryusingtheDATEPART()function(Table5.3)onthevariableyou'veimportedandcomparethatwithyourSASdate.
Question6:Mydatevalueslookright,sowhycan'tgetImydatecomparisontowork?
Thisfrequentlymeansthatoneofyourvaluesischaracter.RemovingformatsfromaSASdatevalueisagoodwaytomakesurethatyou'vegotaSASdate
value.Asanexample,ifthedateisin2014,itshouldbeanumberbetween19724and20088.
Question7:HowcanIsubsetmydatabeforeorafteraspecificdate/time/datetime?
Youhavetouseadateliteralsuchas
'01JAN2014'd,atimeliteralsuchas'14:00't,oradatetimeliteralsuchas'17OCT2014:07:00'dt.
DATAjunestock;SETsashelp.citiday;WHEREdateBETWEEN'01JUN1988'dAND'30JUN1988'd;RUN;
Thisisonewayto
createasubsetofdataforJune1998fromthedatasetSASHELP.CITIDAY.However,don'tlettheformatofthedatefoolyou.Here'sthesamemethodappliedtothedatasetSASHELP.CITIMON.
DATAstock8081;SETsashelp.citimon;
WHEREdateBETWEEN'01JAN1980'dAND'31DEC1981'd;RUN;
Eventhoughthedatesaremonthly,theyarestillSASdates,soyouhavetospecifytheboundariesascompleteSASdates,notjustamonthandyear.
Question8:HowdoI
getadatefromadateandtime?
UsetheDATEPART()functionafteryou'veconvertedittoaSASdatetimevalue.Ifyoujustneedthetime,usetheTIMEPART()function.Thisexampletakesadatetimevalueandseparatesitintodateandtime,
formattedandunformattedversions.
DATAdate_from_datetime;datetime='8APR2014:16:00'dt;fmt_datetime=datetime;date=DATEPART(datetime);fmt_date=date;time=TIMEPART(datetime);fmt_time=time;FORMATfmt_datetimemdyampm21.fmt_datemmddyy10.fmt_time
timeampm.;RUN;
PROCPRINTDATA=date_from_datetimeNOOBS;RUN;
datetime fmt_datetime
17125920004/8/20144:00PM
Question9:Whydo
mydateslooklikeabunchofnumbersthatdon'tmakeanysense,andhowcanIfixit?
Ifyourdatevaluelookslikeanumbersuchas16789,thenitisdisplayingasitsSASdate,andallyouneedtodoistoformatitusingoneofthedate
formatsinAppendixA,orifyouneedoneoftheNLSformatstotranslatethedateintoalanguageotherthanEnglish,seeSection6.4andAppendixB.
Question9a:IformattedmydateandnowallIgetisabunchofasterisks(************).What's
wrong?
IfyourunformattedSASvalueismorethan7digitslong,oryou'veusedadateformatandyougetasterisks,youprobablyhaveadatetimevalue,andyouneedtouseadatetimeformat.SeeAppendixAforthequicklist.
Question10:Mydatelookslike"06/25/2014,"butIneedtomakeitlooklike"2014/06/25."Iknowit'saSASdatevalueinthedataset,sohowdoIchangeit?
UsetheFORMATstatement.Itdoesnotmatterwhatformatthe
variablehasassociatedwithitinthedataset.AslongasitisaSASdate,time,ordatetimevalue,youcanchangethedisplaybychangingtheformatintheprocedurewhereyouaredisplayingthevariable.However,ifyougetanerrormessagealongthelinesof"Format$...not
found,"thedollarsign($)istellingyouthatthevariableyouaretryingtoformatisacharactervariable.InthatcaseyouwillhavetoconvertittothecorrespondingSASvalue.
Let'sprintoutsomerecordsfromadatasetusingthiscode:
ODSRTFFILE="apxc_10.rtf";PROCPRINTDATA=book.dailysales(OBS=5);VARdate;RUN;
Obs date
1 22MAY2014
2 23MAY2014
3 24MAY2014
4 25MAY2014
5 26MAY2014
WhatyouseeinthedatecolumnisjustaSASdatethathasbeenassociatedwiththeDATE9.formatwhenthedatasetwascreated,sowithoutanyFORMATstatementin
thePRINTprocedure,thatiswhatitlookslike.Nowwe'lladdaFORMATstatement.
1PROCPRINTDATA=book.dailysales(OBS=5);2VARdate;3FORMATdateyymmdds10.;4RUN;
Obs date
1 2014/05/22
2 2014/05/23
3 2014/05/24
4 2014/05/25
5 2014/05/26
Andthat'showyouchangethewayadate,time,ordatetimelooksinoutputfromits
defaultformat.
Question11:Mydateisnumeric,like20140815.HowdoIgetittodisplayas08/15/2014?
Thisisusuallytheresultofanimportthatwentwrong.First,makesurethatitreallyisthenumber
20,140,815.Ifthisistrue,thenyoucanturnthatnumberintoacharacterstringwiththePUTfunctionandconvertittoadatevaluelikeyoudowithanyothercharacterdatestring.Here'soneway:
DATAc11;bad_date=20140815;
char_date=PUT(bad_date,10.);SAS_date=INPUT(STRIP(char_date),yymmdd8.);fmt_SAS_date=SAS_date;FORMATfmt_SAS_dateweekdate.;RUN;
PROCPRINTDATA=c11NOOBS;RUN;
bad_date char_date
20140815 20140815
Question12:HowcanIdisplayjustthemonthandyear,whenIhavemonth,day,andyear?
Bydefinition,SASdatesareaspecificday
inaspecificmonthduringaspecificyear,soyoucan'tjustdeletethedayandstorethemonthandyear.Ifyouwanttodisplaythevalueasonlyamonthandayear,thenjustuseaformatthatonlydisplaysthemonthandyear.
Question13:Howdo
Iconvertfromdatetimeformattodateformat?
Inordertoanswerthisquestion,youneedtoknowwhatyouwant.IfyouneedaSASdatevalue,thenyouneedtoconvertitfromsecondssincemidnight,January1,1960,todayssinceJanuary1,
1960,byusingtheDATEPARTfunction.Ifyoujustwantittodisplaylikeadate,anddon'tneedorwanttheextravariableinyourdataset,thenyoucanuseaformat.SeeAppendixAfortheavailableSASdatetimeformatsandtheoutputtheyproduce.
DATAq12;datetime='31AUG2014:10:15'dt;fmt_datetime=datetime;date_from_datetime=DATEPART(datetime);fmt_date=date_from_datetime;FORMATfmt_datetimedtwkdatx.fmt_dateweekdatx.;RUN;
PROCPRINTDATA=q12NOOBS;RUN;
NotethedifferenceintheactualSASvalues.Eventhoughtheformattedvaluesareidentical,thevariabledatetimeisaSASdatetimevalue,whilethevariabledate_from_datetimeisaSASdatevaluecreatedwiththeDATEPARTfunction.
datetime fmt_datetime
1725099300Sunday,31August2014
Question14:Ican'tfindaSASformattomakemydate/time/datetime
lookthewayIwant.OR:Ineedtooutputmydatesoitlookslike…
First,checkAppendixAandtheSASdocumentationtoseeifyoucanfindaformatthatmatchesyourneeds.Ifnot,thenusetheFORMATprocedurewiththePICTURE
statement.Section2.7ofthebookprovidesallthedetailsyouneedtocreateacustomformat,includingtheSASdatedirectivesthattellSASwhatyouwantyourdate,time,ordatetimetolooklike.Don'tworrythatyoumaybeduplicatinganexistingSASformat;thatwillnotcauseaproblemas
longasyoudonotusethesamenameasaSAS-suppliedformat.Youwillseeanoteinthelog,andyourcustomformatwillnotbecreated.
Question15:HowcanIreadadate/time/datetimeformattedlike…?
Thesimpleansweristouseoneofthe"ANYDATE"informats.Don'tforgetabouttheDATESTYLE=systemoption,andcheckyourresultscarefullybeforeusingthem.The"ANYDATE"informatsareeasy,buttheycanbefooled,evenwhenfour-digityearsareused.SeeSection3.4.4
fordetails.
Question16:HowcanIconvertaUTCtimevaluetoaspecifictimezone?
Ifyour"timevalue"isadatetime,usetheTZONEU2S()function.ThischangestheSASvalue,sodon'toverwriteyouroriginal
valueunlessthisiswhatyouwanttodo.Ifyouhavejustatimevalue,youwillneedtogettheoffsetviatheTZONEOFF()function,whichwillreturntheoffsetfromGMTforthetimezoneyousupply.
DATAq16;datetime="26MAR2014:11:47:00"dt;gmt_datetime=
TZONES2U(datetime);RUN;
PROCPRINTDATA=q16NOOBS;FORMATdatetimegmt_datetimemdyampm21.;RUN;
datetime gmt_datetime
3/26/201411:47AM
3/26/20144:47PM
Question17:HowcanImakeasingledatevariablefromseparatemonth,day,andyear?
TheMDYfunctionwillletyousupplyanumericmonth,day,andyear,anditwillcalculatetheSASdatevalue.Youseethisoftenwhenreading
Excelfiles,wherethemonth,day,andyearareinseparatecolumns.We'llusein-streamcomma-separateddatainsteadofanExcelfilefortheexample.
1DATAQ17;2INFILEDATALINESDLM=',';3INPUTmonthdayyear;4SAS_date=
MDY(month,day,year);5fmt_date=SAS_date;6FORMATfmt_datemmddyyd10.;7DATALINES;82,15,201399,6,20141012,17,2013115,22,201412;;;;13RUN;
14PROCPRINTDATA=q17NOOBS;15RUN;
TheSAS_datecolumnshowstheSASdatevalueresultingfromtheuseoftheMDYfunctioninline4.
month day year SAS_date
2 15 2013 19404
9 6 2014 19972
12 17 2013 19709
5 22 2014 19865
Question18:Ihaveadateandatime.HowcanImakeaSASdatetimefromthem?
ThisoccurswhenyouimportdataintoSASandthedateisinonecolumnandthetimeisinanother.TheDHMS()functioniswhatisusedtocreatedatetimesfromdatesandtimes.Althoughyoumightthinkthatyouhavetobreakthetimevalueintohours,minutes,andseconds
tousethefunction,rememberthatSAStimesaremaintainedinsecondssincemidnight,soyoucanleavehoursandminutessettozeroandputthetimevariableintothesecondsparameter.Wewillusein-streamdatafortheexample.Payattentiontoline3.Thisishowyoucreatea
datetimefromaSASdateandaSAStime.
1DATAq18;2INPUTdate:yymmdd10.time:time.;3datetime=DHMS(date,0,0,time);4fmt_date=date;5fmt_time=time;6fmt_datetime=datetime;7FORMATfmt_datemmddyy10.fmt_timetimeampm.fmt_datetimemdyampm21.;
8DATALINES;92014-8-175:45102014-03-119:06112015-02-2715:43122014-12-1310:0013;14RUN;
15ODSRTFFILE='apxc_18.rtf';16PROCPRINTDATA=q18NOOBS;17RUN;
dateandtimearethe
SASvaluesasreadfromthedata,anddatetimeistheSASvaluecreatedinline3oftheabovecode.Wehavecreatedduplicatevariablesforformatting.
date time datetime
19952 20700 1723873500
19793 32760 1710147960
20146 56580 1740670980
20070 36000 1734084000
Question19:HowcanIcalculatethenumberofdaysbetweentwodates?
Therearemultiplewaystocalculatethedifferencebetweentwodates,times,ordatetimesinSAS.Thisisoneofthebestthingsabouthavingthemrepresentedas
numbers.Thesimplestwaytofindthedifferenceistosubtractonedatefromanother.Itisimportantthatyoumakesurethatyouaresubtractingdatesfromdates,timesfromtimes,anddatetimesfromdatetimes.
Question20:HowdoIconvertanumeric
SASdatevalueintocharacterformat?
Thefirstquestionyoushouldaskyourselfiswhy.FormattingtheSASdatevaluewillgiveyouthedisplayyouwant.Evenwhenyouareexportingtoothersoftware,aslongasyouputthedateintoaformthattheother
softwareunderstands,itshouldworkfine.Youdon'tneedtodothecharacterconversion,andyouwillnotbeabletodoanycalculationswiththatcharactervariable.TheonlytimethatIwouldconvertadatevalueintoacharactervalueiswhenIneedtoputthedateinsideofa
longstringoftextsuchas,"ThesubjectstartedthetrialonJanuary15,2012,andmasteredtaskAwithin15minutes."Itdoesn'tmatterifaformatispermanentlyassociatedwiththedatevariableorwhatitlookslikewhenyoulookatthedataset;rememberthatyoucanchangethe
wayadateisdisplayedinanyprocedurewhereyoucanuseaFORMATstatement.
Here'sadatasetwithavariablethathasbeenformattedwiththeWORDDATX.format.ThismeansthatanytimethevariableDATEisdisplayedinaSASprocedure,itwill
bedisplayedwiththeWORDDATX.formatasshownbelow.
Now,let'srunaPROCPRINT,butIwantto
showthedateasDD-MMM-YYYY,soIusetheFORMATstatementtochangethedisplayforthisrun:
PROCPRINTDATA=q20NOOBS;FORMATdatedate10.;RUN;
FormattedwithDATE10.
date
30JUN2014
18SEP2014
14MAR2014
18JUL2014
26APR2014
WhatifyouwanttoseeitasYYYY-MM-DD?
PROCPRINTDATA=q20NOOBS;FORMATdateyymmddd10.;RUN;
FormattedwithYYMMDDD10.(forcestheseparatortobethedash)
date
2014-06-30
2014-09-18
2014-03-14
2014-07-18
2014-04-26
ButwhenweremovealltheformatsbyusingaFORMATstatementwithoutaformatname,weseetheactualSAS
datevalue:
PROCPRINTDATA=q20NOOBS;FORMATdate;RUN;
FormatRemoved
date
19904
19984
19796
19922
19839
IfyoustillwanttoconvertyourSASdateintoacharactervalue,thenyoucanusethePUTfunction.Line2isaprecautiontomakesurethatthecharacter
variableislongenoughtoholdthelongestvalue.Notethatyouhavetouseadifferentnameforthecharactervariableyoucreateinline4.
1.DATAq20_plus;2.LENGTHchardate$31;3.SETq20;4.chardate=PUT(date,weekdate.);5.RUN;
chardate date
Monday,June30,2014
19904
Thursday,September18,2014
19984
Friday,March14,2014
19796
Friday,July18,2014
19922
Saturday,April26,2014
19839
IndexSymbolsandNumerics&(ampersand)192=(equalssign)207$(dollarsign)61%%datedirective49
A%adatedirective49%Adatedirective49AFRlanguageprefix214ampersand(&)192
ANYDTDTEw.informat82–83ANYDTDTMw.informatand84–85ANYDTTMEw.informatand85–86DATESTYLE=systemoptionand81,82–83,85–86troubleshooting239
ANYDTDTMw.informat81,84–85automaticmacrovariables186–189
B
%bdatedirective49%Bdatedirective49B8601CIw.dinformat78,108B8601DAw.format93B8601DAw.informat104B8601DJw.dinformat79,108B8601DNw.format99B8601DTw.dformat99–100B8601DTw.dinformat109B8601DXw.dformat100–101B8601DZw.dformat102B8601DZw.dinformat110B8601LZw.dformat96B8601TMw.dformat94
B8601TMw.dinformat105B8601TXw.dformat94–95B8601TZw.dformat97–98B8601TZw.dinformat105–106
CcalculationsINTCK()functionand151–156INTNX()functionand156–159numberofdaysbetweendates145–149numberofyearsbetween
dates146–147CALLIS8601_CONVERT123–136CALLSYMGET()function192–193CALLSYMPUT()function192–193casesensitivity48–49CATlanguageprefix214CATS()function14CATT()function14
CATX()function14characterconstants61
characterstringsDATETIMEinformatand63PUT()functionand55–56
charactervariablesINPUT()functionand61–62INPUTC()function61–62PUT()functionand55–56PUTN()functionand55–56
COMPRESS()function14constants,dateandtimeas3–5CONVERTstatement,EXPANDprocedureconvertingtohigherfrequency202–203METHOD=option206
OBSERVED=option206–212
CROlanguageprefix214CSYlanguageprefix214
D%ddatedirective49,51DANlanguageprefix214DATAstepFORMATstatement10–137%LETstatementand191,192
DATADIF()function145–146DATALINESstatement61
DATATYPE=option48,51datedirectives,pictureformat50DATE()function187–188&DATEmacrovariable187–188DATEsystemoption7DATEAMPMw.dformat42–43,233DATEPART()function140datetimeformatsand41–42troubleshooting241,242–243,245
datesautomaticmacrovariables
186–189CALLSYMPUT()functionand192–193asconstants3–5countersfor1creatingcharacterstrings55–56customformats47–55datetimevaluesand13–14,41–42defaultjustification13Exceland227–228externalrepresentationof2–3formatsfor14–37,92–103
graphing194–200Hebrewformats226informatsfor59,61,64–73,81–86,103–111internalrepresentationof2internationalformatsandinformats212–220intervaldefinitions149–151intervalfunctions151–159Japaneseformats226Japaneseinformats226–227quickreference231–233,235–237shiftingintervals159–168%SYSFUNC()macro
functionand187–189Taiwaneseformats226Taiwaneseinformats226–227intitles186–187troubleshooting239–251widthspecification5–6,13YEARCUTOFF=systemoptionand57–59
DATESTYLE=systemoptionANYDTDTEw.informatand82–83,85–86ANYDTDTMw.informatand84LOCALE=systemoption
and212missingvaluesexample81troubleshooting246
DATESTYLE=DMYsystemoption81–82DATESTYLE=LOCALEsystemoption81DATESTYLE=MDYsystemoption81–82DATESTYLE=YMDsystemoption81–82DATETIME()function138datetimevaluesautomaticmacrovariablesand186–189
CALLSYMPUT()functionand192–193asconstants3–5customformats47–55dateformatsand13–14,41–42defaultjustification13Exceland227–228externalrepresentationof2–3formatsfor41–46,99–103informatsfor61,78–81,81–82,108–111internalrepresentationof2internationalformatsand
informats212–220intervaldefinitions150–151intervalfunctions151–159quickreference234,235–237shiftingintervals159–1682%SYSFUNC()macrofunctionand187–189widthspecification5–6,37,41–42YEARCUTOFF=systemoptionand57–59
DATETIMEw.informatANYDTDTEw.informatand82
ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86characterstringsand63
DATETIMEw.dformat43–44,79,213,233DATEw.format15DTDATEw.formatand44internationalformatfor213quickreference231
DATEw.informat64ANYDTDTEw.informat82ANYDTDTMw.informat84ANYDTTMEw.informat85–
86DATJUL()function140–141DAY()function138DAYinterval150INTCK()function152INTNX()function158shiftpoint160
DAYw.format15,231DB2databases227–228DDMMYYB.format17,231DDMMYYC.format17,231DDMMYYD.format17,231DDMMYYN.format231DDMMYYP.format17,231
DDMMYYS.format231DDMMYYw.format15–16,30–31internationalformatfor213quickreference231YYMMDDw.formatand30–31
DDMMYYw.informat64–65ANYDTDTEw.informatand82ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86DATASTYLE=system
option81–82DDMMYYxw.format16–17MMYYxw.formatand20YYMMxw.formatand30YYQxw.formatand33–34
DESlanguageprefix214DEUlanguageprefix214DFLANG=systemoption212DHMS()function141–142,247–248dollarsign($)61dot(.)Seeperiod
DOWNAMEw.format17
internationalformatfor213quickreference231
DTDATE9.format44DTDATEw.format44DATEwformatand15quickreference233
DTDAYinterval150INTCK()function155INTNX()function158shiftpoint160
DTHOURinterval151,161DTMINUTEinterval151,161DTMONTHinterval151INTNX()function158
shiftpoint161DTMONYYw.format44MONYYw.formatand21quickreference233
DTQTRinterval151INTNX()function157,158shiftpoint161
DTRESETsystemoption7DTSECONDinterval151,161DTSEMIMONTHinterval151INTNX()function158shiftpoint161
DTSEMIYEARinterval151INTNX()function157,158
shiftpoint161DTTENDAYinterval151INTNX()function158shiftpoint161
DTWEEKinterval150INTNX()function157shiftpoint161
DTWEEKDAYinterval151INTNX()function157shiftpoint161
DTWKDATXw.format45quickreference233
DTYEARinterval151INTNX()function157,158
shiftpoint161DTYEARw.format45,233DTYYQCw.format46,233durations,ISO8601116–136
EE8601DAw.format93E8601DAw.informat104E8601DNw.format99E8601DTw.dformat100E8601DTw.dinformat109–110E8601DXw.dformat101–102E8601DZw.dformat102–103E8601DZw.dinformat110–111
E8601LZw.dformat96–97E8601LZw.dinformat107E8601TMw.dformat94E8601TMw.dinformat105E8601TXw.dformat95–96E8601TZw.dformat98–99E8601TZw.dinformat106–107equalssign(=)207_ERROR_automaticvariable6–63ESPlanguageprefix214"EUR"formats213–214"EUR"informats213–214EURDFDD.format213
EURDFDEw.format213EURDFDN.format213EURDFDTw.format213EURDFDWN.format213EURDFMN.format213EURDFMYw.format213EURDFWDX.format213EURDFWKX.format213Excel(Microsoft)227–228EXPANDprocedurecapabilities200–202CONVERTstatement206–212convertingtohigher
frequency202–203FROM=option206,209–212IDstatement204–205interpolatingmissingvalues205–206TO=option206,209–212
externalrepresentation,dateandtime2–3
F%Fdatedirective223FCMPprocedure52–55FINlanguageprefix214
FOOTNOTEstatement186FORMATprocedurePICTUREstatement47–52troubleshooting246VALUEstatement47–48
FORMATstatementdatedirectivesand50functionality10–13INFORMATstatementand59–60troubleshooting243–244
formats10–13,59custom47–55dateconstantsand4–5fordates14–37
fordatetime41–46datetimevalues99–103"EUR"213–214externalrepresentationofdate,timeand2–3graphingdatesand194–200Hebrew226ISO860192–103,117–121Japanese226"NLS"214–220PUT()functionand55–56quickreference231–233Taiwanese226fortime37–41usingwrong62–63
FRAlanguageprefix214FROM=option,EXPANDstatement206,209–212FRSlanguageprefix214FUNCTIONstatement52–55functionscalculatingintervals145–149creatingdate,time140–145currentdate,time137–138extraction138–140
Ggraphingdates194–200
GregorianyearJULIANw.informat65PDJULG4.informat66PDJULGw.informat22PDJULIw.format22PDJULIw.informat66
H%Hdatedirective49,223HDATEw.format226HEBDATEw.format226Hebrewdateformats226HHMMSSw.informat73–75HHMMw.dformat38,233
HMS()function143HOLIDAY()function148–149,170HOUR()function140HOURinterval151INTNX()function158shiftpoint161
HOURw.dformat38–39,233HUNlanguageprefix214
I%Idatedirective49,223IDstatement,EXPANDprocedure204–205
imputeddates52–55INFORMATstatement59–61,59–63informatsabout59ANYDTvariants81–86"EUR"213–214fordates64–73fordatetime78–81fordatetimevalues108–111fortime73–78Hebrew226INFORMATstatement59–63ISO8601103–111
ISO8601durationandinterval121–123JapaneseandTaiwanese226–227"NLS"220usingwrong62–63
INPUT()functionfunctionality3informatsand59,61–62troubleshooting240,241
INPUTstatement60–61INPUTC()function61–62INPUTN()function61–62INTCINDEX()function183INTCK()function159,161–162
calculatingintervals167–168WORKINGDAYSinterval175–176
INTCYCLE()function183internalrepresentation,dateandtime2intervalmultipliersgraphsand194–200shiftingintervalsand162–163
intervalsbasicsof149–151creating169–176custom162–163
INTCK()function151–156intervalfunctions176–181INTNX()function156–159ISO8601116–136measuring167–168numberofdaysbetweendates145–149numberofyearsbetweendates146–147retailcalendar181–183shifting159–168
INTFIT()function177–178INTFMT()function178–179INTGET()function179–180INTINDEX()function183
INTNX()function151,156–160,167–168INTSEAS()function183INTSHIFT()function180–181INTTEST()function181ISO860191–92durationsandintervals116–136formats92–103informats103–111
ITAlanguageprefix214
J%jdatedirective49,223
Japanesedateformats226Japanesedateinformats226–227JDATEMYDw.informat226–227Jewishcalendar226JNENGOW.informat227Joshi,Bhairav2JULDATE()function138JULDATE7()function138JULDAYw.format17–18,233JuliandateJULDATE()function138JULDATE7()function138
JULDAYw.format17–18JULIANw.format18JULIANw.informat65PDGJULI1.format23PDJULG.informat66PDJULG4.informat66PDJULGw.format22PDJULIw.format22–23PDJULIw.informat66
JULIANw.format231JULIANw.informat65ANYDTDTEw.informatand82ANYDTDTMw.informatand84
ANYDTTMEw.informatand85–86
justificationdateformats13–14PDJULIw.formatand22
KKanjirepresentation227
L%LEFT()macrofunction192LENGTHstatement5–6%LETstatement191,192LISTINGdestination13–14
literalvaluesquotationmarksand3YEARCUTOFF=systemoptionand57–59
LOCALE=systemoption111,214–215
M%mdatedirective49,223%Mdatedirective49MAClanguageprefix214macrofunctions,dateandtimein186–189macrovariables
CALLSYMPUT()functionand192–193datesand185–193quotationmarksand186
MAKEDATE()function52–55MDY()function143,247MDYAMPMw.format46,233MDYAMPMw.dinformat79–80METHOD=option,CONVERTstatement(EXPAND)206MicrosoftExcel227–228MINGUOw.format226MINGUOw.informat227MINUTE()function140
MINUTEinterval151INTNX()function158shiftpoint161
missingvaluesDATESTYLE=systemoption81EXPANDprocedureand205–206symbolfor50wronginformatsand62–63
MMDDYw.format18MMDDYYxw.formatand19quickreference231YYMMDDw.formatand30–31
MMDDYY10.format11–13,18MMDDYYB.format19,231MMDDYYC.format19,231MMDDYYD.format231MMDDYYN.format231MMDDYYP.format19,231MMDDYYS.format231MMDDYYw.informat65–66ANYDTDTEw.informatand82ANYDTDTMw.informatand84DATESTYLE=systemoptionand81–82
MMDDYYxw.format19MMYYxw.formatand20YYMMxw.formatand30YYQxw.formatand33–34
MMSSw.dformat39,233MMYYC.format20,231MMYYD.format20,231MMYYN.format20,232MMYYP.format20,232MMYYS.format232MMYYw.format19–20,231MMYYxw.format20MONNAMEw.format14,21internationalformatfor213
quickreference232MONTH()function138MONTHinterval150example202–203INTCK()function152INTNX()function158shiftpoint160,165–166
MONTHw.format21,232MONYYw.format21DTMONYYw.formatand44internationalformatfor213quickreference232
MONYYw.informat66ANYDTDTEw.informatand82
ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86explanationof66
MSEC8.informat76
N$N8601BAw.dformat119$N8601Bw.informat121–122$N8601Bw.dformat118$N8601EAw.format120$N8601EHw.format120$N8601Ew.format119
$N8601EXw.format121$N8601Rw.informat122–123NationalLanguageSupport(NLS)111,212NENGOw.format227NLDlanguageprefix214NLDATE.format235NLDATE()function221–225NLDATEL.format215,235NLDATEM.format235NLDATEMD.format215,235NLDATEMDL.format215,235NLDATEMDM.format216,235NLDATEMDS.format216,235
NLDATEMDT.format217NLDATEML.format217NLDATEMN.format216,235NLDATES.format216,235NLDATEw.format215NLDATEW.format235NLDATEWN.format216,235NLDATEWw.format216NLDATEYM.format216,235NLDATEYML.format216,235NLDATEYMM.format216,235NLDATEYMS.format216,235NLDATEYQ.format216,235NLDATEYQL.format217,236
NLDATEYQM.format217,236NLDATEYQS.format217,236NLDATEYR.format217,236NLDATEYW.format217,236NLDATM()function221–225NLDATMAPw.format217NLDATMw.format215,217NLS(NationalLanguageSupport)111,212"NLS"formats214–220"NLS"informats220NLTIME.format236NLTIME()function221–225NLTIMEAP.format236
NODATEsystemoption7NORlanguageprefix214numericvariablesdate,timeas3–5functionsfrom140–145INPUT()functionand61–62LENGTHstatementand5–6
NWKDOM()function144,170
O%odatedirective223OBSERVED=option,CONVERTstatement(EXPAND)206–212
OBSERVED=AVERAGEoption,CONVERTstatement(EXPAND)207–212OBSERVED=BEGINNINGoption,CONVERTstatement(EXPAND)207–212OBSERVED=DERIVATIVEoption,CONVERTstatement(EXPAND)207–212OBSERVED=ENDoption,CONVERTstatement(EXPAND)207–212OBSERVED=MIDDLEoption,CONVERTstatement(EXPAND)207–212
OBSERVED=TOTALoption,CONVERTstatement(EXPAND)207–212ODSdestinations13–14,214–215OPTIONSINTERVALDS=statement169–176OPTIONSstatementDATE/NODATEsystemoption7LOCALE=systemoption212
OSTIMEmacro76,78OUTLIB=option52–55
P%pdatedirective49,223PDFdestination14PDJULG.informat66PDJULG4.informat66PDJULGw.format22PDJULI1.format23PDJULIw.format22–23PDJULIw.informat23,66PDTIME4.informat76period(.)formatsyntaxand16ininformats59
missingvaluesand50PICTUREstatement,FORMATprocedure47–52,246POLlanguageprefix214PRINTprocedure11–12PROCstep11PTGlanguageprefix214PUT()function14,17,28,55–56,61–62,221,244–245PUTN()function14,17,28,55–56
Q%QSYSFUNC()macrofunction
187QTR()function138QTRinterval150INTNX()function158shiftpoint160
QTRRw.format23–24,232QTRw.format23,232
R&RAWDATEmacrovariable187retailcalendarintervals181–183RMFDUR4.informat76
RMFSTAMP8.informat80RTFdestination14RUSlanguageprefix214
S%Sdatedirective49,223samplingfrequencyconvertingtohigher202–203convertingtolower203–205OBSERVED=optionand207–212
SASDATEFMT=systemoption
228–229SAS/ETS183,200SAS/GRAPH194–200seasonalityfunctions183SECOND()function140SECONDinterval151INTNX()function158shiftpoint161
SEMIMONTHinterval150INTNX()function158shiftpoint160
SEMIYEARinterval150INTNX()function158shiftpoint160
shiftoperators,intervalsand159–162SLOlanguageprefix214SMFSTAMP8.informat80SMRSTAMP8.informat80SQLprocedure193STIMERsystemoption76STIMERw.informat76–77STRIP()function14SVElanguageprefix214&SYSDATEautomaticmacrovariable185,187&SYSDATE9automaticmacrovariable186,187
&SYSDAYautomaticmacrovariable186,187%SYSFUNC()macrofunction187–189&SYSTIMEautomaticmacrovariable186,187
TTaiwanesedateformats226Taiwanesedateinformats226–227TENDAYinterval150INTNX()function158shiftpoint160
timeautomaticmacrovariables186–189CALLSYMPUT()functionand192–193asconstants3–5countersfor2customformats47–55defaultjustification13Exceland227–228externalrepresentationof2–3formatsfor37–41,92–103informatsfor73–78,81–82,103–111
internalrepresentationof2internationalformatsandinformats212–220intervaldefinitions150–151intervalfunctions151–159quickreference233,235–237shiftingintervals159–168%SYSFUNC()macrofunctionand187–189widthspecification5–6,37
TIME()function138timezonefunctions111–115TIMEAMPM11.format11–13TIMEAMPMw.dformat40
clockvaluesand37quickreference233
TIMEPART()function41–42,140troubleshooting242–243
TIMEw.informat77–78ANDTDTEw.informatand82ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86
TIMEw.dformat39–40HHMMw.dformatand38quickreference233
TIMEZONE=option93,111–112TITLEstatement186titles,datein186–187TO=option,EXPANDprocedure206,209–212TODAY()function137TODSTAMP8.informat78TODw.dformat40–41clockvaluesin37quickreference233
troubleshootingdates239–251TU4.informat78two-digityear
extractionfunctionsand138–140YEARCUTOFF=systemoptionsand57–59,79
TZONEDSTNAME()function114TZONEDSTOFF()function114TZONEID()function112TZONENAME()function112–113TZONEOFF()function113,246TZONES2U()function113TZONESTTNAME()function114–115TZONESTTOFF()function115
TZONEU2S()function115,246
UUalgorithm25,35,69,70,139%udatedirective223%Udatedirective49,223
VValgorithm26–27,36–37,69–71,139,223%Vdatedirective223VALUEstatement,FORMATprocedure47–48variables
Seecharactervariables;macrovariables;numericvariables
WWalgorithm27,37,69–72,139,223%wdatedirective49,223%Wdatedirective223WEEK()function139WEEKinformats69–70WEEKinterval150INTCK()function152INTNX()function157,159
shiftpoint160,161–162,163–164
WEEKDATEw.format11–12,24quickreference232WEEKDATXw.formatand24–25
WEEKDATXw.format24–25DTWKDATXw.formatand445internationalformatfor213–214quickreference232
WEEKDAY()function139WEEKDAYinterval150
INTNX()function157shiftpoint160
WEEKDAYw.format25internationalformatfor213quickreference232
WEEKUw.format25–26quickreference232
WEEKUw.informat70–71WEEKVinterval182–183WEEKVw.format26–27quickreference232WEEKWw.formatand27
WEEKVw.informat71–72WEEKWw.format27,232
WEEKWw.informat72–73WHEREclause,SQLprocedure228widthspecificationfordateformats5–6,13–14fordatetimeformats5–6,37,41–42fortimeformats5–6,37formatsand13–14informatsand59
WORDDATEw.format28FORMATstatementand50quickreference232
WORDDATXw.format28–29,249
internationalformatfor213quickreference232
WORKINGDAYSinterval175–176
Y%ydatedirective49,223%Ydatedirective49,51,223Y2Kproblem185YEAR()function139YEARinterval150INTCK()function152INTNX()function158shiftpoint160,161–162,
165–166YEAR10.interval166–167YEARCUTOFF=systemoptionDATJUL()functionand140–141extractionfunctionsand138–140Japanese/Taiwanesedateinformats226–227MDY()function143PDJULGw.formatand22PDJULI.format23two-digityearand57–59,79YYQ()function144–145
YEARVinterval182YEARw.format29DTYEARw.formatand45quickreference232
YMDDTTMw.dinformat80–81YRDIF()function146–147,155–159YYMM.format232YYMMC.format30,232YYMMD.format30,232YYMMDDB.format32,232YYMMDDC.format32,232YYMMDDD.format32,232YYMMDDN.format32,232
YYMMDDP.format32,232YYMMDDS.format232YYMMDDw.format30–31DATESTYLE=systemoption81–82quickreference232
YYMMDDw.informat66–67ANYDTDTEw.informatand82ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86DATESTYLE=systemoptionand81–82
YYMMDDxw.format31–32YYMMxw.formatand30YYQxw.formatand33–34
YYMMN.format30,232YYMMNw.informat67YYMMP.format30,232YYMMS.format232YYMMw.format29YYMMxw.format30YYMONw.format32,232YYQ()function144–145YYQC.format33DDTYQCw.formatand46quickreference233
YYQD.format34,233YYQN.format33,233YYQP.format34,233YYQRC.format35,233YYQRD.format35,233YYQRN.format35,233YYQRP.format35,233YYQRS.format233YYQRw.format34,233YYQRxw.format34–35YYQS.format233YYQw.format32–33,233YYQw.informat67–68ANYDTDTEw.informatand
82ANYDTDTMw.informatand84ANYDTTMEw.informatand85–86
YYQxw.format33–34YYWEEKU.format233YYWEEKUw.format35–36YYWEEKV.format233YYWEEKVw.format36YYWEEKWw.format37,233
TableofContents
1. AboutThisBook
2. Acknowledgments3. Chapter1:IntroductiontoDatesandTimesinSAS1. 1.1HowDoesItWork?(January1,1960,andMidnightasZero)
2. 1.2InternalRepresentation
3. 1.3ExternalRepresentation(BasicFORMAT
Concepts)4. 1.4DateandTimeasNumericConstantsinSAS
5. 1.5LengthandNumericRequirementsforDate,Time,andDatetime
6. 1.6GeneralSASOptionsforDates
4. Chapter2:DisplayingSASDate,Time,and
DatetimeValuesasDatesandTimesasWeKnowThem1. 2.1HowDoIUseaFormat?
2. 2.2HowManyBuilt-InFormatsAreThereforDatesandTimes?
3. 2.3DateFormats,Justification,andODS
4. 2.4Detailed
DiscussionofEachFormat1. 2.4.1DateFormats
2. 2.4.2TimeFormats
3. 2.4.3DatetimeFormats
5. 2.5CreatingCustomDateFormatsUsingtheVALUEStatement
ofPROCFORMAT
6. 2.6CreatingCustomDateFormatsUsingthePICTUREStatementofPROCFORMAT
7. 2.7CreatingCustomFormatsUsingPROCFCMPforProcessing
8. 2.8ThePUT()FunctionandFormats
5. Chapter3:ConvertingDatesandTimesintoSASDate,Time,andDatetimeValues1. 3.1AvoidingtheTwo-DigitYearTrap
2. 3.2UsingInformats
3. 3.3The
INFORMATStatement1. 3.3.1UsingInformatswiththeINPUTStatement
2. 3.3.2InformatswiththeINPUT()Function
3. 3.3.3When
theInformatDoesNotMatchtheDataBeingRead
4. 3.4ListingandDiscussionofInformats1. 3.4.1DateInformats
2. 3.4.2TimeInformats
3. 3.4.3
DatetimeInformats
4. 3.4.4The"ANYDATE"SeriesofInformats
5. 3.4.5SoWhyNotJustUsethe"ANYDATE"SeriesofInformats?
6. Chapter4:ISO8601
Dates,Times,Datetimes,Durations,andFunctions1. 4.1WhatIsISO8601?
2. 4.2ISO8601Formats1. 4.2.1ISODateFormats
2. 4.2.2ISOTimeFormats
3. 4.2.3ISO
DatetimeFormats
3. 4.3ISO8601Informats1. 4.3.1ISODateInformats
2. 4.3.2ISOTimeInformats
3. 4.3.3ISODatetimeInformats
4. 4.4TimeZoneFunctions1. 4.4.1Introduction
2. 4.4.2TheTIMEZONE=Option
3. 4.4.3ListofTimeZoneFunctions
5. 4.5ISO8601DurationsandIntervals
1. 4.5.1ISODurationandIntervalRepresentations
2. 4.5.2ISO8601DurationandIntervalFormats
3. 4.5.3ISO8601DurationandInterval
Informats4. 4.5.4CALLIS8601_CONVERT
6. 4.6Conclusion7. Chapter5:DateandTimeFunctions1. 5.1CurrentDateandTimeFunctions
2. 5.2ExtractingPiecesfromSASDate,Time,andDatetimeValues
3. 5.3CreatingDates,Times,andDatetimesfromNumbersorOtherInformation1. 5.3.1Introduction
2. 5.3.2ListofFunctionsandTheirDescriptions
4. 5.4CalculatingElapsedTime,
andtheHOLIDAY()Function1. 5.4.1CalculatingElapsedTimewithDATDIF()andYRDIF()
5. 5.5TheBasicsofSASIntervals1. 5.5.1TheInterval
CalculationFunctions:INTCK()andINTNX()
6. 5.6ModifyingSASIntervals
7. 5.7CreatingYourOwnSASIntervals
8. 5.8IntervalFunctionsaboutIntervals1. 5.8.1
INTFIT(argument-1,argument-2,type)
2. 5.8.2INTFMT('interval','size')
3. 5.8.3INTGET(argument1,argument2,argument3)
4. 5.8.4INTSHIFT('interval')
5. 5.8.5INTTEST('interval')
9. 5.9RetailCalendarIntervals
andSeasonality1. 5.9.1RetailCalendarIntervals
2. 5.9.2SeasonalityFunctions
8. Chapter6DeeperintoDatesandTimeswithSAS1. 6.1MacroVariablesandDates
1. 6.1.1AutomaticMacroVariables
2. 6.1.2PuttingDatesintoTitles
3. 6.1.3Using%SYSFUNC()toCreateDates,Times,andDatetimesin
MacroVariables
4. 6.1.4UsingDatesinMacros
2. 6.2GraphingDates1. Johnny'sSavingsAccount
3. 6.3TheBasicsofPROCEXPAND1. 6.3.1
CapabilitiesofPROCEXPAND
2. 6.3.2UsingPROCEXPANDtoConverttoaHigherFrequency
3. 6.3.3UsingPROCEXPANDtoConverttoa
LowerFrequency
4. 6.3.4UsingPROCEXPANDtoInterpolateMissingValues
5. 6.3.5TheOBSERVED=OptionfortheCONVERT
StatementinPROCEXPAND
4. 6.4InternationalDate,Time,andDatetimeFormatsandInformats1. 6.4.1"EUR"FormatsandInformats
2. 6.4.2NLSFormats
5. 6.5NLSDate,
Time,andDatetimeConversionFunctions
6. 6.6DateFormatsandInformatsforOtherCalendars1. 6.6.1HebrewDateFormats
2. 6.6.2JapaneseandTaiwaneseDateFormats
3. 6.6.3JapaneseandTaiwaneseDateInformats
7. 6.7OtherSoftwareandTheirDates(Excel,Oracle,DB2)1. 6.7.1TheSASDATEFMT=System
Option8. 6.8Conclusion
9. AppendixA:AQuickReferenceGuidetoSASDate,Time,andDatetimeFormats
10. AppendixB:AQuickReferenceGuidetoNLSDate,Time,andDatetimeFormats
11. AppendixC:TroubleshootingDates101
12. Index