Paul Grimshaw Paul Grimshaw - 2 months ago 7
C# Question

C# Date String to different format WITHOUT converting to date first

Is it possible to convert date strings from one format to another without actually converting them to a date?

I need something like this:

string inputDateString = "01/01/2012 23:36:17.234";
string inputFormat = "dd/MM/yyyy HH:mm:ss.fff";

string ouputFormat = "yyyy/MM/dd HH:mm:ss.fff";
string outputDateString = StringDate.Convert(inputDateString,inputFormat, outputFormat);


I can obviously write a StringDate class to parse the formats, but that would seem like reinventing the wheel. The reason I can't go first to a date is I have had numerous problems with timezones/server times, and don't have control over the environment in which this will run. I just want to be 100% sure that the date string is just rearanged, and not messed up!

Thanks

EDIT
The output format will always be the same, however the input format could be any combination of:

Time variations:
HH:mm:ss.fff
HH:mm:ss
HH:mm

Date variations (could be more):
dd/MM/yyyy
dd/MM/yy
MM/dd/yyyy
MM/dd/yy
yyyy/MM/dd
yy/MM/dd

Answer

You should absolutely parse it first. You just need to be careful about how you parse it and format it. Just because you've had problems with time zones in the past doesn't mean you should just avoid the parsing/formatting - it means you should work out what you want to do in terms of time zones. It sounds like you just want to treat the data as local. I suspect you'll want to specify DateTimeStyles.AssumeLocal and also use the invariant culture.

Use DateTime.ParseExact with the exact format you're expecting (and a specific culture, probably the invariant culture), then call ToString with the output format and again, the relevant culture.

Also note that your expecting format string isn't correct - you're using hh when you mean HH, and I suspect you want fff instead of mmm. Sample code:

using System;
using System.Globalization;

public class Test
{
    static void Main()
    {
        string inputDateString = "01/01/2012 23:36:17.234";
        string inputFormat = "dd/MM/yyyy HH:mm:ss.fff";        
        string outputFormat = "yyyy/MM/dd HH:mm:ss.fff";

        DateTime parsed = DateTime.ParseExact(inputDateString, inputFormat,
                                              CultureInfo.InvariantCulture,
                                              DateTimeStyles.AssumeLocal);
        string outputDateString = parsed.ToString(outputFormat, 
                                                  CultureInfo.InvariantCulture);
        Console.WriteLine(outputDateString); // Prints 2012/01/01 23:36:17.234
    }
}

You might also want to look into my Noda Time project, which would allow you to create a LocalDateTimePattern for each of input and output, then reuse them repeatedly.

Comments