예제 #1
0
 static bool ParseDateOrTime(FuncContext fctx, string date, ref DateTime p)
 {
     double r = 0.0;
     if (!ParseYyyyMmDd(date, p)) return false;
     else if (!ParseHhMmSs(date, p)) return false;
     else if (date.Equals("now", StringComparison.InvariantCultureIgnoreCase)) return SetDateTimeToCurrent(fctx, p);
     else if (ConvertEx.Atof(date, ref r, date.Length, TEXTENCODE.UTF8))
     {
         p.JD = (long)(r * 86400000.0 + 0.5);
         p.ValidJD = true;
         return false;
     }
     return true;
 }
예제 #2
0
        static RC ParseModifier(FuncContext fctx, string mod, DateTime p)
        {
            RC rc = RC.ERROR;
            int n;
            double r = 0;
            StringBuilder z = new StringBuilder(mod.ToLower());
            _zdtBuf.Length = 0;
            switch (z[0])
#if !OMIT_LOCALTIME
            {
                case 'l':
                    {
                        // localtime - Assuming the current time value is UTC (a.k.a. GMT), shift it to show local time.
                        if (z.ToString() == "localtime")
                        {
                            ComputeJD(p);
                            p.JD += LocaltimeOffset(p, fctx, out rc);
                            ClearYMD_HMS_TZ(p);
                        }
                        break;
                    }
#endif
                case 'u':
                    {
                        // unixepoch - Treat the current value of p->iJD as the number of seconds since 1970.  Convert to a real julian day number.
                        if (z.ToString() == "unixepoch" && p.ValidJD)
                        {
                            p.JD = (long)((p.JD + 43200) / 86400 + 210866760000000L);
                            ClearYMD_HMS_TZ(p);
                            rc = RC.OK;
                        }
#if !OMIT_LOCALTIME
                        else if (z.ToString() == "utc")
                        {
                            ComputeJD(p);
                            long c1 = LocaltimeOffset(p, fctx, out rc);
                            if (rc == RC.OK)
                            {
                                p.JD -= c1;
                                ClearYMD_HMS_TZ(p);
                                p.JD += c1 - LocaltimeOffset(p, fctx, out rc);
                            }
                        }
#endif
                        break;
                    }
                case 'w':
                    {
                        // weekday N - Move the date to the same time on the next occurrence of weekday N where 0==Sunday, 1==Monday, and so forth.  If the date is already on the appropriate weekday, this is a no-op.
                        if (z.ToString().StartsWith("weekday ") && ConvertEx.Atof(z.ToString().Substring(8), ref r, z.ToString().Substring(8).Length, TEXTENCODE.UTF8) && (n = (int)r) == r && n >= 0 && r < 7)
                        {
                            ComputeYMD_HMS(p);
                            p.ValidTZ = false;
                            p.ValidJD = false;
                            ComputeJD(p);
                            long Z = ((p.JD + 129600000) / 86400000) % 7;
                            if (Z > n) Z -= 7;
                            p.JD += (n - Z) * 86400000;
                            ClearYMD_HMS_TZ(p);
                            rc = RC.OK;
                        }
                        break;
                    }
                case 's':
                    {
                        // start of TTTTT - Move the date backwards to the beginning of the current day, or month or year.
                        if (z.Length <= 9) z.Length = 0;
                        else z.Remove(0, 9);
                        ComputeYMD(p);
                        p.ValidHMS = true;
                        p.h = p.m = 0;
                        p.s = 0.0;
                        p.ValidTZ = false;
                        p.ValidJD = false;
                        if (z.ToString() == "month")
                        {
                            p.D = 1;
                            rc = RC.OK;
                        }
                        else if (z.ToString() == "year")
                        {
                            ComputeYMD(p);
                            p.M = 1;
                            p.D = 1;
                            rc = RC.OK;
                        }
                        else if (z.ToString() == "day")
                            rc = RC.OK;
                        break;
                    }
                case '+':
                case '-':
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    {
                        for (n = 1; n < z.Length && z[n] != ':' && !char.IsWhiteSpace(z[n]); n++) { }
                        if (!ConvertEx.Atof(z.ToString(), ref r, n, TEXTENCODE.UTF8))
                        {
                            rc = RC.ERROR;
                            break;
                        }
                        if (z[n] == ':')
                        {
                            // A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the specified number of hours, minutes, seconds, and fractional seconds
                            // to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be omitted.
                            string z2 = z.ToString();
                            int z2Idx = 0;
                            if (!char.IsWhiteSpace(z2[z2Idx])) z2Idx++;
                            DateTime tx = new DateTime();
                            if (ParseHhMmSs(z2.Substring(z2Idx), tx)) break;
                            ComputeJD(tx);
                            tx.JD -= 43200000;
                            long day = tx.JD / 86400000;
                            tx.JD -= day * 86400000;
                            if (z[0] == '-') tx.JD = -tx.JD;
                            ComputeJD(p);
                            ClearYMD_HMS_TZ(p);
                            p.JD += tx.JD;
                            rc = RC.OK;
                            break;
                        }
                        while (char.IsWhiteSpace(z[n])) n++; z = z.Remove(0, n);
                        n = z.Length;
                        if (n > 10 || n < 3) break;
                        if (z[n - 1] == 's') z.Length = --n;
                        ComputeJD(p);
                        rc = RC.OK;
                        double rounder = (r < 0 ? -0.5 : +0.5);
                        if (n == 3 && z.ToString() == "day") p.JD += (long)(r * 86400000.0 + rounder);
                        else if (n == 4 && z.ToString() == "hour") p.JD += (long)(r * (86400000.0 / 24.0) + rounder);
                        else if (n == 6 && z.ToString() == "minute") p.JD += (long)(r * (86400000.0 / (24.0 * 60.0)) + rounder);
                        else if (n == 6 && z.ToString() == "second") p.JD += (long)(r * (86400000.0 / (24.0 * 60.0 * 60.0)) + rounder);
                        else if (n == 5 && z.ToString() == "month")
                        {
                            ComputeYMD_HMS(p);
                            p.M += (int)r;
                            int x = (p.M > 0 ? (p.M - 1) / 12 : (p.M - 12) / 12);
                            p.Y += x;
                            p.M -= x * 12;
                            p.ValidJD = false;
                            ComputeJD(p);
                            int y = (int)r;
                            if (y != r)
                                p.JD += (long)((r - y) * 30.0 * 86400000.0 + rounder);
                        }
                        else if (n == 4 && z.ToString() == "year")
                        {
                            int y = (int)r;
                            ComputeYMD_HMS(p);
                            p.Y += y;
                            p.ValidJD = false;
                            ComputeJD(p);
                            if (y != r)
                                p.JD += (long)((r - y) * 365.0 * 86400000.0 + rounder);
                        }
                        else
                            rc = RC.ERROR;
                        ClearYMD_HMS_TZ(p);
                        break;
                    }
                default: break;
            }
            return rc;
        }