コード例 #1
0
            /// <summary>
            /// ToValidValue - enforce max and min value of a nullable datetime
            /// SOURCE: https://stackoverflow.com/questions/3115678/converting-string-to-int-using-c-sharp
            /// </summary>
            /// <param name="dateToClean"></param>
            /// <returns></returns>
            public DateTime?ToValidValue(string dateToClean, DateTime dateMaxValue, DateTime dateMinValue, DateUtil.DataType dateDataType, DateUtil.Delim dateDelimiter, DateFormat dateFormat, bool expectTrailingAMorPM)
            {
                String[] strFormat = null;
                DateTime?tmpResult = null;

                try
                {
                    if (String.IsNullOrWhiteSpace(dateToClean))
                    {
                        tmpResult = null; //Always return null. Protects against a gigabyte of whitespace!!!
                    }
                    else
                    {
                        DateTime value;

                        if (DateTime.Compare(dateMinValue.ToUniversalTime(), dateMaxValue.ToUniversalTime()) > 0)
                        {
                            throw new Exception("Invalid parameters: minimum date cannot be greater than the maximum date.");
                        }

                        if (dateDelimiter == DateUtil.Delim.ForwardSlash)
                        {
                            if (dateToClean.IndexOf(@"/") == -1)
                            {
                                throw new Exception("Invalid date: missing forward slash delimiter.");
                            }
                        }
                        if (dateDelimiter == DateUtil.Delim.Dash)
                        {
                            if (dateToClean.IndexOf(@"-") == -1)
                            {
                                throw new Exception("Invalid date: missing dash delimiter.");
                            }
                        }

                        if (dateDelimiter == DateUtil.Delim.Dot)
                        {
                            if (dateToClean.IndexOf(@".") == -1)
                            {
                                throw new Exception("Invalid date: missing dot delimiter.");
                            }
                        }

                        //This includes Truncate to 33 chars (longest datetime format)
                        dateToClean = SaniCore.NormalizeOrLimit.ToASCIIDateTimesOnly(dateToClean, dateDelimiter, dateDataType, expectTrailingAMorPM);

                        #region Regex checks and strFormat assignment

                        DateRegex dateRegexObj = new DateRegex(SaniCore.CompileRegex);

                        //Perform specific Regex checks where possible after having already normalized the unicode string and reduced it to ASCII-like characters.
                        if ((dateDataType == DateUtil.DataType.Date) && (dateFormat == DateFormat.US)) //Delimiter slash, dash, or dot
                        {
                            strFormat = new string[] { "M/d/yyyy", "MM/dd/yyyy" };                     //Example 6/14/2020

                            if (dateDelimiter == DateUtil.Delim.Dot)
                            {
                                strFormat = new string[] { "M.d.yyyy", "MM.dd.yyyy" };
                            }
                            if (dateDelimiter == DateUtil.Delim.Dash)
                            {
                                strFormat = new string[] { "M-d-yyyy", "MM-dd-yyyy" };
                            }

                            dateRegexObj.PerformRegexForDateInUSFormat(dateToClean);
                        }

                        if ((dateDataType == DateUtil.DataType.Date) && (dateFormat == DateFormat.Euro)) //Delimiter slash, dash, or dot
                        {
                            strFormat = new string[] { "d/M/yyyy", "dd/MM/yyyy" };                       //Example 28/02/2005

                            if (dateDelimiter == DateUtil.Delim.Dot)
                            {
                                strFormat = new string[] { "d.M.yyyy", "dd.MM.yyyy" };
                            }
                            if (dateDelimiter == DateUtil.Delim.Dash)
                            {
                                strFormat = new string[] { "d-M-yyyy", "dd-MM-yyyy" };
                            }

                            dateRegexObj.PerformRegexForDateInEuroFormat(dateToClean);
                        }

                        if ((dateDataType == DateUtil.DataType.Date) && (dateFormat == DateFormat.China)) //Delimiter slash, dash, or dot
                        {
                            strFormat = new string[] { "yyyy/M/d", "yyyy/MM/dd" };                        //Example 2009/6/15

                            if (dateDelimiter == DateUtil.Delim.Dot)
                            {
                                strFormat = new string[] { "yyyy.M.d", "yyyy.MM.dd" };
                            }
                            if (dateDelimiter == DateUtil.Delim.Dash)
                            {
                                strFormat = new string[] { "yyyy-M-d", "yyyy-MM-dd" };
                            }

                            dateRegexObj.PerformRegexForDateInChineseFormat(dateToClean);
                        }

                        //Not the best regex here but we still have DateTime.ParseExact further below.
                        if ((dateDataType == DateUtil.DataType.DateTime) && (dateFormat == DateFormat.US)) //Delimiter slash, dash, or dot
                        {
                            strFormat = null;                                                              //Example 02/18/1753 15:15  NOTE: capital H indicates 24-hour time.

                            if (dateDelimiter == DateUtil.Delim.ForwardSlash)
                            {
                                strFormat = new string[] { "M/d/yyyy H:m", "MM/dd/yyyy H:m" };
                            }
                            if (dateDelimiter == DateUtil.Delim.Dot)
                            {
                                strFormat = new string[] { "M.d.yyyy H:m", "MM.dd.yyyy H:m" };
                            }
                            if (dateDelimiter == DateUtil.Delim.Dash)
                            {
                                strFormat = new string[] { "M-d-yyyy H:m", "MM-dd-yyyy H:m" };
                            }

                            dateRegexObj.PerformRegexForDateTimeInUSFormat(dateToClean);
                        }

                        //Not the best regex here but we still have DateTime.ParseExact further below.
                        if ((dateDataType == DateUtil.DataType.DateTimeWithSeconds) && (dateFormat == DateFormat.US) && !(dateDelimiter == DateUtil.Delim.UTCWithDelimiters || dateDelimiter == DateUtil.Delim.UTCWithoutDelimiters || dateDelimiter == DateUtil.Delim.UTCWithDelimitersAndZone)) //Delimiter slash, dash, or dot
                        {
                            strFormat = null;                                                                                                                                                                                                                                                     //Example 06/05/2009 15:15:33 or 06/05/2009 03:15:33 PM

                            //Date in US format with single space H:m:ss and with optional AM or PM
                            if (expectTrailingAMorPM == false)
                            {
                                if (dateDelimiter == DateUtil.Delim.ForwardSlash) //NOTE: capital H indicates 24-hour time.
                                {
                                    strFormat = new string[] { "M/d/yyyy H:m:s", "MM/dd/yyyy H:m:s" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dot)
                                {
                                    strFormat = new string[] { "M.d.yyyy H:m:s", "MM.dd.yyyy H:m:s" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dash)
                                {
                                    strFormat = new string[] { "M-d-yyyy H:m:s", "MM-dd-yyyy H:m:s" };
                                }
                            }
                            else //expect AM or PM
                            {
                                if (dateDelimiter == DateUtil.Delim.ForwardSlash) //NOTE: capital h indicates regular time not military.
                                {
                                    strFormat = new string[] { "M/d/yyyy h:m:s tt", "M/d/yyyy hh:mm:ss tt", "MM/dd/yyyy h:m:s tt", "MM/dd/yyyy hh:mm:ss tt" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dot)
                                {
                                    strFormat = new string[] { "M.d.yyyy h:m:s tt", "M.d.yyyy hh:mm:ss tt", "MM.dd.yyyy h:m:s tt", "MM.dd.yyyy hh:mm:ss tt" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dash)
                                {
                                    strFormat = new string[] { "M-d-yyyy h:m:s tt", "M-d-yyyy hh:mm:ss tt", "MM-dd-yyyy h:m:s tt", "MM-dd-yyyy hh:mm:ss tt" };
                                }
                            }

                            dateRegexObj.PerformRegexForDateTimeWithSecondsInUSFormat(dateToClean, expectTrailingAMorPM);
                        }

                        //Not the best regex here but we still have DateTime.ParseExact further below.
                        if ((dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) && (dateFormat == DateFormat.US)) //Delimiter slash, dash, or dot
                        {
                            strFormat = null;                                                                              //Example 06/05/2009 15:15:33.001 OR 06/05/2009 03:05:03.003 PM

                            //Date in US format with single space H:m:ss.fff and with optional AM or PM

                            //NOTE: M = single-digit month is formatted WITHOUT a leading zero. MM = single-digit month is formatted WITH a leading zero.
                            //      H = single-digit hour is formatted WITHOUT a leading zero.  HH = single-digit hour is formatted WITH a leading zero.
                            //      d = single-digit day is formatted WITHOUT a leading zero.   dd = single-digit day is formatted WITH a leading zero.
                            if (expectTrailingAMorPM == false)
                            {
                                if (dateDelimiter == DateUtil.Delim.ForwardSlash) //NOTE: capital H indicates 24-hour time.
                                {
                                    strFormat = new string[] { "M/d/yyyy H:m:s.fff", "MM/dd/yyyy H:m:s.fff", "MM/dd/yyyy HH:mm:ss.fff", "M/d/yyyy HH:m:s.fff" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dot)
                                {
                                    strFormat = new string[] { "M.d.yyyy H:m:s.fff", "MM.dd.yyyy H:m:s.fff", "MM.dd.yyyy HH:mm:ss.fff", "M.d.yyyy HH:m:s.fff" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dash)
                                {
                                    strFormat = new string[] { "M-d-yyyy H:m:s.fff", "MM-dd-yyyy H:m:s.fff", "MM-dd-yyyy HH:mm:ss.fff", "M-d-yyyy HH:m:s.fff" };
                                }
                            }
                            else //expect AM or PM
                            {
                                if (dateDelimiter == DateUtil.Delim.ForwardSlash) //NOTE: capital h indicates regular time not military.
                                {
                                    strFormat = new string[] { "M/d/yyyy h:m:s.fff tt", "M/d/yyyy hh:mm:ss.fff tt", "MM/dd/yyyy h:m:s.fff tt", "MM/dd/yyyy hh:mm:ss.fff tt" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dot)
                                {
                                    strFormat = new string[] { "M.d.yyyy h:m:s.fff tt", "M.d.yyyy hh:mm:ss.fff tt", "MM.dd.yyyy h:m:s.fff tt", "MM.dd.yyyy hh:mm:ss.fff tt" };
                                }
                                if (dateDelimiter == DateUtil.Delim.Dash)
                                {
                                    strFormat = new string[] { "M-d-yyyy h:m:s.fff tt", "M-d-yyyy hh:mm:ss.fff tt", "MM-dd-yyyy h:m:s.fff tt", "MM-dd-yyyy hh:mm:ss.fff tt" };
                                }
                            }

                            dateRegexObj.PerformRegexForDateTimeWithMillisecondsInUSFormat(dateToClean, expectTrailingAMorPM);
                        }

                        if ((dateDataType == DateUtil.DataType.SQLServerDateTime) && (dateFormat == DateFormat.SQLServer)) //Delimiter slash, dash, or dot
                        {
                            strFormat = strFormat = new string[] { "yyyy-MM-dd H:m:s.fff", "yyyy-MM-dd HH:mm:ss.fff" };    //Example 2019-01-25 16:01:36.000

                            //Date in SQL Server format
                            dateRegexObj.PerformRegexForDateTimeInSQLServerFormat(dateToClean);
                        }

                        if (dateDelimiter == DateUtil.Delim.UTCWithDelimiters)
                        {
                            //Example 2015-12-08T15:15:19
                            strFormat = new string[] { "yyyy-MM-dd'T'H:m:s", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'H:m:s'Z'", "yyyy-MM-dd'T'HH:mm:ss'Z'" };

                            dateRegexObj.PerformRegexForDateTimeWithSecondsAsUTCWithDelimiters(dateToClean);
                        }

                        if (dateDelimiter == DateUtil.Delim.UTCWithDelimitersAndZone)
                        {
                            //Example 2020-06-10T22:03:15-05:00
                            strFormat = new string[] { "yyyy-MM-dd'T'H:m:sK", "yyyy-MM-dd'T'HH:mm:ssK", "yyyy-MM-dd'T'H:m:sK'Z'", "yyyy-MM-dd'T'HH:mm:ssK'Z'" };
                            dateRegexObj.PerformRegexForDateTimeWithSecondsAsUTCWithDelimitersAndZone(dateToClean);
                        }

                        if (dateDelimiter == DateUtil.Delim.UTCWithoutDelimiters)
                        {
                            strFormat = new string[] { "yyyyMMdd'T'HHmmss", "yyyyMMdd'T'Hms", "yyyyMd'T'Hms" }; //Example 20151208T151519

                            //TODO: support yyyyMMdd'T'HHmmss.SSSZ with Milliseconds ?!?

                            dateRegexObj.PerformRegexForDateTimeWithSecondsAsUTCWithoutDelimiters(dateToClean);
                        }
                        #endregion

                        CultureInfo culture = null;

                        if (dateFormat == DateFormat.US || dateFormat == DateFormat.SQLServer) //Example 6/15/2009 1:45:30 PM
                        {
                            culture = CultureInfo.CreateSpecificCulture("en-US");
                        }

                        if (dateFormat == DateFormat.Euro)                        //Example 15/06/2009 13:45:30
                        {
                            culture = CultureInfo.CreateSpecificCulture("es-ES"); //Spain
                        }

                        if (dateFormat == DateFormat.China)                       //Example 2009/6/15 13:45:30
                        {
                            culture = CultureInfo.CreateSpecificCulture("zh-CN"); //China
                        }

                        try
                        {
                            value = DateTime.ParseExact(dateToClean, strFormat, culture, DateTimeStyles.None);
                        }
                        catch (FormatException)
                        {
                            throw new Exception("Unable to parse date.");
                        }

                        //SOURCE: https://blog.submain.com/4-common-datetime-mistakes-c-avoid/
                        if (DateTime.Compare(value.ToUniversalTime(), dateMinValue.ToUniversalTime()) < 0) //convert to utc prior to comparison
                        {
                            tmpResult = dateMinValue;                                                      //if minimum needs to be applied then apply it.
                        }
                        else //check for maximum
                        {
                            if (DateTime.Compare(value.ToUniversalTime(), dateMaxValue.ToUniversalTime()) > 0)
                            {
                                tmpResult = dateMaxValue;
                            }
                            else
                            {
                                tmpResult = value;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    SaniExceptionHandler.TrackOrThrowException(TruncateLength, SaniType, SaniCore, "MinMax: ", "Error datetime to valid MinMax value: ", dateToClean, ex);
                }
                return(tmpResult);
            }
コード例 #2
0
 /// <summary>
 /// ToValidValueUSDefault - enforce max and min value of a nullable datetime. Default max 1/1/2999 and min 1/1/1753 with US Format and no AM/PM.
 /// SOURCE: https://stackoverflow.com/questions/3115678/converting-string-to-int-using-c-sharp
 /// </summary>
 /// <param name="decimalToClean"></param>
 /// <returns></returns>
 public DateTime?ToValidValueUSDefault(string dateToClean, DateUtil.DataType dateDataType, DateUtil.Delim dateDelimiter)
 {
     return(SaniCore.MinMax.DateTimeType.ToValidValue(dateToClean, new DateTime(2999, 1, 1), new DateTime(1753, 1, 1), dateDataType, dateDelimiter, MinMax.DateFormat.US, false));
 }
コード例 #3
0
 /// <summary>
 /// ToValidValueUSDefault - enforce max and min value of a nullable datetime. Default max 1/1/2999 and min 1/1/1753.
 /// SOURCE: https://stackoverflow.com/questions/3115678/converting-string-to-int-using-c-sharp
 /// </summary>
 /// <param name="decimalToClean"></param>
 /// <returns></returns>
 public DateTime?ToValidValueUSDefault(string dateToClean, DateUtil.DataType dateDataType, DateUtil.Delim dateDelimiter, DateFormat dateFormat, bool expectTrailingAMorPM)
 {
     return(SaniCore.MinMax.DateTimeType.ToValidValue(dateToClean, new DateTime(2999, 1, 1), new DateTime(1753, 1, 1), dateDataType, dateDelimiter, dateFormat, expectTrailingAMorPM));
 }
コード例 #4
0
        /// <summary>
        /// Limit a Unicode string to just the limited subset of ASCII-compatible date times only, aka Latin numbers with date and time delimiters.
        /// </summary>
        /// <param name="strToClean"></param>
        /// <returns></returns>
        public string ToASCIIDateTimesOnly(string strToClean, DateUtil.Delim delimiter, DateUtil.DataType dateDataType, bool allowAMandPM)
        {
            string tmpResult = String.Empty;

            if (dateDataType == DateUtil.DataType.SQLServerDateTime)
            {
                dateDataType = DateUtil.DataType.DateTimeWithMilliseconds; //retain colon and space
            }

            try
            {
                if (string.IsNullOrWhiteSpace(strToClean))
                {
                    tmpResult = null; //Always return null. Protects against a gigabyte of whitespace!!!
                }
                else
                {
                    tmpResult = SaniCore.Truncate.ToValidLength(strToClean, 33);
                    tmpResult = tmpResult.Normalize(NormalizationForm.FormKC);//just to be extra safe

                    //Example 12-8-2015 15:15
                    if (delimiter == DateUtil.Delim.Dash && !(delimiter == DateUtil.Delim.UTCWithDelimiters || delimiter == DateUtil.Delim.UTCWithoutDelimiters || delimiter == DateUtil.Delim.UTCWithDelimitersAndZone))
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) || //Latin numbers
                                                                                    ((int)c == 45) || //45 = dash
                                                                                    (allowAMandPM ? (((int)c == 65) || ((int)c == 77) || ((int)c == 80) || ((int)c == 97) || ((int)c == 109) || ((int)c == 112)) : false) || //65 = A , 77 = M, 80 = P, 97 = a, 109 = m, 112 = p
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 32) : false) || //32 = space
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 58) : false) || //58 = colon
                                                                                    ((dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 46) : false) //46 = dot
                                                                                    )).ToArray()));
                    }

                    //Example 12.8.2015 15:15
                    if (delimiter == DateUtil.Delim.Dot && !(delimiter == DateUtil.Delim.UTCWithDelimiters || delimiter == DateUtil.Delim.UTCWithoutDelimiters || delimiter == DateUtil.Delim.UTCWithDelimitersAndZone))
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) ||
                                                                                    ((int)c == 46) || //46 = dot
                                                                                    (allowAMandPM ? (((int)c == 65) || ((int)c == 77) || ((int)c == 80) || ((int)c == 97) || ((int)c == 109) || ((int)c == 112)) : false) || //65 = A , 77 = M, 80 = P, 97 = a, 109 = m, 112 = p
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 32) : false) || //32 = space
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 58) : false) //58 = colon
                                                                                    )).ToArray()));
                    }

                    //Example 12/8/2015 15:15
                    if (delimiter == DateUtil.Delim.ForwardSlash && !(delimiter == DateUtil.Delim.UTCWithDelimiters || delimiter == DateUtil.Delim.UTCWithoutDelimiters || delimiter == DateUtil.Delim.UTCWithDelimitersAndZone))
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) ||
                                                                                    ((int)c == 47) || //47 = forward slash
                                                                                    (allowAMandPM ? (((int)c == 65) || ((int)c == 77) || ((int)c == 80) || ((int)c == 97) || ((int)c == 109) || ((int)c == 112)) : false) || //65 = A , 77 = M, 80 = P, 97 = a, 109 = m, 112 = p
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 32) : false) || //32 = space
                                                                                    ((dateDataType == DateUtil.DataType.DateTime || dateDataType == DateUtil.DataType.DateTimeWithSeconds || dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 58) : false) || //58 = colon
                                                                                    ((dateDataType == DateUtil.DataType.DateTimeWithMilliseconds) ? ((int)c == 46) : false) //46 = dot
                                                                                    )).ToArray()));
                    }

                    if (delimiter == DateUtil.Delim.UTCWithoutDelimiters) //yyyyMMdd'T'HHmmss.SSSZ
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) || //Latin numbers
                                                                                    ((int)c == 46) || //46 = dot
                                                                                    (((int)c == 84) || ((int)c == 90) || ((int)c == 32)) //84 = T, 90 = Z, 32 = space
                                                                                    )).ToArray()));
                    }

                    if (delimiter == DateUtil.Delim.UTCWithDelimitersAndZone) //yyyy-MM-dd'T'HH:mm:ssK EXAMPLE: 2020-06-10T22:03:15-05:00
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) || //Latin numbers
                                                                                    ((int)c == 45) || //45 = dash and minus sign
                                                                                    ((int)c == 58) || //58 = colon
                                                                                    ((int)c == 43) || //43 = plus sign
                                                                                    (((int)c == 84) || ((int)c == 90) || ((int)c == 32)) //84 = T, 90 = Z, 32 = space
                                                                                    )).ToArray()));
                    }

                    if (delimiter == DateUtil.Delim.UTCWithDelimiters) //yyyy-MM-dd'T'HH:mm:ss.SSSZZ  EXAMPLE: 2014-08-29T06:44:03Z
                    {
                        tmpResult = (new string(tmpResult.ToCharArray().Where(c => ((48 <= (int)c && (int)c <= 57) || //Latin numbers
                                                                                    ((int)c == 45) || //45 = dash
                                                                                    ((int)c == 58) || //58 = colon
                                                                                    (((int)c == 84) || ((int)c == 90) || ((int)c == 32)) //84 = T, 90 = Z, 32 = space
                                                                                    )).ToArray()));
                    }

                    //TODO: support 1995-07-14T13:05:00.0000000-03:00 ?!?
                }
            }
            catch (Exception ex)
            {
                SaniExceptionHandler.TrackOrThrowException(TruncateLength, SaniType, SaniCore, "NormalizeOrLimit: ", "Error limiting unicode to ASCII DateTimes Only: ", strToClean, ex);
            }
            return(tmpResult);
        }