5,447,640 members and growing! (21,113 online)
Email Password   helpLost your password?
General Programming » Date and Time » General     Intermediate

Excel serial date to Day, Month, Year and vise versa

By Victor Vogelpoel

A speedy algorithm to convert Excel numbers to DMY and vise versa.
VC6, VC7, C++Windows, Win2K, WinXP, Visual Studio, Dev

Posted: 12 Aug 2002
Updated: 12 Aug 2002
Views: 136,687
Bookmarked: 15 times
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
18 votes for this Article.
Popularity: 5.38 Rating: 4.29 out of 5
1 vote, 7.1%
1
0 votes, 0.0%
2
0 votes, 0.0%
3
1 vote, 7.1%
4
12 votes, 85.7%
5

Introduction

For a little project of mine, I needed to convert a serial date number to day/month/year (DMY) and vise versa. The serial number came from date field in a converted Paradox database and seemed to be exactly the same as the serial date in Microsoft Excel, hence the article name. After some googling I learned that the Excel serial date is related to Julian date, and found a speedy algorithm to convert these numbers to DMY and vise versa.

Excel Serial Date Number

Now what is an Excel serial date number? 37477 is a serial date number and is the number of days since 1-1-1900. 37477 actually translates to Aug 9, 2002, the date of writing this article.

The number of days since 1-1-1900 isn't that hard to calculate of course, once you know the leap years. Microsoft Excel however contains a bug with its date calculation: it considers 29-02-1900 as a valid date, but 1900 isn't a leap year! 29-02-1900 is not a valid date!

According to the stories, Microsoft decided to duplicate this date bug from Lotus 123, which was the dominating spreadsheet application at the time Excel was being written. This allowed Excel to open Lotus 123 spreadsheets without date problems.

(Note that a serial date number may also contain a fraction that denotes the time. It's actually the percentage of 24 hours, but that's not for this article.)

Mac Excel Serial Date number

Excel on the Apple Mac uses a slightly different Serial Date number base: the number of days since 1-1-1904. That's why Excel also features a "1904 Date System" checkbox in its Options (Calculation tab). I won't go into this futher.

Translating Serial Date Number to DMY

First of all, credit where credit is due. I got the basic algorithm from http://serendipity.magnet.ch/hermetic/cal_stud/jdn.htm. It's about converting a Julian date to DMY using integer calculations. I won't bore you with the theory (following the above hyperlink), but the original Julian has a different base date.

With an addition of a certain number, the algorithm comes close to the Excel serial date. And when the 29-02-1900 issue is handled, we've got an Excel serial date to Day, Month, Year calculation!

void ExcelSerialDateToDMY(int nSerialDate, int &nDay, 
                          int &nMonth, int &nYear)
{
    // Excel/Lotus 123 have a bug with 29-02-1900. 1900 is not a

    // leap year, but Excel/Lotus 123 think it is...

    if (nSerialDate == 60)
    {
        nDay    = 29;
        nMonth    = 2;
        nYear    = 1900;

        return;
    }
    else if (nSerialDate < 60)
    {
        // Because of the 29-02-1900 bug, any serial date 

        // under 60 is one off... Compensate.

        nSerialDate++;
    }

    // Modified Julian to DMY calculation with an addition of 2415019

    int l = nSerialDate + 68569 + 2415019;
    int n = int(( 4 * l ) / 146097);
            l = l - int(( 146097 * n + 3 ) / 4);
    int i = int(( 4000 * ( l + 1 ) ) / 1461001);
        l = l - int(( 1461 * i ) / 4) + 31;
    int j = int(( 80 * l ) / 2447);
     nDay = l - int(( 2447 * j ) / 80);
        l = int(j / 11);
        nMonth = j + 2 - ( 12 * l );
    nYear = 100 * ( n - 49 ) + i + l;
}

DMY to Excel Serial Date

Calculate an Excel serial date from Day, Month, Year. The function assumes that the day, month and year are valid date numbers.

int DMYToExcelSerialDate(int nDay, int nMonth, int nYear)
{
    // Excel/Lotus 123 have a bug with 29-02-1900. 1900 is not a

    // leap year, but Excel/Lotus 123 think it is...

    if (nDay == 29 && nMonth == 02 && nYear==1900)
        return 60;

    // DMY to Modified Julian calculatie with an extra substraction of 2415019.

    long nSerialDate = 
            int(( 1461 * ( nYear + 4800 + int(( nMonth - 14 ) / 12) ) ) / 4) +
            int(( 367 * ( nMonth - 2 - 12 * ( ( nMonth - 14 ) / 12 ) ) ) / 12) -
            int(( 3 * ( int(( nYear + 4900 + int(( nMonth - 14 ) / 12) ) / 100) ) ) / 4) +
            nDay - 2415019 - 32075;

    if (nSerialDate < 60)
    {
        // Because of the 29-02-1900 bug, any serial date 

        // under 60 is one off... Compensate.

        nSerialDate--;
    }

    return (int)nSerialDate;
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Victor Vogelpoel


Victor is consulting in The Netherlands.

His interests include Windows and web application development using .NET technologies and even some Apache/PHP/MySQL...
Occupation: Web Developer
Location: Netherlands Netherlands

Other popular Date and Time articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 27 (Total in Forum: 27) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralPorted to PHP and fixedmemberLubosdz1:19 9 Aug '07  
QuestionWorks great for date, what about for time?memberTariAbay21:19 29 Jul '07  
GeneralYEARmembergtown75:20 17 May '07  
GeneralGoing off after Febuvary...membervijaicmo1:23 12 Mar '07  
GeneralBut how can I know if the cell value is a Date?memberstanley guan17:51 7 Oct '05  
GeneralRe: But how can I know if the cell value is a Date?memberVictor Vogelpoel23:56 7 Oct '05  
GeneralNumber off by 183sussAnonymous5:33 29 Aug '05  
GeneralRe: Number off by 183sussAnonymous7:03 29 Aug '05  
GeneralDMYToExcelSerialDate doesn't work for 28th Feb 1900membercrusby0:09 10 Feb '05  
GeneralRe: DMYToExcelSerialDate doesn't work for 28th Feb 1900memberVictor Vogelpoel11:10 10 Feb '05  
Generaldoesn't work in months input > 12sussAnonymous13:23 24 Jun '04  
GeneralRe: doesn't work in months input > 12memberVictor Vogelpoel23:54 24 Jun '04  
GeneralThanks - Would like some clarificationsmemberjocompto10:11 4 May '04  
GeneralRe: Thanks - Would like some clarificationsmemberVictor Vogelpoel11:29 4 May '04  
Generaldate month year in excelsussAnonymous5:36 3 May '04  
GeneralRe: date month year in excelmemberVictor Vogelpoel9:44 3 May '04  
GeneralDifferent Results then ExcelsussAlex Baldini13:14 20 Oct '03  
GeneralPorted to PHPsussNathan Gasser17:39 24 Aug '03  
GeneralExcel dates in C#sussKris Vandermotten2:30 3 Apr '03  
GeneralRe: Excel dates in C#memberVictor Vogelpoel8:41 3 Apr '03  
GeneralRe: Excel dates in C#memberVentsyV13:39 29 Nov '07  
GeneralThanks! Just what I neededmemberTimian Heber9:58 12 Nov '02  
GeneralRe: Thanks! Just what I neededmemberVictor Vogelpoel10:21 12 Nov '02  
GeneralISO 8601 (International Standard Date Format)memberWarren Stevens3:46 13 Aug '02  
GeneralRe: ISO 8601 (International Standard Date Format)memberVictor Vogelpoel4:08 13 Aug '02  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 12 Aug 2002
Editor: Chris Maunder
Copyright 2002 by Victor Vogelpoel
Everything else Copyright © CodeProject, 1999-2008
Web16 | Advertise on the Code Project