BookmarkSubscribeRSS Feed
Caetreviop543
Obsidian | Level 7

Is it possible to convert mm/dd/yyyy hh:mm:ss AM/PM (e.g., 10/15/2008 12:00:00 AM) to a numeric date time variable using input, or do I have to remove AM/PM? What informat would it require? I tried MDYAMPM., but it didn't work.

 

 

16 REPLIES 16
ChrisNZ
Tourmaline | Level 20

If you want a SAS datetime, you can use

 DTM=input('10/15/2008 12:00:00 PM',anydtdtm32.);
 

AnandsinhSindha
Obsidian | Level 7

You can use "ANYDTTME29." informate .

Kurt_Bremser
Super User

MDYAMPM works, see

data test;
invar = "10/15/2008 12:00:00 AM";
outvar = input(invar,mdyampm22.);
format outvar e8601dt19.;
put outvar=;
run;

Log:

 73         data test;
 74         invar = "10/15/2008 12:00:00 AM";
 75         outvar = input(invar,mdyampm22.);
 76         format outvar e8601dt19.;
 77         put outvar=;
 78         run;
 
 outvar=2008-10-15T00:00:00
Caetreviop543
Obsidian | Level 7

Thank you for your help. Unfortunately, neither methods works. The date is imported as character, but provides numbers for dates in the range of 40,000. I thought that the imported value corresponds to the number of days since 01/01/1960, however, wouldn't that mean it's reading the date as ~100 years from 01/01/1960?

 

Using anydtdte32. results in blank values, and the log for mdyampm22. shows input errors at given data lines. I've checked these lines thoroughly and can't find any incorrect, weird, or missing values. 

 

 

Kurt_Bremser
Super User

Open the file with a text editor and copy/paste some values into a code box opened with </>.

My code proves that the informat works with the string you posted.

The raw number of a datetime value will be much higher, as it is a count of seconds from 1960-01-01 00:00:00.

Caetreviop543
Obsidian | Level 7
          6/30/2010  12:00:00 AM
          6/25/2010  12:00:00 AM
          5/6/2010  12:00:00 AM

The data are right aligned in the cell, so there are several spaces before the date times. Could that be the problem?

Kurt_Bremser
Super User

@Caetreviop543 wrote:
          6/30/2010  12:00:00 AM
          6/25/2010  12:00:00 AM
          5/6/2010  12:00:00 AM

The data are right aligned in the cell, so there are several spaces before the date times. Could that be the problem?


Even with this data, the MDYAMPM informat works, you just need to give it sufficient length:

data want;
input dtvar mdyampm40.;
format dtvar e8601dt19.;
datalines;
          6/30/2010  12:00:00 AM
          6/25/2010  12:00:00 AM
          5/6/2010  12:00:00 AM
;
ballardw
Super User

@Caetreviop543 wrote:

Thank you for your help. Unfortunately, neither methods works. The date is imported as character, but provides numbers for dates in the range of 40,000. I thought that the imported value corresponds to the number of days since 01/01/1960, however, wouldn't that mean it's reading the date as ~100 years from 01/01/1960?

 

Using anydtdte32. results in blank values, and the log for mdyampm22. shows input errors at given data lines. I've checked these lines thoroughly and can't find any incorrect, weird, or missing values. 

 

 


Numbers in the 40000 range typically appear when working with Excel because that uses 31Dec1899 (or similar) as day 0.

 

SHOW the code you are using and actual example data.

 

Doesn't work is awful vague.

Are there errors in the log?: Post the code and log in a code box opened with the <> to maintain formatting of error messages.

No output? Post any log in a code box.

Unexpected output? Provide input data in the form of data step code pasted into a code box, the actual results and the expected results. Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the <> icon or attached as text to show exactly what you have and that we can test code against.

Caetreviop543
Obsidian | Level 7

I've attached screenshots of my code and log, as well as the first five data points. Anydtdte32. appears to work, but it provides the wrong dates.

Caetreviop543
Obsidian | Level 7

I would like to add that this file originally had column headers throughout. Therefore, the contact_date variable which was imported as BA, originally looked like this:

 

 

BA

contact_date

1/1/2012 12:00:00 AM

12/23/2004 12:00:00 AM



contact_date 

03/04/2005 12:00:00 AM 



contact_date 

12/13/2004 12:00:00 AM

 

 

There are around 500 files, so in order to work around editing each one manually, I imported them as is, and deleted rows containing the column headers. However, doing that unfortunately resulted in everything being imported as character. Now it seems SAS has an issue converting the once character variable contact_date (e.g., BA) to a date. 

 

I don't know how to correct this without editing the 500 files manually by hand.

ChrisNZ
Tourmaline | Level 20

>  I imported them as is, and deleted rows containing the column headers.

Why do this? How did you import? Of course if you read the header as data, then the data is a string.

 

> Now it seems SAS has an issue converting the once character variable contact_date (e.g., BA) to a date. 

Provide an exact sample of the data you are trying to read (use the icon </> so the data is kept as is). 

 

Also please run the PULOG line for one of the values and show us the log so we can see if the space are not special characters.

data T;
  A='03/04/2005 12:00:00 AM';
  putlog A= A= $hex64.;
run;  

 

The solutions given work for the data given.

 

 

ballardw
Super User

Not opening ZIP or xlsx files from unknown sources. Program text is best copy/paste into a code box opend on the forum with either the </> or "running man" icons.

 

You have to create a new variable. Once a variable exists in a SAS data set the variable type is fixed.

So if you did not use something like

newvar = input(charactervar, anydtdte.);

then that is likely part of your issue.

 

If you have a lot of files of similar format to read you are almost always better off writing a data step so they are all processed the same. Since Proc Import will make different "guesses" for each file imported you can spend way more time "fixing" things that could have been prevented by reading properly the first time.

Yes, it appears you do not have a simple file format to read. But SAS can examine a line of text in the  file and you can find key values and pick appropriate alternate code to process the line.

data example;
   infile datalines dlm=',' ;
   input @;
   if _infile_ =: 'contact_date' or missing (_infile_) then do;
      input;
      delete;
   end;
   ampmpos = max(index(_infile_,'AM'),index(_infile_,'PM'));
   if 0< ampmpos < 24 then do;
      /*likely found AM PM as part of date*/
      contact_date = input(substr(_infile_,1,ampmpos+1),anydtdtm32.);
      input;
   end;
   format contact_date  dateampm.;
   drop ampmpos;
datalines;
contact_date

1/1/2012 12:00:00 AM

12/23/2004 12:00:00 AM



contact_date 

03/04/2005 12:00:00 AM 



contact_date 

12/13/2004 12:00:00 AM
;

The INPUT @ holds the current input line until told to advance with another Input statement.

_INFILE is an automatic variable that holds the line of the input file. So you can test it for key values and use appropriate INPUT to read the value in the desired form (often called parsing a line of text).

 

I suspect your file is more complex but without an actual TXT example, copy for your file with a text editor and paste into a code box opened on the forum with the </> icon, not going to do much more. The code box is critical in this case because the message window will reformat the text otherwise.

 

You don't discuss the "BA" that appears. If that is supposed to be some sort of identifier then you could read it and retain the value to keep on records until another identifier appears. Or if this is always on the first/second/what have you line of the file that can be read first with an input and then conditionally execute other input statements based on whether that is set (not missing).

Caetreviop543
Obsidian | Level 7

I did create a new variable using input, but it results in missing values. BA is simply the excel header that SAS reads as the column name, because the column names are interspersed throughout the data. Below are a few of thousands of records directly copied and pasted from the excel file. There are two spaces between the date and the time. I apologize for the delay, and for not understanding how to correctly share data. 

 

BA

CONTACT_DATE
12/18/2009  12:00:00 AM
12/22/2009  12:00:00 AM
12/22/2009  12:00:00 AM
8/31/2010  12:00:00 AM
3/5/2012  12:00:00 AM


CONTACT_DATE
9/23/2011  12:00:00 AM
9/26/2011  12:00:00 AM
2/7/2012  12:00:00 AM
2/7/2012  12:00:00 AM


CONTACT_DATE
5/25/2010  12:00:00 AM
5/25/2010  12:00:00 AM
5/2/2011  12:00:00 AM
5/3/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/17/2011  12:00:00 AM
7/14/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM

Ballardw, I'm not sure how to apply your code to excel files. Is it essentially trying to remove AM/PM? Is there a way to import excel files using input? Specifically, I'm confused about how to apply 'datalines' to thousands of records. I tried the code below where work.mydata refers to an excel file imported using proc import. The code works fine and applies the format to contact_date, but all the values are missing. 

 

data work.mydata2;
	set work.mydata;
	if BA= 'contact_date' or BA='' then delete;
	ampmpos=max(index(BA,"AM"), index(BA, "PM"));
	if 0<ampmpos<24 then do;
		contact_date=input(substr(BA,1,ampmpos+1), anydtdtm32.);
	end;
	format contact_date dateampm.;
	drop ampmpos;
run;
Kurt_Bremser
Super User

If your imported dataset looks like this, the MDYAMPM informat will also work in the INPUT function:

data have;
input BA $30.;
datalines;
CONTACT_DATE
12/18/2009  12:00:00 AM
12/22/2009  12:00:00 AM
12/22/2009  12:00:00 AM
8/31/2010  12:00:00 AM
3/5/2012  12:00:00 AM


CONTACT_DATE
9/23/2011  12:00:00 AM
9/26/2011  12:00:00 AM
2/7/2012  12:00:00 AM
2/7/2012  12:00:00 AM


CONTACT_DATE
5/25/2010  12:00:00 AM
5/25/2010  12:00:00 AM
5/2/2011  12:00:00 AM
5/3/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/14/2011  12:00:00 AM
7/17/2011  12:00:00 AM
7/14/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
10/30/2011  12:00:00 AM
;

data want;
set have (rename=(BA=_BA));
where _BA not in("","CONTACT_DATE");
BA = input(_BA,mdyampm32.);
format BA e8601dt19.;
run;

Result:

1	12/18/2009  12:00:00 AM	2009-12-18T00:00:00	
2	12/22/2009  12:00:00 AM	2009-12-22T00:00:00	
3	12/22/2009  12:00:00 AM	2009-12-22T00:00:00	
4	8/31/2010  12:00:00 AM	2010-08-31T00:00:00	
5	3/5/2012  12:00:00 AM	2012-03-05T00:00:00	
6	9/23/2011  12:00:00 AM	2011-09-23T00:00:00	
7	9/26/2011  12:00:00 AM	2011-09-26T00:00:00	
8	2/7/2012  12:00:00 AM	2012-02-07T00:00:00	
9	2/7/2012  12:00:00 AM	2012-02-07T00:00:00	
10	5/25/2010  12:00:00 AM	2010-05-25T00:00:00	
11	5/25/2010  12:00:00 AM	2010-05-25T00:00:00	
12	5/2/2011  12:00:00 AM	2011-05-02T00:00:00	
13	5/3/2011  12:00:00 AM	2011-05-03T00:00:00	
14	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
15	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
16	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
17	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
18	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
19	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
20	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
21	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
22	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
23	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
24	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
25	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
26	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
27	7/17/2011  12:00:00 AM	2011-07-17T00:00:00	
28	7/14/2011  12:00:00 AM	2011-07-14T00:00:00	
29	10/30/2011  12:00:00 AM	2011-10-30T00:00:00	
30	10/30/2011  12:00:00 AM	2011-10-30T00:00:00	
31	10/30/2011  12:00:00 AM	2011-10-30T00:00:00	
32	10/30/2011  12:00:00 AM	2011-10-30T00:00:00	
33	10/30/2011  12:00:00 AM	2011-10-30T00:00:00	

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 16 replies
  • 6221 views
  • 0 likes
  • 5 in conversation