locked
Formatting different date formats into a common format RRS feed

  • Question

  • User-1988614724 posted

    Hi,

    I have this function


    public static DateTime ToDateTime(this string date)
    {
    return DateTime.ParseExact(date, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
    }

    The problem is the date variable, which has different forms: 2015-12-01T00: 00: 00 + 00:00, 12/31/2018 01:00:00 etc.

    At startup, I have an error:

    System.FormatException
    HResult=0x80131537
    Message=The string was not recognized as a valid DateTime element.
    Source=mscorlib
    Ślad stosu:
    w System.DateTimeParse.ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)
    w System.DateTime.ParseExact(String s, String format, IFormatProvider provider)
    w InsuranceService.Common.ExtensionMethods.StringExtensionMethods.ToDateTime(String date) w StringExtensionMethods.cs:wiersz 10
    w AutoMapper.Internal.DelegateBasedResolver2.Resolve(ResolutionResult source) w AutoMapper.NullReferenceExceptionSwallowingResolver.Resolve(ResolutionResult source) w AutoMapper.PropertyMap.<>c.<ResolveValue>b__44_0(ResolutionResult current, IValueResolver resolver) w System.Linq.Enumerable.Aggregate[TSource,TAccumulate](IEnumerable1 source, TAccumulate seed, Func`3 func)
    w AutoMapper.PropertyMap.ResolveValue(ResolutionContext context)
    w AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, Object mappedObject, PropertyMap propertyMap)

    Does anyone know how to fix it? Finally, I need to have a date in the format: yyyy-MM-dd

    Friday, December 21, 2018 11:10 AM

All replies

  • User753101303 posted

    Hi,

    You have also the https://docs.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?view=netframework-4.7.2#System_DateTime_ParseExact_System_String_System_String___System_IFormatProvider_System_Globalization_DateTimeStyles_ or maybe just Parse. It dépends a bit about which kind of formats you want to accept (and reject).

    Friday, December 21, 2018 12:33 PM
  • User-1988614724 posted

    I need a universal function to replace dates. I have dates in the following format: 2015-12-01T00: 00: 00 + 00:00, 12/31/2018 01:00:00, 2015-12-01, 12/31/2018 etc. I need to get a date using the above function in the format "yyyy-MM-dd"

    Friday, December 21, 2018 12:34 PM
  • User753101303 posted

    I wondered more specifically if you can have both  dd/MM/yyyy and MM/dd/yyyy ? If yes you have no way to know which date it is without knowing which convention is used and you would have to configure this explicitely. It seems like string data coming from a whole lot of external systems ?

    Or have you tried Parse first then if you don't want to ParseExact and provide explicitely allowed formats ?

    Friday, December 21, 2018 12:54 PM
  • User-1988614724 posted

    I'm sorry, I turned around.
    My formats are:

    string format1 = "yyyy-MM-ddTHH: mm: sszzzz";
    string format2 = "yyyy-MM-dd HH: mm: ss";
    string format3 = "dd.MM.yyyy HH: mm: ss";
    string format4 = "yyyy-MM-ddTHH: mm: sszzzz";

    I'm try this code, but it's not working:

    public static DateTime ToDateTime(this string date)

            {

                string format1 = "yyyy-MM-ddTHH:mm:sszzzz";

                string format2 = "MM/dd/yyyy HH:mm:ss";

                string format3 = "dd.MM.yyyy HH:mm:ss";

    string format4 = "yyyy-MM-ddTHH: mm: sszzzz";

                DateTime result = DateTime.ParseExact(date, new[] { format1, format2, format3 }, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None);

                return DateTime.ParseExact(date, "yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);

            }

    Friday, December 21, 2018 1:00 PM
  • User475983607 posted

    I need a universal function to replace dates. I have dates in the following format: 2015-12-01T00: 00: 00 + 00:00, 12/31/2018 01:00:00, 2015-12-01, 12/31/2018 etc. I need to get a date using the above function in the format "yyyy-MM-dd"

     As suggested above, come up with a plan for the date string formats you expect then simply parse the date strings into a DateTime.  

                DateTime temp = DateTime.Now;
    
                DateTime.TryParse("12/31/2018 01:00:00", out temp);
                Console.WriteLine(temp);
    
                DateTime.TryParse("2015-12-01", out temp);
                Console.WriteLine(temp);
    
                DateTime.TryParse("12/31/2018", out temp);
                Console.WriteLine(temp);
    
                DateTime.TryParse("2015-12-01T00:00:00+00:00", out temp);
                Console.WriteLine(temp);

    Results

    12/31/2018 1:00:00 AM
    12/1/2015 12:00:00 AM
    12/31/2018 12:00:00 AM
    11/30/2015 7:00:00 PM
    Press any key to continue . . .

    I'm in the EST time zone so the last DateTime is 5 hours off.

    To serialize the DateTime to yyyy-mm-dd format.

    temp.ToString("yyyy-MM-dd");

    Reference docs

    https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings

    https://docs.microsoft.com/en-us/dotnet/api/system.datetime.tryparse?view=netframework-4.7.2

    Friday, December 21, 2018 1:03 PM
  • User303363814 posted

    but it's not working:
    Can you provide a bit more detail.  Wrong result?  Doesn't compile? Runtime exception?

    Why do you compute the 'result' and then do another ParseExact?  Why not just return the 'result' that yo have calculated?

    Saturday, December 22, 2018 11:23 AM
  • User753101303 posted

    This is not because you kept the last line ???? Also you'll have both MM/dd/yyyy HH:mm:ss"; and "dd.MM.yyyy HH:mm:ss"; ?

    What is the real context ? You are importing data from multiple sources ? My first thought would be to be able to configure which date format is used for each source rather than trying to create a "catch all" method especially if you have contradictory formats. Once again you may have cases when you can't decide for sure which value you have unless knowing which convention is used.

    Try perhaps :

    using System;
    namespace Parse
    {
        class Program
        {
            public static DateTime ToDateTime(string date)
            {
                var format = new string[]{
                    "yyyy-MM-dd",
                    "yyyy-MM-ddTHH:mm:sszzzz",
                    "MM/dd/yyyy",
                    "MM/dd/yyyy HH:mm:ss",
                    "dd.MM.yyyy HH:mm:ss",
                    "yyyy-MM-ddTHH: mm: sszzzz" };
                    DateTime result = DateTime.ParseExact(date, format,System.Globalization.CultureInfo.InvariantCulture,System.Globalization.DateTimeStyles.None);
                return result;
            }
            static void Main(string[] args)
            {
                string[] values =
                {
                    "2015-12-01T00:00:00+00:00",
                    "12/31/2018 01:00:00",
                    "2015-12-01",
                    "12/31/2018"
                };
                foreach(var value in values)
                {
                    Console.WriteLine(ToDateTime(value).ToString(System.Globalization.CultureInfo.InvariantCulture));
                }
            }
        }
    }
    

    which shows :

    12/01/2015 01:00:00
    12/31/2018 01:00:00
    12/01/2015 00:00:00
    12/31/2018 00:00:00
    

    And add maybe other cases but wonder also pêrhaps why you have such a mess to start with...

    Saturday, December 22, 2018 1:02 PM
  • User-1716253493 posted

    Use

    If(tryParseExact(format1,str,null,out datevalue))
    {
    result=datevalue;
    } If(tryParseExact(format2,str,null,out datevalue))
    {
    result=datevalue;
    }
    If(tryParseExact(format3,str,null,out datevalue))
    {
    result=datevalue;
    }
    If(tryParseExact(format3,str,null,out datevalue))
    {
    result=datevalue;
    } return result;

    There are two datetime variable here, result and datevalue as tryparseexact output

    Monday, December 24, 2018 6:57 AM