Converting Dates to Words in C#

Introduction

A question which was recently asked on our forums is - how do I convert a date to words?

This can be easily solved by using the method in my earlier article entitled Converting Numbers To Words in C# (http://www.c-sharpcorner.com/uploadfile/b942f9/converting-numbers-to-words-in-C-Sharp/) to convert the year, together with additional code to convert the day and month.

In this article, I'd therefore like to present a simple program which does all this.

The program supports both the US and UK ways of writing dates. For example the date, 29th February 2012, would typically be expressed as follows

February Twenty Ninth Two Thousand Twelve (in the US )

The Twenty Ninth of February Two Thousand and Twelve (in the UK )

The program optionally supports the addition of the time to the date. This is expressed in hours and minutes AM or PM. For example 17:45 would map to Five Forty Five PM

Seconds and milliseconds are ignored.

Source Code

using System;
using System.Globalization;
using System.Threading;

class Program
{
    static void Main()
    {
        // use US English culture throughout the examples
        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");

        string words;
        DateTime dt = DateTime.Now;
        words = DateToText(dt, true, false);
        Console.WriteLine(words);

        DateTime dt2 = DateTime.Parse("07/27/2011 18:59:32");
        words = DateToText(dt2, true, true);
        Console.WriteLine(words);

        DateTime dt3 = DateTime.Parse("02/29/2004 12:00");
        words = DateToText(dt3, true, false);
        Console.WriteLine(words);

        DateTime dt4 = DateTime.Parse("01/06/1999");
        words = DateToText(dt4, false, true);
        Console.WriteLine(words);

        Console.ReadKey();
    }

    public static string DateToText(DateTime dt, bool includeTime, bool isUK)
    {
        string[] ordinals = { "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth",
            "Eleventh", "Twelfth", "Thirteenth", "Fourteenth", "Fifteenth", "Sixteenth", "Seventeenth", "Eighteenth", "Nineteenth",
            "Twentieth", "Twenty First", "Twenty Second", "Twenty Third", "Twenty Fourth", "Twenty Fifth", "Twenty Sixth", "Twenty Seventh",
            "Twenty Eighth", "Twenty Ninth", "Thirtieth", "Thirty First" };

        int day = dt.Day;
        int month = dt.Month;
        int year = dt.Year;

        DateTime dtm = new DateTime(1, month, 1);
        string date;

        if (isUK)
        {
            date = "The " + ordinals[day - 1] + " of " + dtm.ToString("MMMM") + " " + NumberToText(year, true);
        }
        else
        {
            date = dtm.ToString("MMMM") + " " + ordinals[day - 1] + " " + NumberToText(year, false);
        }

        if (includeTime)
        {
            int hour = dt.Hour;
            int minute = dt.Minute;
            string ap = "AM";

            if (hour >= 12)
            {
                ap = "PM";
                hour = hour - 12;
            }

            if (hour == 0) hour = 12;

            string time = NumberToText(hour, false);
            if (minute > 0) time += " " + NumberToText(minute, false);
            time += " " + ap;

            date += ", " + time;
        }

        return date;
    }

    public static string NumberToText(int number, bool isUK)
    {
        if (number == 0) return "Zero";

        string and = isUK ? "and" : ""; // deals with UK or US numbering

        if (number == -2147483648)
            return "Minus Two Billion One Hundred " + and + " Forty Seven Million Four Hundred " + and + " Eighty Three Thousand Six Hundred " + and + " Forty Eight";

        int[] num = new int[4];
        int first = 0;
        int u, h, t;
        System.Text.StringBuilder sb = new System.Text.StringBuilder();

        if (number < 0)
        {
            sb.Append("Minus ");
            number = -number;
        }

        string[] words0 = { "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" };
        string[] words1 = { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" };
        string[] words2 = { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };
        string[] words3 = { "Thousand", "Million", "Billion" };

        num[0] = number % 1000; // units
        num[1] = number / 1000;
        num[2] = number / 1000000;
        num[1] = num[1] - 1000 * num[2]; // thousands
        num[3] = number / 1000000000; // billions
        num[2] = num[2] - 1000 * num[3]; // millions

        for (int i = 3; i > 0; i--)
        {
            if (num[i] != 0)
            {
                first = i;
                break;
            }
        }

        for (int i = first; i >= 0; i--)
        {
            if (num[i] == 0) continue;

            u = num[i] % 10; // ones
            t = num[i] / 10;
            h = num[i] / 100; // hundreds
            t = t - 10 * h; // tens

            if (h > 0)
                sb.Append(words0[h] + " Hundred ");

            if (u > 0 || t > 0)
            {
                if (h > 0 || i < first)
                    sb.Append(and);

                if (t == 0)
                    sb.Append(words0[u]);
                else if (t == 1)
                    sb.Append(words1[u]);
                else
                    sb.Append(words2[t - 2] + " " + words0[u]);
            }

            if (i != 0)
                sb.Append(words3[i - 1]);
        }

        return sb.ToString().TrimEnd();
    }
}

Output

outputDate

Conclusion

There are, of course, many ways in which one can write a date in words and this program only deals with what I consider to be two of the commoner ones.

However, it would not be difficult to adjust the program to deal with other formats.

The code for this article is also available as a download.


Similar Articles