Home » excel » convert mmm dd, yyyy, h:mm am in Excel VBA

convert mmm dd, yyyy, h:mm am in Excel VBA

Posted by: admin May 14, 2020 Leave a comment

Questions:

An application exports with a text field that combines date and time in the format shown below. This format is a bit different (there’s a comma after the year for starters) than the answer to “convert MMM DD, YYYY HH:MM:SS am in Excel” which was answered on Stackflow on 6/2/2014. I tried running the VBA code that the answer provided but am getting a run time error 13 and type mismatch. I don’t know enough about VBA to know what changes I should make to the VBA code. Any help would be gratefully received.

Apr 5, 2018, 10:00 AM
Apr 15, 2018, 2:00 PM 
Apr 30, 2018, 7:00 PM
How to&Answers:

You do not state what you want to convert it to.

However, to extract a standard Excel DATE or TIME value from your string, merely replace the second comma with a space, and apply either the TIMEVALUE or DATEVALUE function to the result.

If you want to create a combined date/time stamp, apply the VALUE function, or a double unary, to the substituted string:

DATE/TIME

=VALUE(SUBSTITUTE(A1,","," ",2))  or
=--(SUBSTITUTE(A1,","," ",2)) 

Result -->   43195.41667 which can be formatted however you want

DATE ONLY

 =DATEVALUE(SUBSTITUTE(A1,","," ",2))

TIME ONLY

=TIMEVALUE(SUBSTITUTE(A1,","," ",2))

Answer:

Formulas and some background:

If you are trying to get a date have a look at a couple of ideas using formulas that will aid your understanding with using VBA later. Ultimately you need to create a string that can be parsed as a date. In the example you quoted the CDate function was able to recognise the string as a date and convert it to Date datatype.

1) With yours, if Apr 5, 2018, 10:00 AM were in A2, you could use a simple:

=DATE(RIGHT(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),4),MONTH(1&LEFT(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),3)),TRIM(MID(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),5,2)))

The inner

=SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",","")

gets the string before second “,” , then replaces the remaining “,” with “” giving

Apr 5 2018

The rest of the formula uses the Date function to create a date from the dateparts i.e. Year,Month,Day.

There are assumptions made that Month will be always 3 letter abbreviation. Single white spaces inside the string and no additional white space either side.

2) Without such assumptions you may end up with something like:

=DATE(RIGHT(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),4),MONTH(1&LEFT(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),3)),MID(A4,4,FIND(CHAR(1),SUBSTITUTE(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),CHAR(32),CHAR(1),2))-FIND(CHAR(1),SUBSTITUTE(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),CHAR(32),CHAR(1),1))))

Here is a table explaining each step of both:

Formula tables

Formulas in image by reference number

1) Removed “,” and extra white space

=TRIM(SUBSTITUTE(SUBSTITUTE(B2,",",""),CHAR(32)," "))

2) Get date part without time

=LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(B2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(B3,CHAR(32),CHAR(1),3))-1)

3) Position of first space ” “

=FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),1))

4) Position of second space ” “

=FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),2))

5) Month number

=MONTH(1&LEFT(B4,3))

6) Year

=RIGHT(B4,4)

7) Day

=MID(B4,4,FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),2))-FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),1)))

8) Date from dateparts Y,M,D

=DATE(B8,B7,B9)

9) Long formula already given above as second solution

10) Get string before second “,” , then replace remaining “,” with “”

=SUBSTITUTE(LEFT(B2,FIND(", ",B2,FIND(", ",B2)+1)-1),",","")

11) Formula given at top as first solution with lots of assumptions

VBA:

Edit:

@ Darren Bartrup-Cook has pointed out that CDate is more effective than I imagined and you can simply do:

 CDate(Replace(.Range("B2").Text, ",", ""))

This will preserve the Time element. I have covered removing the time element earlier in the answer if required. Or you can do

Int(CDate(Replace(.Range("B2").Text, ",", "")))

Original text:

With vba you can use the Instr or Instrrev functions instead of Find to locate the occurrence of a character within a string. Find is used with range objects rather than the string within when using VBA. Instr starts searching from the start of the string, and InstrRev from the end i.e. right to left. These means argument orders change. More info on this is given in the references.

The simple formula as vba code using CDate function as per answer you referenced.

Public Sub test()
    With ThisWorkbook.Worksheets("Sheet1")
        Debug.Print CDate(Left$(.Range("B2").Text, InStr(InStr(.Range("B2").Text, ", ") + 1, .Range("B2").Text, ", ") - 1))
    End With
End Sub

The above you could use in a loop over the range where you want to convert values.

Something like:

.Range("B2") = CDate(Left$(.Range("B2").Text, InStr(InStr(.Range("B2").Text, ", ") + 1, .Range("B2").Text, ", ") - 1))

Or,

You can convert this into a user defined function and call from within the worksheet:

Public Function GetDate(ByVal rng As Range)
    GetDate = CDate(Left$(rng.Text, InStr(InStr(rng.Text, ", ") + 1, rng.Text, ", ") - 1))
End Function

Calling UDF in sheet

UDF

Note you either format the cells as Date format to get the correct formatting or change the function to:

GetDate = Format$(CDate(Left$(rng.Text, InStr(InStr(rng.Text, ", ") + 1, rng.Text, ", ") - 1)), "dd/mm/yyyy")

References:

  1. Instrrev
  2. Instr
  3. Range.Find
  4. Substitute
  5. Char
  6. User Defined Functions UDF
  7. CDate