Thursday, August 4, 2011

.NET Format String 102: DateTime Format String


DateTime has its own set format string modifiers because there are so many ways to display a date and time. There are 2 things that affects how your DateTime is formatted.
1. CultureInfo
Besides the format string modifiers, CultureInfo on your thread also greatly influences the output. My examples will be based on CultureInfo.InvariantCulture.
You can set the CultureInfo on your thread by calling this

Thread
.CurrentThread.CurrentCulture = <some culture>;
eg.
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");
2. Format String
There are actually two different ways of formatting a DateTime object. Both methods produce the same results:
DateTime now = DateTime.Now;
now.ToString("<dateTimeFormatString>");
String.Format("<strFormat>", now);

Basically:
<strFormat> = {<argument index>:<dateTimeFormatString>}
My examples will use the DateTime.ToString() method.
If you have read any DateTime format string documentation, you will know that the .NET platform has two different styles of DateTime format string:
2-a. Standard Format String
This is basically built in short hand for custom format string. You pass in the one character string to denote which custom format you want.
i.e.
now.ToString("d");  
// "09/27/2006"
now.ToString("D");  // "Tuesday, 27 September 2006"
now.ToString("G");  // "09/27/2006 14:15:39"
All of the format string syntax I discussed in ".NET Format String 101" is invalid here. Also, if you call now.ToString(), it is basically calling now.ToString("G");
I have included my own table mapping Standard Format String to Custom Format string in part 2-c below.MSDN actually has a pretty good table that describe what each item does, and DateTime.ToString() has a pretty good code example that shows what each format string specifier do. Also if you just want samples, MSDN has a "Standard Date Time Format String Output example" here. Because documentation is so good. I won't go into this too much. :)
2-b. Custom Format String
Custom format string gives you the flexibility to build your own formatting. When using a single character format string specifier, you will need to prepend it with a "%", otherwise it will be interpreted as a Standard Format String. Here are the basics for building your own string:
DateTime now = new DateTime(2006, 9, 07, 15, 06, 01, 08, DateTimeKind.Local);
now.ToString();      //"09/27/2006 15:06:01"

Year
now.ToString("%y");   //"6"
now.ToString("yy");   //"06"
now.ToString("yyy");  //"2006"
now.ToString("yyyy"); //"2006"

Month
now.ToString("%M");    //"9"
now.ToString("MM");    //"09"
now.ToString("MMM");   //"Sep"
now.ToString("MMMM");  //"September"

Day
now.ToString("%d");    //"7"
now.ToString("dd");    //"07"
now.ToString("ddd");   //"Thu"
now.ToString("dddd");  //"Thursday"

Hour
now.ToString("%h");    //"3"
now.ToString("hh");    //"03"
now.ToString("hhh");   //"03"
now.ToString("hhhh");  //"03"
now.ToString("%H");    //"15"
now.ToString("HH");    //"15"
now.ToString("HHH");   //"15"
now.ToString("HHHH");  //"15"

Minutes
now.ToString("%m");    //"3"
now.ToString("mm");    //"03"
now.ToString("mmm");   //"03"
now.ToString("mmmm");  //"03"

Seconds
now.ToString("%s");    //"1"
now.ToString("ss");    //"01"
now.ToString("sss");   //"01"
now.ToString("ssss");  //"01"

Milliseconds
now.ToString("%f");    //"0"
now.ToString("ff");    //"00"
now.ToString("fff");   //"008"
now.ToString("ffff");  //"0080"
now.ToString("%F");    //""
now.ToString("FF");    //""
now.ToString("FFF");   //"008"
now.ToString("FFFF");  //"008"

Kind
now.ToString("%K");    //"-07:00"
now.ToString("KK");    //"-07:00-07:00"
now.ToString("KKK");   //"-07:00-07:00-07:00"
now.ToString("KKKK");  //"-07:00-07:00-07:00-07:00"
// Note: The multiple K were just read as multiple instances of the
// single K

DateTime unspecified = new DateTime(now.Ticks, DateTimeKind.Unspecified);
unspecified.ToString("%K");   //""

DateTime utc = new DateTime(now.Ticks, DateTimeKind.Utc);
utc.ToString("%K");           //"Z"

TimeZone
now.ToString("%z");     //"-7"
now.ToString("zz");     //"-07"
now.ToString("zzz");    //"-07:00"
now.ToString("zzzz");   //"-07:00"

Other
now.ToString("%g");    //"A.D."
now.ToString("gg");    //"A.D."
now.ToString("ggg");   //"A.D."
now.ToString("gggg");  //"A.D."

now.ToString("%t");    //"P"
now.ToString("tt");    //"PM"
now.ToString("ttt");   //"PM"
now.ToString("tttt");  //"PM" 
2-c. Additional Resources
Now that you understand what Standard and Custom format strings are, here is a table of Standard Format String to Custom Format String mapping:
Year Month Day Patterns:
d      = "MM/dd/yyyy"
D      = 
"dddd, dd MMMM yyyy"
M or m = 
"MMMM dd"
Y or y = 
"yyyy MMMM"
Time Patterns:
t      = "HH:mm"
T      = 
"HH:mm:ss"
Year Month Day and Time without Time Zones:
f      = "dddd, dd MMMM yyyy HH:mm"
F      = 
"dddd, dd MMMM yyyy HH:mm:ss"
g      = 
"MM/dd/yyyy HH:mm"
G      = 
"MM/dd/yyyy HH:mm:ss"
Year Month Day and Time with Time Zones:
o      = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK"
R or r = 
"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"
s      = 
"yyyy'-'MM'-'dd'T'HH':'mm':'ss"
u      = 
"yyyy'-'MM'-'dd HH':'mm':'ss'Z'"
U      = 
"dddd, dd MMMM yyyy HH:mm:ss"
All other single characters will throw an exception.
Answering the question...
So finally, to answer the question that began this whole discussion. "What exactly would "zz" do?"  i.e. What would "now.ToString("zz")" return?
Because there are 2 characters, it will be interpreted as a custom format string. "zz" stands for the signed time zone offset with a leading zero for single digit offsets. For me, being in Pacific Standard Time, my return value would be "-07". 


How to Format a DateTime in C# / ASP.NET


When I was a new developer making websites in .NET, I ended up doing some pretty screwy things to make date’s and time’s look how I wanted to. I would do things like:
DateTime thisDate = DateTime.Now;
string AMPM = String.Empty;
if(thisDate.Hour>=12) {AMPM = "PM";} else {AMPM = "AM";}
String FormattedDate = (thisDate.Hour%12).ToString() + ":" + thisDate.Minute.ToString() + " " + AMPM;
Fortunately I soon learned there were much better ways to do that. C# and Visual Basic both have a very powerful DateTime variable type, which will let you display your date/time in just about any way that you’d like  using the .ToString(“”) method. Let’s say we want to display a formatted date/time that we had stored in a variable called “ThisDate”. Here are some common ways to display your DateTime Variable:
  • ThisDate.ToString(“d”);  // “01/10/2009″
  • ThisDate.ToString(“D”);  // “Monday, 10 January 2009″
  • ThisDate.ToString(“G”);  // “01/10/2009 12:00:00″
  • ThisDate.ToString(“hh:mm tt”) // “12:00 AM”
  • ThisDate.ToString(“dddd”) // “Monday”
These are the manners that I most frequently use the ASP.NET DateTime format tool. here is a writeup on how to create your own specially formatted DateTime views.