DateTime formatting extension method

Notes: I also updated the pieces of code at http://www.extensionmethod.net/Details.aspx?ID=393

In current project, I get some troubles in DateTime class, about format the date time object with the pattern specific string and the current culture, so I decide to code some extension methods in DataTime class in .NET library. And I think it’s it very useful if somebody can use it as right way. I take some idea from this link and coding the enum class for its. After that I also used the Lambda Expression for pass the parameter into the DateTime formatting method. It’s really easy for read code. And below is my implementation for that:


+ DateTimeFormat enum class:

    public enum DateTimeFormat
    {
        [StringValue("unknown")]
        UnknownSpecific = 0,
        [StringValue("d")]
        ShortDate = 1,
        [StringValue("D")]
        LongDate = 2,
        [StringValue("t")]
        ShortTime = 3,
        [StringValue("T")]
        LongTime = 4,
        [StringValue("f")]
        FullShortDateTime = 5,
        [StringValue("F")]
        FullLongDateTime = 6,
        [StringValue("g")]
        GeneralShortDateTime = 7,
        [StringValue("G")]
        GeneralLongDateTime = 8,
        [StringValue("m")]
        MonthDayLowerCase = 9,
        [StringValue("M")]
        MonthDayUpperCase = 10,
        [StringValue("r")]
        Rfc1123LowerCase = 11,
        [StringValue("R")]
        Rfc1123UpperCase = 12,
        [StringValue("s")]
        SortableDateTimeIso8601 = 13,
        [StringValue("U")]
        UniversalSortableDateTime = 14,
        [StringValue("y")]
        YearMonthLowerCase = 15,
        [StringValue("Y")]
        YearMonthUpperCase = 16
    }

+ DateTime extension class:

    public static class DateTimeExtension
    {
        /// <summary>
        /// Toes the string format.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="dateTimeFormat">The date time format.</param>
        /// <returns></returns>
        public static string ToStringFormat(this DateTime source, Expression<Func<DateTimeFormat>> dateTimeFormat)
        {
            var dateTimeFormatCompiled = dateTimeFormat.Compile().Invoke();

            var dateTimeStringFormat = StringEnum.GetStringValue(dateTimeFormatCompiled);

            var currentCulture = Thread.CurrentThread.CurrentCulture;

            return source.ToString(dateTimeStringFormat, currentCulture);
        }
    }

+ Use it:

var shortDateResult = DateTime.Now.ToStringFormat(() => DateTimeFormat.ShortDate);
var fullLongDateTimeResult = DateTime.Now.ToStringFormat(() => DateTimeFormat.FullLongDateTime);
var rfc1123Result = DateTime.Now.ToStringFormat(() => DateTimeFormat.Rfc1123LowerCase);

+ Some unit testing:

    [TestClass]
    public class DateTimeFormatTesting
    {
        [TestMethod]
        public void Can_Get_String_Of_Date_Time_Format()
        {
            var shortDate = StringEnum.GetStringValue(DateTimeFormat.ShortDate);
            Assert.AreEqual(shortDate, "d");
            var longDate = StringEnum.GetStringValue(DateTimeFormat.LongDate);
            Assert.AreEqual(longDate, "D");
            var shortTime = StringEnum.GetStringValue(DateTimeFormat.ShortTime);
            Assert.AreEqual(shortTime, "t");
            var longTime = StringEnum.GetStringValue(DateTimeFormat.LongTime);
            Assert.AreEqual(longTime, "T");
            var monthDayLowerCase = StringEnum.GetStringValue(DateTimeFormat.MonthDayLowerCase);
            Assert.AreEqual(monthDayLowerCase, "m");
            var monthDayUpperCase = StringEnum.GetStringValue(DateTimeFormat.MonthDayUpperCase);
            Assert.AreEqual(monthDayUpperCase, "M");
            var rfc1123UpperCase = StringEnum.GetStringValue(DateTimeFormat.Rfc1123UpperCase);
            Assert.AreEqual(rfc1123UpperCase, "R");

            // and more testing for this enum at here
            // ...
        }
    }
    [TestClass]
    public class DateTimeStringFormatTesting
    {
        private DateTime _originalDateTime;

        [TestInitialize]
        public void InitTestCase()
        {
            _originalDateTime = new DateTime(1984, 3, 11, 2, 30, 58);
        }

        [TestMethod]
        public void Can_Get_Short_Date_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.ShortDate);
            Assert.AreEqual(_originalDateTime.ToShortDateString(), result);
        }

        [TestMethod]
        public void Can_Get_Long_Date_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.LongDate);
            Assert.AreEqual("11 March 1984", result);
        }

        [TestMethod]
        public void Can_Get_Short_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.ShortTime);
            Assert.AreEqual("02:30", result);
        }

        [TestMethod]
        public void Can_Get_Long_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.LongTime);
            Assert.AreEqual("02:30:58", result);
        }

        [TestMethod]
        public void Can_Get_Full_Short_Date_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.FullShortDateTime);
            Assert.AreEqual("11 March 1984 02:30", result);
        }

        [TestMethod]
        public void Can_Get_Full_Long_Date_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.FullLongDateTime);
            Assert.AreEqual("11 March 1984 02:30:58", result);
        }

        [TestMethod]
        public void Can_Get_General_Short_Date_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.GeneralShortDateTime);
            Assert.AreEqual("11/03/1984 02:30", result);
        }

        [TestMethod]
        public void Can_Get_General_Long_Date_Time_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.GeneralLongDateTime);
            Assert.AreEqual("11/03/1984 02:30:58", result);
        }

        [TestMethod]
        public void Can_Get_Month_Day_Lower_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.MonthDayLowerCase);
            Assert.AreEqual("11 March", result);
        }

        [TestMethod]
        public void Can_Get_Month_Day_Upper_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.MonthDayUpperCase);
            Assert.AreEqual("11 March", result);
        }

        [TestMethod]
        public void Can_Get_Rfc1123_Lower_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.Rfc1123LowerCase);
            Assert.AreEqual("Sun, 11 Mar 1984 02:30:58 GMT", result);
        }

        [TestMethod]
        public void Can_Get_Rfc1123_Upper_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.Rfc1123UpperCase);
            Assert.AreEqual("Sun, 11 Mar 1984 02:30:58 GMT", result);
        }

        [TestMethod]
        public void Can_Get_Sortable_DateTime_Iso8601_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.SortableDateTimeIso8601);
            Assert.AreEqual("1984-03-11T02:30:58", result);
        }

        [TestMethod]
        public void Can_Get_Universal_Sortable_DateTime_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.UniversalSortableDateTime);
            Assert.AreEqual("11 March 1984 02:30:58", result);
        }

        [TestMethod]
        public void Can_Get_Year_Month_Lower_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.YearMonthLowerCase);
            Assert.AreEqual("March 1984", result);
        }

        [TestMethod]
        public void Can_Get_Year_Month_Upper_Case_String()
        {
            var result = _originalDateTime.ToStringFormat(() => DateTimeFormat.YearMonthUpperCase);
            Assert.AreEqual("March 1984", result);
        }

        [TestCleanup]
        public void TeardownTestCase()
        {
            if (_originalDateTime != null)
            {
                GC.SuppressFinalize(_originalDateTime);
            }
        }
    }


That is it. Just 2 classes for this extension and if you have some concern about that, don't hesitate to contact with me. Code for this extension is attached in this post as below. Happy coding, mate!

Shout it

Published Monday, November 1, 2010 7:17 PM by thangchung

Comments

# re: DateTime formatting extension method

Monday, November 1, 2010 5:05 PM by Robert Haken

Why the lambda? Why don't you use the DateTimeFormat parameter in the extension method directly?

# re: DateTime formatting extension method

Monday, November 1, 2010 5:46 PM by thangchung

@Robert: Because I want to wrap my enum object in the Expression Tree, so I can pass it anywhere, even through the wire but do not need to serialize. And one other reason, I want to invert the control out of this extension method, so in the future if have any extend usage, I can do on the Func and pass it into the DateTime extension method. That is my idea. IMHO, your comment is very useful, man. Thanks!

# re: DateTime formatting extension method

Thursday, November 4, 2010 12:05 PM by Ramon Smits

I am with Robert. Really weird to use a lambda to pass an enum value. No real advantage for that even after your explanation.

# re: DateTime formatting extension method

Tuesday, November 9, 2010 7:15 AM by neo

method is excellent

# re: DateTime formatting extension method

Thursday, November 11, 2010 7:04 AM by anehra63

Excellent post bro worth reading thanks for sharing

# re: DateTime formatting extension method

Friday, November 19, 2010 4:16 PM by James Curran

Your arguments pro-lambda don't make any sense.

1) Enums are inherently serializable.  Expressions are not. SO, you can allready pass a enum anywhere, but you'd have work to do to pass an expression tree.

2)As for inverting control, I'm not seeing what that buys you:

// Current method: (passing lambda)

  var formatfunc = () => DateTimeFormat.ShortTime;

  // later

  string strDate = dateTime.ToStringFormat(formatfunc);

How is that significantly different from:

// passing enum:

  var formatfunc = () => DateTimeFormat.ShortTime;

  // later

  string strDate = dateTime.ToStringFormat(formatfunc());

Basically, you've taken a simple, quick function and made it complicated & slow --- remember that Expression.Compile is probably several orders-of-magnatude more involved that the simple text formatting that's the goal of this function.

Additionally, your method requires StringValueAttribute/StringEnum which are from a third party library that you never mention.

So, let's see if we can meet the original design goal in a simpler and faster manner.   First we need to recognize the dateTime.ToString("string") is the same as dateTime.ToString("String, Thread.CurrentCulture)  (look it up in Reflector).  Next we need to make a string look like a Enum.  That can be done with static properties on a class:

public static class DateTimeFormat    

{        

public static string UnknownSpecific {get { return "unknown";}}

public static string ShortDate {get { return "d";}}

public static string LongDate {get { return "D";}}

//  etc

}

So, what with your method is:

var shortDateResult = DateTime.Now.ToStringFormat(() => DateTimeFormat.ShortDate);

With mine it's just:

var shortDateResult = DateTime.Now.ToString(DateTimeFormat.ShortDate);

No extension method or outside library; just the one static class.

# re: DateTime formatting extension method

Saturday, November 20, 2010 7:42 AM by A.

Just a note: DateTime is not a class, it's a struct. There's no difference in this particular case, but there are enough differences in general to care about class/struct terminology.

# re: DateTime formatting extension method

Sunday, November 21, 2010 7:37 AM by tutku

You've been kicked..A good thing

# re: DateTime formatting extension method

Tuesday, January 29, 2013 11:50 AM by Still

Greetings from Ohio! I'm bored at work so I decided to check out your website on my iphone during lunch break. I really like the information you provide here and can't wait to take a look when I get home.

I'm surprised at how fast your blog loaded on my cell phone .. I'm not even using WIFI, just 3G .

. Anyhow, great blog!

# re: DateTime formatting extension method

Wednesday, January 30, 2013 8:38 AM by Swan

Greetings! Very helpful advice in this particular article!

It is the little changes that make the most important changes.

Thanks a lot for sharing!

# re: DateTime formatting extension method

Sunday, February 10, 2013 11:29 PM by Dorris

Wonderful beat ! I would like to apprentice

while you amend your web site, how could i subscribe for a blog site?

The account helped me a acceptable deal. I had been a little bit acquainted of this your broadcast offered bright clear concept

# re: DateTime formatting extension method

Wednesday, February 13, 2013 8:10 AM by Heckman

If you want to grow your familiarity just keep visiting this site and be

updated with the most up-to-date news update posted here.

# re: DateTime formatting extension method

Friday, February 15, 2013 1:33 PM by Gant

This post will help the internet people for setting up new blog or

even a blog from start to end.

# re: DateTime formatting extension method

Wednesday, February 20, 2013 8:53 PM by Guinn

Can I simply just say what a comfort to find someone

that truly understands what they are discussing on the web.

You actually realize how to bring a problem to light and make it important.

A lot more people ought to look at this and understand this side of your story.

I was surprised that you aren't more popular given that you certainly have the gift.

# re: DateTime formatting extension method

Friday, March 29, 2013 1:34 AM by Doty

Why viewers still make use of to read news papers when in this technological globe all is

accessible on web?