/** Get generic GMT offset where offset is in seconds */ public static TimeZone fromGmtOffset(int offset) { if (offset == 0) { return(TimeZone.utc()); } else { return(TimeZone.fromStr("GMT" + (offset < 0 ? ("+" + (-offset / 3600)) : ("-" + (offset / 3600))))); } }
////////////////////////////////////////////////////////////////////////// // Parse ////////////////////////////////////////////////////////////////////////// internal DateTime parseDateTime(string s, TimeZone defTz, bool check) { try { // parse into fields tzOffset = System.Int32.MaxValue; parse(s); // now figure out what timezone to use TimeZone.Rule defRule = defTz.rule(year); if (tzName != null) { // use defTz if tzName was specified and matches any variations of defTz if (tzName == defTz.name() || tzName == defRule.stdAbbr || tzName == defRule.dstAbbr) { tz = defTz; } // try to map tzName to TimeZone, use defTz as fallback else { tz = TimeZone.fromStr(tzName, false); if (tz == null) { tz = defTz; } } } // if tzOffset was specified... else if (tzOffset != System.Int32.MaxValue) { // figure out what expected offset was for defTz int time = hour * 3600 + min * 60 + sec; int defOffset = defRule.offset + TimeZone.dstOffset(defRule, year, (int)mon.ordinal(), day, time); // if specified offset matches expected offset for defTz then // use defTz, otherwise use a vanilla GMT+/- timezone if (tzOffset == defOffset) { tz = defTz; } else { tz = TimeZone.fromGmtOffset(tzOffset); } } // no tzName or tzOffset specified, use defTz else { tz = defTz; } // construct DateTime return(new DateTime(year, (int)mon.ordinal(), day, hour, min, sec, ns, tzOffset, tz)); } catch (Exception) {} if (check) { throw ParseErr.make("DateTime", s).val; } return(null); }
private static DateTime fromStr(string s, bool check, bool iso) { try { // YYYY-MM-DD'T'hh:mm:ss int year = num(s, 0) * 1000 + num(s, 1) * 100 + num(s, 2) * 10 + num(s, 3); int month = num(s, 5) * 10 + num(s, 6) - 1; int day = num(s, 8) * 10 + num(s, 9); int hour = num(s, 11) * 10 + num(s, 12); int min = num(s, 14) * 10 + num(s, 15); int sec = num(s, 17) * 10 + num(s, 18); // check separator symbols if (s[4] != '-' || s[7] != '-' || s[10] != 'T' || s[13] != ':' || s[16] != ':') { throw new System.Exception(); } // optional .FFFFFFFFF int i = 19; int ns = 0; int tenth = 100000000; if (s[i] == '.') { ++i; while (true) { int c = s[i]; if (c < '0' || c > '9') { break; } ns += (c - '0') * tenth; tenth /= 10; ++i; } } // zone offset int offset = 0; int ch = s[i++]; if (ch != 'Z') { int offHour = num(s, i++) * 10 + num(s, i++); if (s[i++] != ':') { throw new System.Exception(); } int offMin = num(s, i++) * 10 + num(s, i++); offset = offHour * 3600 + offMin * 60; if (ch == '-') { offset = -offset; } else if (ch != '+') { throw new System.Exception(); } } // timezone - we share this method b/w fromStr and fromIso TimeZone tz; if (iso) { if (i < s.Length) { throw new System.Exception(); } tz = TimeZone.fromGmtOffset(offset); } else { if (s[i++] != ' ') { throw new System.Exception(); } tz = TimeZone.fromStr(s.Substring(i), true); } return(new DateTime(year, month, day, hour, min, sec, ns, offset, tz)); } catch (System.Exception) { if (!check) { return(null); } throw ParseErr.make("DateTime", s).val; } }