// the value of epoch is different depending on time zone internal static System.DateTime GetEpoch(Time time) { if (time.gmt) { return Time.Epoch; } else { return Time.Epoch.ToLocalTime(); } }
internal static void GetParts(Time time, out long sec, out long usec) { long ticks = time.value.Ticks - Time.GetEpoch(time).Ticks; Time.GetParts(ticks, out sec, out usec); }
internal static Time time_mload(Frame caller, Time time, String str) // author: cjs/war, status: done { int p, s; int sec, usec; string buf; int i; System.DateTime tm; time_modify(caller, time); buf = str.value; if (str.value.Length != 8) { throw new TypeError("marshaled time format differ").raise(caller); } p = s = 0; for (i = 0; i < 4; i++) { p |= buf[i] << (8 * i); } for (i = 4; i < 8; i++) { s |= buf[i] << (8 * (i - 4)); } if ((p & (1 << 31)) == 0) { sec = p; usec = s; tm = new DateTime(sec * 100000000L + usec * 100L); } else { p &= ~(1 << 31); tm = new DateTime( ((p >> 14) & 0xffff) + 1900, //year ((p >> 10) & 0xf) + 1, //month //month is 0-11 in ruby, 1-12 in System.DateTime (p >> 5) & 0x1f, //day p & 0x1f, //hour (s >> 26) & 0x3f, //min (s >> 20) & 0x3f); //sec tm = tm.AddTicks((s & 0xfffff) * 10);//usec - DateTime constructor only supports up to msec } time.value = tm.ToLocalTime(); return time; }
internal static object time_add(Time tobj, object offset, int sign, Frame caller) { double v = Numeric.rb_num2dbl(offset, caller); double f, d; uint sec_off; // unsigned_time_t sec_off; long usec_off, sec, usec; //time_t object result; if (v < 0) { v = -v; sign = -sign; } d = Marshal.modf(v, out f); sec_off = (uint)f; if (f != (double)sec_off) { throw new RangeError(string.Format(CultureInfo.InvariantCulture, "time {0} {1} out of Time range", sign < 0 ? "-" : "+", v)).raise(caller); } usec_off = (long)(d * 1e6); Time.GetParts(tobj, out sec, out usec); if (sign < 0) { sec -= sec_off; usec -= usec_off; //wartag: C Ruby uses overflows here to test if the subtraction will fail //unfortunately it tests for overflow on a signed 32-bit integer so it won't fail //if time is subtracted less than -2^31 before epoch. Rather it will go on to throw //a different type of error later on from a different location. if (sec < -2147483648) throw new RangeError(string.Format(CultureInfo.InvariantCulture, "time - {0} out of Time range", v)).raise(caller); } else { //long tt = new Time(Time.EndTime)._tv_sec(); sec += sec_off; usec += usec_off; //wartag: simple rangeerror once we get over (2^31-1) if (sec > 2147483647) throw new RangeError(string.Format(CultureInfo.InvariantCulture, "time - {0} out of Time range", v)).raise(caller); } //Time.CheckAddition(tobj.value, Time.GetTicks(sec, usec), caller); Time.time_overflow_p(ref sec, ref usec, caller); result = new Time(new System.DateTime(Time.GetEpoch(tobj).Ticks + Time.GetTicks(sec, usec), tobj.value.Kind)); return result; }
internal static String time_mdump(Frame caller, Time timeRecv) // author: war, cjs, status: done { long p, s; DateTime time = timeRecv.value.ToUniversalTime(); int year = time.Year - 1900; //time is stored internally in ruby as years from 1900 if ((year & 0xffff) != year) //year must be able to be stored in 16-bits for marshalling purposes { throw new ArgumentError("year too big to marshal").raise(caller); } p = 0x1 << 31 | /* 1 */ year << 14 | /* 16 */ time.Month - 1 << 10 | /* 4 */ //month is 0-11 in ruby, 1-12 in System.DateTime time.Day << 5 | /* 5 */ time.Hour; /* 5 */ DateTime usecTime = new DateTime(time.Ticks); TimeSpan ts = usecTime.Subtract(new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second)); int usec = (int)ts.Ticks / 10; s = time.Minute << 26 | /* 6 */ time.Second << 20 | /* 6 */ usec; /* 20 */ char[] buf = new char[8]; for (int i = 0; i < 4; i++) { buf[i] = (char)(p & 0xff); p = p >> 8; } for (int i = 4; i < 8; i++) { buf[i] = (char)(s & 0xff); s = s >> 8; } return new String(new System.String(buf)); }
internal static Time time_dup(Time time, Frame caller, Proc block) { Time dup = (Time)time_s_alloc.singleton.Call0(null, Ruby.Runtime.Init.rb_cTime, caller, null); time_init_copy.singleton.Call1(null, dup, caller, block, time); return dup; }
internal static Time time_get_tm(Time time, bool gmt, Frame caller) { if (gmt) return (Time)Ruby.Methods.time_gmtime.singleton.Call0(null, time, caller, null); return (Time)Ruby.Methods.time_localtime.singleton.Call0(null, time, caller, null); }
internal static void time_modify(Frame caller, Time time) { TypeError.rb_check_frozen(caller, time); if (!time.Tainted && Eval.rb_safe_level() >= 4) throw new SecurityError("Insecure: can't modify Time").raise(caller); }
public override object Call0(Class last_class, object recv, Frame caller, Proc block) { Time tobj = new Time((Class)recv); tobj.tm_got = false; return tobj; }