// tries to parse a string with a relative time specification
        private static DateTime?Parse_relative(string dateStr, JavaCalendar now)
        {
            JavaCalendar cal;
            SystemReader sysRead = SystemReader.GetInstance();

            // check for the static words "yesterday" or "now"
            if ("now".Equals(dateStr))
            {
                return((now == null) ? Sharpen.Extensions.CreateDate(sysRead.GetCurrentTime()) :
                       now.GetTime());
            }
            if (now == null)
            {
                cal = new JavaGregorianCalendar(sysRead.GetTimeZone(), sysRead.GetLocale());
                cal.SetTimeInMillis(sysRead.GetCurrentTime());
            }
            else
            {
                cal = (JavaCalendar)now.Clone();
            }
            if ("yesterday".Equals(dateStr))
            {
                cal.Add(JavaCalendar.DATE, -1);
                cal.Set(JavaCalendar.HOUR_OF_DAY, 0);
                cal.Set(JavaCalendar.MINUTE, 0);
                cal.Set(JavaCalendar.SECOND, 0);
                cal.Set(JavaCalendar.MILLISECOND, 0);
                cal.Set(JavaCalendar.MILLISECOND, 0);
                return(cal.GetTime());
            }
            // parse constructs like "3 days ago", "5.week.2.day.ago"
            string[] parts       = dateStr.RegexSplit("\\.| ");
            int      partsLength = parts.Length;

            // check we have an odd number of parts (at least 3) and that the last
            // part is "ago"
            if (partsLength < 3 || (partsLength & 1) == 0 || !"ago".Equals(parts[parts.Length
                                                                                 - 1]))
            {
                return(null);
            }
            int number;

            for (int i = 0; i < parts.Length - 2; i += 2)
            {
                try
                {
                    number = System.Convert.ToInt32(parts[i]);
                }
                catch (FormatException)
                {
                    return(null);
                }
                if ("year".Equals(parts[i + 1]) || "years".Equals(parts[i + 1]))
                {
                    cal.Add(JavaCalendar.YEAR, -number);
                }
                else
                {
                    if ("month".Equals(parts[i + 1]) || "months".Equals(parts[i + 1]))
                    {
                        cal.Add(JavaCalendar.MONTH, -number);
                    }
                    else
                    {
                        if ("week".Equals(parts[i + 1]) || "weeks".Equals(parts[i + 1]))
                        {
                            cal.Add(JavaCalendar.WEEK_OF_YEAR, -number);
                        }
                        else
                        {
                            if ("day".Equals(parts[i + 1]) || "days".Equals(parts[i + 1]))
                            {
                                cal.Add(JavaCalendar.DATE, -number);
                            }
                            else
                            {
                                if ("hour".Equals(parts[i + 1]) || "hours".Equals(parts[i + 1]))
                                {
                                    cal.Add(JavaCalendar.HOUR_OF_DAY, -number);
                                }
                                else
                                {
                                    if ("minute".Equals(parts[i + 1]) || "minutes".Equals(parts[i + 1]))
                                    {
                                        cal.Add(JavaCalendar.MINUTE, -number);
                                    }
                                    else
                                    {
                                        if ("second".Equals(parts[i + 1]) || "seconds".Equals(parts[i + 1]))
                                        {
                                            cal.Add(JavaCalendar.SECOND, -number);
                                        }
                                        else
                                        {
                                            return(null);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(cal.GetTime());
        }