title: .NumberFormat sometimes returns the wrong value with dates and times
body: <p>It seems that every week or so someone posts a question about dates being converted (corrupted?) to American format.  Like many others, I have attempted to help but the problem is elusive.  I now wonder if I have discovered the cause.</p>
  
  <p>I am working on an application in which I need to extract data from an Excel worksheet and output it as strings formatted to match the value the Excel user can see.  So if the value is “1” formatted to display as “1.00” then I want the string to be “1.00”.</p>
  
  <p>I achieve this effect by testing the cell value to be a number, date or time.  If it is, I retrieve the number format and use it to format the cell value so:</p>
  
  <pre><code>With .Cells(Row, Column) 
    Output string = Format(.Value, .NumberFormat)
  End With
  </code></pre>
  
  <p>In most cases this gives me exactly the output I require.  However, sometimes I get American dates and times when the source is formatted as a UK date or time.</p>
  
  <p>After much experimentation with Excel 2003 and Excel 2007, I have discovered the cause.  (I do not have access to Excel 2010 but from questions I deduce it has the same problem.)  This question is in part intended to reveal this problem to the world because I can discover nothing on the internet to indicate that anyone else has noticed it.  (No doubt someone will reply that they googled “xyz” and got the answer immediately.)  However, the main purpose of this question is to seek suggestions for obtaining the result I need in all situations.</p>
  
  <p>Typically I enter dates as, for example, “23mar12”.  Excel recognises this as a date and formats it as “23-Mar-12”.  I can select <code>Format Cells</code> and enter or select a custom format or select one of the date formats so I can have any format I can imagine wanting including non-English names for days and months.</p>
  
  <p>However, in one case the format I select is not the format that is recorded: Custom format “dd/mm/yyyy” is recorded as Date format “* 14/03/2001”.  This is not obviously a problem until further down the line.</p>
  
  <p>I created a column of dates and times and formatted each with a different custom or standard format.   I wrote a macro to extract the NumberFormat for each of these dates and times and write it as a string to an adjacent column.  I also formatted the value using the number format and wrote that string to a third column.</p>
  
  <p>In a number of cases the format selected and recorded by Excel was not the format returned by NumberFormat:</p>
  
  <pre><code>Excel format            NumberFormat
  Date: * 14/03/2001       m/d/yyyy
  Date: * 14 March 2001   [$-F800]dddd, mmmm dd, yyyy
  Date: 14/03/2001        dd/mm/yyyy;@
  Date: 14/03/01          dd/mm/yy;@
  Date: 14/3/01           d/m/yy;@
  Date: 14.3.01           d.m.yy;@
  Date: 2001-03-14        yyyy-mm-dd;@
  Date: 14 March 2001 (1) [$-809]dd mmmm yyyy;@
  Date: 14 March 2001 (2) [$-809]d mmmm yyyy;@
  Custom: hh:mm:ss        h:mm:ss
  Time: * 13:30:55        [$-F400]h:mm:ss AM/PM
  Time: 13:30:55 (1)      hh:mm:ss;@
  Time: 13:30:55 (2)      h:mm:ss;@
  Time: 01:30:55 PM       [$-409]hh:mm:ss AM/PM;@
  Time: 1:30:55 PM        [$-409]h:mm:ss AM/PM;@
  </code></pre>
  
  <p>The values (1) and (2) in the Excel format column were added by me to indicate that there are two apparently identical formats.  As can be seen from the NumberFormat column, in each case the second version suppresses a leading zero.</p>
  
  <p>Most changes have no important effect.  “[$-F800]” and so on are apparently dummy values with no effect.  Apparently you can replace “F800” with an Microsoft country code to have the names of days and months translated to the language of that country.</p>
  
  <p>However, the three standard formats that Microsoft marks with an asterisk are changed unacceptably.  The dates are changed from little endian to middle endian; the time is changed from 24 hour to 12 hour and the day of the week has been added to “* 14 March 2001”.</p>
  
  <p>The asterisk against the dates, references the comment: “Except for items that have an asterisk (<em>) in the Type list (Number tab, Format Cells dialog box), date formats that you apply do not switch date orders with the operating system.”  The asterisk against the time, references the comment: “Except for items that have an asterisk (</em>) in the Type list (Number tab, Format Cells dialog box), time formats that you apply do not switch time orders with the operating system.”</p>
  
  <p>If I have to, I can warn my users that standard date and time formats may not give the result desired.  However, if they want the popular format “dd/mm/yyyy”, they cannot have it.  “dd-mm-yyyy”, for example, is OK but custom format “dd/mm/yyyy” becomes date format “* 14/03/2001” becomes “m/d/yyyy”.</p>
  
  <p>Returning to my opening point: is this strange handling of one particular date format the reason so many people claim their dates are sometimes being converted to American format and is this why the problem is so elusive?  I have come across this type of problem elsewhere of one group of Microsoft programmers not knowing what another group are doing.  Is this why some functions always work and other sometimes don’t?  Some Microsoft programmers know where to look for the correct format and others don’t?</p>
  
  <p>More importantly, for me, can anyone suggest:</p>
  
  <ul>
  <li>How I obtain the true date or time format?</li>
  <li>Some other way of determining the user’s chosen display format for a date or time?</li>
  </ul>
  
  <p>BTW 1: I recall that thirty or so years ago I was told that the American military do not use month/day/year format; only American civilians use this format.  Can anyone tell me if this is true?</p>
  
  <p>BTW 2: The similar problem is with Excel colours.  Excel holds its colours as "ggbbrr" while everybody else holds them as "rrggbb".  The programmers for the .Net Excel inter-op were not told and and did not reverse the Excel colour number before using it to control the screen.</p>