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; }
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; }