Date and time To Words

image_pdfimage_print
   
 


#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Globalization;

namespace Newtonsoft.Utilities.Text
{
    public class FormatUtils
    {
        private static readonly string[] fuzzyHours = new string[] { 
        "midnight", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "noon", "one", "two", "three", 
        "four", "five", "six", "seven", "eight", "nine", "ten", "eleven"
     };
        private static readonly string[] fuzzyMinutes = new string[] { "five", "ten", "a quarter", "twenty", "twenty five", "half" };

        public static string DateTimeToWords(DateTime date)
        {
            return DateTimeToWords(date, DateTime.Now);
        }

        public static string DateTimeToWords(DateTime dateTime, DateTime currentDate)
        {
            string result;
            TimeSpan t1 = new TimeSpan(currentDate.Ticks);
            TimeSpan t2 = new TimeSpan(dateTime.Ticks);
            int daysElapsed = t1.Days - t2.Days;
            if (daysElapsed < -7 || daysElapsed >= 14)
                result = DateToWords(dateTime, currentDate);
            else if (daysElapsed == 0)
                result = "this " + GetPeriod(dateTime.Hour);
            else
                result = DateToWords(dateTime, currentDate) + " " + GetPeriod(dateTime.Hour);

            return (result + " at " + TimeToWords(dateTime));
        }

        public static string DateToWords(DateTime date)
        {
            return DateToWords(date, DateTime.Now);
        }

        public static string DateToWords(DateTime date, DateTime currentDate)
        {
            TimeSpan t1 = new TimeSpan(currentDate.Ticks);
            TimeSpan t2 = new TimeSpan(date.Ticks);
            int daysElapsed = t1.Days - t2.Days;

            if (daysElapsed < -1 &amp;&amp; daysElapsed >= -7)
                return ("next " + date.ToString("dddd"));

            if (daysElapsed == -1)
                return "tomorrow";

            if (daysElapsed == 0)
                return "today";

            if (daysElapsed == 1)
                return "yesterday";

            if (daysElapsed > 1 &amp;&amp; daysElapsed < 7)
                return date.ToString("dddd");

            if (daysElapsed >= 7 &amp;&amp; daysElapsed < 14)
                return "last " + date.ToString("dddd");

            return
              (date.ToString("MMMM") + " " + GetOrdinal(date.Day) +
               ((date.Year != currentDate.Year) ? (" " + date.ToString("yyyy")) : string.Empty));
        }
        public static string GetOrdinal(int value)
        {
            string&#91;&#93; _suffixes = new string&#91;&#93; { "th", "st", "nd", "rd" };
            int tenth = value % 10;


            if (tenth >= _suffixes.Length)
            {
                return _suffixes[0];
            }
            else
            {
                // special case for 11, 12, 13
                int hundredth = value % 100;
                if (hundredth >= 11 &amp;&amp; hundredth <= 13)
                    return _suffixes&#91;0&#93;;

                return _suffixes&#91;tenth&#93;;
            }
        }
        private static string GetPeriod(int hour)
        {
            if (hour > 18)
                return "evening";

            if (hour > 12)
                return "afternoon";

            if (hour > 3)
                return "morning";

            return "night";
        }

        public static string TimeToWords(DateTime time)
        {
            string result;
            int minutes = time.Minute;
            int hours = time.Hour;
            bool toHour = false;
            int remainder = time.Minute % 5;

            if (remainder < 3)
                minutes -= remainder;
            else
                minutes += 5 - remainder;

            if (minutes > 30)
            {
                hours = (hours + 1) % 24;
                minutes = 60 - minutes;
                toHour = true;
            }

            if (minutes != 0)
                result = fuzzyMinutes[minutes / 6] + " " + (toHour ? "to" : "past") + " " + fuzzyHours[hours];
            else
                result = fuzzyHours[hours] + ((hours != 0 &amp;&amp; hours != 12) ? " o&#039;clock" : string.Empty);

            if (hours > 0 &amp;&amp; hours < 12)
                return result + " am";

            if (hours > 12)
                result = result + " pm";

            return result;
        }
    }
}