示例#1
0
文件: Date.cs 项目: wyerp/openpetra
        /// <summary>
        /// Converts a string to a formatted date string
        /// </summary>
        /// <param name="AParseDate">String which contains the date that should be converted</param>
        /// <param name="ADescription">String about the conversion type that is performed. This is
        /// used to gather error messages.</param>
        /// <param name="AParsedDate">String that holds the parsed date (if successful)</param>
        /// <param name="AShowVerificationError">true if error message box should be shown if conversion fails</param>
        /// <returns>true if successful, otherwise false</returns>
        public static Boolean LongDateStringToDateTimeInternal(String AParseDate,
                                                               String ADescription,
                                                               out object AParsedDate,
                                                               Boolean AShowVerificationError)
        {
            Boolean ReturnValue = false;
            Int32   DayOffset;
            String  TmpYear;
            String  TmpMonth;
            String  TmpDay;
            String  TmpMonthDayExchange = "";
            String  TmpShortDatePattern;
            Int16   YearStart = 0;
            Int16   RestStart = 0;

            AParsedDate = null;
            DateTimeFormatInfo CurrentDateTimeFormatInfo;

            // for testing purposes only
            // string TmpDateSeparator = CurrentDateTimeFormatInfo.DateSeparator;

            try
            {
                // TODO: implement parsing of localised short month names like 4GL does (according to user's default language setting), eg. accept 'M?R' instead of 'MAR' for March if the user's language setting is DE (German)
                // MessageBox.Show('AParseDate: ' + AParseDate);
                if (TDateChecks.IsValidDateTime(AParseDate, "") != null)
                {
                    // MessageBox.Show('No regular DateTime');
                    if ((AParseDate.StartsWith("-")) || ((AParseDate.StartsWith("+")) && (AParseDate.Length != 1)))
                    {
                        // MessageBox.Show('Calculating date from the amount that follows the + or  sign...');
                        // calculate date from the amount that follows the + or  sign
                        if (TNumericalChecks.IsValidInteger(AParseDate.Substring(1), "") == null)
                        {
                            DayOffset = System.Convert.ToInt32(AParseDate.Substring(1));

                            // MessageBox.Show('DayOffset: ' + DayOffset.ToString);
                            if (AParseDate.StartsWith("+"))
                            {
                                AParseDate = DateTime.Now.Date.AddDays(DayOffset).ToString("D");
                            }
                            else
                            {
                                AParseDate = DateTime.Now.Date.Subtract(new TimeSpan(DayOffset, 0, 0, 0)).ToString("D");
                            }
                        }
                        else
                        {
                            // characters following the + or  are not an Int32
                            MessageBox.Show(TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultText,
                                            TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultTextCaption);
                            return(ReturnValue);
                        }
                    }
                    else if (((AParseDate.Length <= 6) ||
                              (AParseDate.Length <= 8)) && (AParseDate.Length != 1) && (TNumericalChecks.IsValidInteger(AParseDate, "") == null))
                    {
//                        MessageBox.Show("Checking for dates entered like eg. 211105 or 21112005 ...");

                        /*
                         * Checking for dates entered like eg. 211105 or 21112005.
                         *
                         * Notes:
                         * Petra.NET accepts date entry dependent on current Culture
                         * (=settings are taken from Windows Control Panel -> Regional and
                         * Language Options).
                         * However, 4GL Petra parses dates according to the server-wide setting
                         * '-d'in startup.pf (Progress home directory). This should normally be
                         * the same than the Windows Control Panel setting on the user's
                         * machines, so there should be no deviation.
                         */
                        CurrentDateTimeFormatInfo = DateTimeFormatInfo.CurrentInfo;
                        TmpShortDatePattern       = CurrentDateTimeFormatInfo.ShortDatePattern.ToUpper();

                        // TmpShortDatePattern := "MM DD";      // For testing purposes only

                        if (TmpShortDatePattern.StartsWith("Y"))
                        {
                            YearStart = 0;

                            switch (AParseDate.Length)
                            {
                            case 8:
                                RestStart = 4;
                                break;

                            case 6:
                                RestStart = 2;
                                break;

                            case 4:
                                RestStart = 0;
                                YearStart = -1;
                                break;
                            }
                        }
                        else
                        {
                            RestStart = 0;

                            switch (AParseDate.Length)
                            {
                            case 6:
                            case 8:
                                YearStart = 4;
                                break;

                            case 4:
                                YearStart = -1;
                                break;
                            }
                        }

//MessageBox.Show("TmpShortDatePattern: " + TmpShortDatePattern + "; TmpDateSeparator: " + TmpDateSeparator +
//    "\r\nYearStart: " + YearStart.ToString() + "; RestStart: " + RestStart.ToString());
                        if (AParseDate.Length <= 6)
                        {
                            if (YearStart != -1)
                            {
                                TmpYear = AParseDate.Substring(YearStart, 2);

                                // Determine the correct century for twodigit years.

                                /* For compatibility reasons: This is the way how it's done in 4GL, */
                                /* in sp_date.p/ConvertStringToDate */
                                if (Convert.ToInt32(TmpYear) < 80)
                                {
                                    TmpYear = "20" + TmpYear;
                                }
                                else if (Convert.ToInt32(TmpYear) < 100)
                                {
                                    TmpYear = "19" + TmpYear;
                                }

                                /*  */
                                /* This would be the Windows way of doing it... */
                                /* I (ChristianK) found no way to retrieve the correct century from */
                                /* .NET, so it's hardcoded here, taking the default values of Windows */
                                /* XP :( */
                                /*  */
                                /* if Convert.ToInt32(TmpYear) <= 29 then */
                                /* begin */
                                /* TmpYear := '20' + TmpYear; */
                                /* end */
                                /* else */
                                /* begin */
                                /* TmpYear := '19' + TmpYear; */
                                /* end; */
                            }
                            else
                            {
                                TmpYear = DateTime.Now.Year.ToString();
                            }

//MessageBox.Show("TmpYear: " + TmpYear);
                        }
                        else
                        {
                            TmpYear = AParseDate.Substring(YearStart, 4);
                        }

                        if ((AParseDate.Length == 4) || (AParseDate.Length == 6) || (AParseDate.Length == 8))
                        {
                            if (TmpShortDatePattern.IndexOf('M') < TmpShortDatePattern.IndexOf('D'))
                            {
                                TmpMonth = AParseDate.Substring(RestStart, 2);
                                TmpDay   = AParseDate.Substring(RestStart + 2, 2);
                            }
                            else
                            {
                                TmpDay   = AParseDate.Substring(RestStart, 2);
                                TmpMonth = AParseDate.Substring(RestStart + 2, 2);
                            }
                        }
                        else
                        {
                            // format with other number of digits not supported
                            MessageBox.Show(TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultText,
                                            TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultTextCaption);

                            return(ReturnValue);
                        }

                        if (Convert.ToInt16(TmpMonth) > 12)
                        {
                            TmpMonthDayExchange = TmpMonth;
                            TmpMonth            = TmpDay;
                            TmpDay = TmpMonthDayExchange;
                        }

                        // AParseDate := TmpYear + TmpDateSeparator + TmpMonth + TmpDateSeparator + TmpDay;    For testing purposes
                        // MessageBox.Show('AParseDate (1): ' + AParseDate);    For testing purposes
                        try
                        {
                            AParseDate = new DateTime(Convert.ToInt32(TmpYear), Convert.ToInt32(TmpMonth), Convert.ToInt32(TmpDay)).ToString("D");

                            // TmpMonth + '/' + TmpDay + '/' + TmpYear;

                            if (TmpMonthDayExchange != "")
                            {
                                MessageBox.Show(StrMonthDayExchangedInfo, StrMonthDayExchangedInfoTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            }
                        }
                        catch (Exception)
                        {
                            MessageBox.Show(TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultText,
                                            TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultTextCaption);
                            return(ReturnValue);
                        }

//MessageBox.Show("TmpShortDatePattern: " + TmpShortDatePattern + "; TmpDateSeparator: " + TmpDateSeparator +
//                                        "\r\nYearStart: " + YearStart.ToString() + "; RestStart: " + RestStart.ToString() +
//"; TmpDay: " + TmpDay + "; TmpMonth: " + TmpMonth + "; TmpYear: " + TmpYear + "\r\nAParseDate: " + AParseDate);
                        AParsedDate = AParseDate;
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else if (AParseDate == "")
                    {
//MessageBox.Show("Value = \"");
                        AParsedDate = DBNull.Value;
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else if ((AParseDate == "=") || (AParseDate == "+") || (AParseDate.ToLower() == "today"))
                    {
                        AParsedDate = DateTime.Now.ToString("D");
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else
                    {
                        if (AShowVerificationError)
                        {
                            // not an accepted date parse string
                            MessageBox.Show(TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultText,
                                            TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultTextCaption);
                        }

                        return(ReturnValue);
                    }
                }

                // AParseDate ready to be parsed
                AParsedDate = DateTime.Parse(AParseDate).ToString("D");
                ReturnValue = true;
            }
            catch (Exception)
            {
                MessageBox.Show(TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultText,
                                TDateChecks.GetInvalidDateVerificationResult(ADescription).ResultTextCaption);
            }

            return(ReturnValue);
        }
示例#2
0
        /// <summary>
        /// todoComment
        /// </summary>
        /// <param name="AParseDate"></param>
        /// <param name="ADescription"></param>
        /// <param name="AParsedDate"></param>
        /// <param name="AShowVerificationError"></param>
        /// <param name="ATypeWhichCallsVerification"></param>
        /// <returns></returns>
        private static Boolean LongDateStringToDateTimeInternal(String AParseDate,
                                                                String ADescription,
                                                                out object AParsedDate,
                                                                Boolean AShowVerificationError,
                                                                System.Type ATypeWhichCallsVerification)
        {
            Boolean ReturnValue;
            Int32   DayOffset;
            String  TmpYear;
            String  TmpMonth;
            String  TmpDay;
            String  TmpMonthDayExchange = "";
            String  TmpShortDatePattern;
            Int16   YearStart = 0;
            Int16   RestStart = 0;

            // see StringHelper.DateToLocalizedString
            // Mono and .Net return different strings for month of March in german culture

            TExecutingOSEnum OSVersion = Utilities.DetermineExecutingOS();

            bool   IsPossiblyWin10 = ((OSVersion == TExecutingOSEnum.eosWin8Plus) || (OSVersion == TExecutingOSEnum.eosWin10));
            string CurrentCulture  = Thread.CurrentThread.CurrentCulture.ToString();

            List <string> CulturesToIgnore = new List <string>();

            CulturesToIgnore.Add("de-BE");
            CulturesToIgnore.Add("de-CH");
            CulturesToIgnore.Add("de-LI");
            CulturesToIgnore.Add("de-LU");

            if ((CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "de") &&
                !(CurrentCulture == "de-AT") &&
                !(IsPossiblyWin10 && CulturesToIgnore.Contains(CurrentCulture)))
            {
                AParseDate = AParseDate.Replace("MÄR", "MRZ");
            }

            AParsedDate = null;
            DateTimeFormatInfo CurrentDateTimeFormatInfo;

            ReturnValue = false;
            try
            {
                // TODO: implement parsing of localised short month names like 4GL does (according to user's default language setting), eg. accept 'M�R' instead of 'MAR' for March if the user's language setting is DE (German)
                // MessageBox.Show('AParseDate: ' + AParseDate);
                if (TDateChecks.IsValidDateTime(AParseDate, "") != null)
                {
                    // MessageBox.Show('No regular DateTime');
                    if ((AParseDate.StartsWith("-")) || ((AParseDate.StartsWith("+")) && (AParseDate.Length != 1)))
                    {
                        // MessageBox.Show('Calculating date from the amount that follows the + or  sign...');
                        // calculate date from the amount that follows the + or  sign
                        if (TNumericalChecks.IsValidInteger(AParseDate.Substring(1), "") == null)
                        {
                            DayOffset = System.Convert.ToInt32(AParseDate.Substring(1));

                            // MessageBox.Show('DayOffset: ' + DayOffset.ToString);
                            if (AParseDate.StartsWith("+"))
                            {
                                AParseDate = DateTime.Now.Date.AddDays(DayOffset).ToString("D");
                            }
                            else
                            {
                                AParseDate = DateTime.Now.Date.Subtract(new TimeSpan(DayOffset, 0, 0, 0)).ToString("D");
                            }
                        }
                        else
                        {
                            // characters following the + or  are not an Int32
                            if (AShowVerificationError)
                            {
                                TMessages.MsgGeneralError(TDateChecks.GetInvalidDateVerificationResult(ADescription), ATypeWhichCallsVerification);
                            }

                            return(ReturnValue);
                        }
                    }
                    else if ((AParseDate.Length <= 8) &&
                             (AParseDate.Length != 1) &&
                             (TNumericalChecks.IsValidInteger(AParseDate, "") == null))
                    {
//                        MessageBox.Show("Checking for dates entered like eg. 211105 or 21112005 ...");

                        /*
                         * Checking for dates entered like eg. 211105 or 21112005.
                         *
                         * Notes:
                         * Petra.NET accepts date entry dependent on current Culture
                         * (=settings are taken from Windows Control Panel -> Regional and
                         * Language Options).
                         * However, 4GL Petra parses dates according to the server-wide setting
                         * '-d'in startup.pf (Progress home directory). This should normally be
                         * the same than the Windows Control Panel setting on the user's
                         * machines, so there should be no deviation.
                         */
                        CurrentDateTimeFormatInfo = DateTimeFormatInfo.CurrentInfo;
                        TmpShortDatePattern       = CurrentDateTimeFormatInfo.ShortDatePattern.ToUpper();

                        if (TmpShortDatePattern.StartsWith("Y"))
                        {
                            YearStart = 0;

                            switch (AParseDate.Length)
                            {
                            case 8:
                                RestStart = 4;
                                break;

                            case 6:
                                RestStart = 2;
                                break;

                            case 4:
                                RestStart = 0;
                                YearStart = -1;
                                break;
                            }
                        }
                        else
                        {
                            RestStart = 0;

                            switch (AParseDate.Length)
                            {
                            case 6:
                            case 8:
                                YearStart = 4;
                                break;

                            case 4:
                                YearStart = -1;
                                break;
                            }
                        }

//MessageBox.Show("TmpShortDatePattern: " + TmpShortDatePattern + "; TmpDateSeparator: " + TmpDateSeparator +
//    "\r\nYearStart: " + YearStart.ToString() + "; RestStart: " + RestStart.ToString());
                        if (AParseDate.Length <= 6)
                        {
                            if (YearStart != -1)
                            {
                                TmpYear = AParseDate.Substring(YearStart, 2);

                                // Determine the correct century for twodigit years.
                                // For compatibility reasons: This is the way how it's done in 4GL,
                                // in sp_date.p/ConvertStringToDate
                                if (Convert.ToInt32(TmpYear) < 80)
                                {
                                    TmpYear = "20" + TmpYear;
                                }
                                else if (Convert.ToInt32(TmpYear) < 100)
                                {
                                    TmpYear = "19" + TmpYear;
                                }

                                //
                                // This would be the Windows way of doing it...
                                // I (ChristianK) found no way to retrieve the correct century from
                                // .NET, so it's hardcoded here, taking the default values of Windows
                                // XP :(
                                //
                                // if Convert.ToInt32(TmpYear) <= 29 then
                                // begin
                                // TmpYear := '20' + TmpYear;
                                // end
                                // else
                                // begin
                                // TmpYear := '19' + TmpYear;
                                // end;
                            }
                            else
                            {
                                TmpYear = DateTime.Now.Year.ToString();
                            }
                        }
                        else
                        {
                            TmpYear = AParseDate.Substring(YearStart, 4);
                        }

                        if ((AParseDate.Length == 4) || (AParseDate.Length == 6) || (AParseDate.Length == 8))
                        {
                            if (TmpShortDatePattern.IndexOf('M') < TmpShortDatePattern.IndexOf('D'))
                            {
                                TmpMonth = AParseDate.Substring(RestStart, 2);
                                TmpDay   = AParseDate.Substring(RestStart + 2, 2);
                            }
                            else
                            {
                                TmpDay   = AParseDate.Substring(RestStart, 2);
                                TmpMonth = AParseDate.Substring(RestStart + 2, 2);
                            }
                        }
                        else
                        {
                            // format with other number of digits not supported
                            if (AShowVerificationError)
                            {
                                TMessages.MsgGeneralError(TDateChecks.GetInvalidDateVerificationResult(ADescription), ATypeWhichCallsVerification);
                            }

                            return(ReturnValue);
                        }

                        if (Convert.ToInt16(TmpMonth) > 12)
                        {
                            TmpMonthDayExchange = TmpMonth;
                            TmpMonth            = TmpDay;
                            TmpDay = TmpMonthDayExchange;
                        }

                        // AParseDate := TmpYear + TmpDateSeparator + TmpMonth + TmpDateSeparator + TmpDay;    For testing purposes
                        // MessageBox.Show('AParseDate (1): ' + AParseDate);    For testing purposes
                        try
                        {
                            // TmpMonth + '/' + TmpDay + '/' + TmpYear;
                            AParseDate = new DateTime(Convert.ToInt32(TmpYear), Convert.ToInt32(TmpMonth), Convert.ToInt32(TmpDay)).ToString("D");

                            if (TmpMonthDayExchange != "")
                            {
                                MessageBox.Show(StrMonthDayExchangedInfo, StrMonthDayExchangedInfoTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            }
                        }
                        catch (Exception)
                        {
                            if (AShowVerificationError)
                            {
                                TMessages.MsgGeneralError(TDateChecks.GetInvalidDateVerificationResult(ADescription), ATypeWhichCallsVerification);
                            }

                            return(ReturnValue);
                        }

//MessageBox.Show("TmpShortDatePattern: " + TmpShortDatePattern + "; TmpDateSeparator: " + TmpDateSeparator +
//                                        "\r\nYearStart: " + YearStart.ToString() + "; RestStart: " + RestStart.ToString() +
//"; TmpDay: " + TmpDay + "; TmpMonth: " + TmpMonth + "; TmpYear: " + TmpYear + "\r\nAParseDate: " + AParseDate);
                        AParsedDate = AParseDate;
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else if (AParseDate == string.Empty)
                    {
                        AParsedDate = DBNull.Value;
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else if ((AParseDate == "=") || (AParseDate == "+") || (AParseDate.ToLower() == Catalog.GetString("today").ToLower()))
                    {
                        AParsedDate = DateTime.Now.ToString("D");
                        ReturnValue = true;
                        return(ReturnValue);
                    }
                    else
                    {
                        if (AShowVerificationError)
                        {
                            // not an accepted date parse string
                            TMessages.MsgGeneralError(TDateChecks.GetInvalidDateVerificationResult(ADescription), ATypeWhichCallsVerification);
                        }

                        return(ReturnValue);
                    }
                }

                // AParseDate ready to be parsed
                AParsedDate = DateTime.Parse(AParseDate).ToString("D");
                ReturnValue = true;
            }
            catch (Exception /* Exp */)
            {
                if (AShowVerificationError)
                {
                    TMessages.MsgGeneralError(TDateChecks.GetInvalidDateVerificationResult(ADescription), ATypeWhichCallsVerification);
                }
            }

            return(ReturnValue);
        }