| 1 |
/********************************************************************** |
| 2 |
|
| 3 |
time.c - |
| 4 |
|
| 5 |
$Author: matz $ |
| 6 |
$Date: 2001/12/13 08:12:59 $ |
| 7 |
created at: Tue Dec 28 14:31:59 JST 1993 |
| 8 |
|
| 9 |
Copyright (C) 1993-2000 Yukihiro Matsumoto |
| 10 |
|
| 11 |
**********************************************************************/ |
| 12 |
/* |
| 13 |
Copyright(C) 2001-2002 arton |
| 14 |
|
| 15 |
Permission is granted for use, copying, modification, distribution, |
| 16 |
and distribution of modified versions of this work as long as the |
| 17 |
above copyright notice is included. |
| 18 |
*/ |
| 19 |
using System; |
| 20 |
using System.Diagnostics; |
| 21 |
using System.Collections; |
| 22 |
using System.Text; |
| 23 |
using System.Threading; |
| 24 |
using System.Reflection; |
| 25 |
using System.Globalization; |
| 26 |
|
| 27 |
namespace arton.NETRuby |
| 28 |
{ |
| 29 |
public class RTime : RData, ICloneable, IComparable |
| 30 |
{ |
| 31 |
internal RTime(NetRuby rb) : |
| 32 |
base(rb, rb.cTime) |
| 33 |
{ |
| 34 |
utc = false; |
| 35 |
time = DateTime.Now; |
| 36 |
} |
| 37 |
internal RTime(NetRuby rb, RMetaObject meta) : |
| 38 |
base(rb, meta) |
| 39 |
{ |
| 40 |
utc = false; |
| 41 |
time = DateTime.Now; |
| 42 |
} |
| 43 |
internal RTime(NetRuby rb, long ftime) : |
| 44 |
base(rb, rb.cTime) |
| 45 |
{ |
| 46 |
utc = false; |
| 47 |
time = DateTime.FromFileTime(ftime); |
| 48 |
} |
| 49 |
internal RTime(NetRuby rb, DateTime tm) : |
| 50 |
base(rb, rb.cTime) |
| 51 |
{ |
| 52 |
utc = false; |
| 53 |
time = tm; |
| 54 |
} |
| 55 |
|
| 56 |
public int CompareTo(object o) |
| 57 |
{ |
| 58 |
if (o is RTime == false) |
| 59 |
{ |
| 60 |
long l = RInteger.ToLong(ruby, o); |
| 61 |
return ToLong().CompareTo(l); |
| 62 |
} |
| 63 |
return time.CompareTo(((RTime)o).time); |
| 64 |
} |
| 65 |
|
| 66 |
public override bool Eql(object o) |
| 67 |
{ |
| 68 |
if (o is RTime == false) return false; |
| 69 |
RTime t = (RTime)o; |
| 70 |
return (time == t.time); |
| 71 |
} |
| 72 |
|
| 73 |
public override int GetHashCode() // for voiding CS0659 warning. |
| 74 |
{ |
| 75 |
return base.GetHashCode(); |
| 76 |
} |
| 77 |
public override bool Equals(object o) |
| 78 |
{ |
| 79 |
if (o is RTime == false) return false; |
| 80 |
return o.GetHashCode() == GetHashCode(); |
| 81 |
} |
| 82 |
|
| 83 |
public long ToLong() // time_t |
| 84 |
{ |
| 85 |
long l = time.ToFileTime(); |
| 86 |
l -= RTimeClass.Epoch; |
| 87 |
l /= 10000000; |
| 88 |
return l; |
| 89 |
} |
| 90 |
public double ToDouble() |
| 91 |
{ |
| 92 |
return (double)time.ToFileTime(); |
| 93 |
} |
| 94 |
public override RInteger ToInteger() |
| 95 |
{ |
| 96 |
long l = ToLong(); |
| 97 |
if (l <= Int32.MaxValue) |
| 98 |
return new RFixnum(ruby, (int)l); |
| 99 |
return new RBignum(ruby, l); |
| 100 |
} |
| 101 |
public override RFloat ToFloat() |
| 102 |
{ |
| 103 |
long l = time.ToFileTime(); |
| 104 |
l -= RTimeClass.Epoch; |
| 105 |
return new RFloat(ruby, l / 10000000.0); |
| 106 |
} |
| 107 |
public override string ToString() |
| 108 |
{ |
| 109 |
if (utc) |
| 110 |
return time.ToUniversalTime().ToString("ddd MMM dd HH:mm:ss \\G\\M\\T yyyy", |
| 111 |
USFormat); |
| 112 |
else |
| 113 |
return time.ToString("ddd MMM dd HH:mm:ss \\L\\M\\T yyyy", USFormat); |
| 114 |
} |
| 115 |
|
| 116 |
internal RTime CopyFormat(RTime t) |
| 117 |
{ |
| 118 |
utc = t.utc; |
| 119 |
return this; |
| 120 |
} |
| 121 |
public DateTime ToDateTime() |
| 122 |
{ |
| 123 |
return time; |
| 124 |
} |
| 125 |
public object Clone() |
| 126 |
{ |
| 127 |
return MemberwiseClone(); |
| 128 |
} |
| 129 |
|
| 130 |
DateTime time; |
| 131 |
bool utc; |
| 132 |
static IFormatProvider USFormat = CultureInfo.CreateSpecificCulture("en-US").DateTimeFormat; |
| 133 |
} |
| 134 |
|
| 135 |
public class RTimeClass : RClass |
| 136 |
{ |
| 137 |
private RTimeClass(NetRuby rb) : |
| 138 |
base(rb, "Time", rb.cObject) |
| 139 |
{ |
| 140 |
} |
| 141 |
|
| 142 |
static internal object s_now(RBasic r, params object[] args) |
| 143 |
{ |
| 144 |
return new RTime(r.ruby, (RMetaObject)r); |
| 145 |
} |
| 146 |
static internal object s_new(RBasic r, params object[] args) |
| 147 |
{ |
| 148 |
object o = s_now(r, args); |
| 149 |
r.ruby.CallInit(o, args); |
| 150 |
return o; |
| 151 |
} |
| 152 |
static internal object s_at(RBasic r, params object[] args) |
| 153 |
{ |
| 154 |
NetRuby rb = r.ruby; |
| 155 |
object[] argv = new object[2]; |
| 156 |
long tmv = 0; |
| 157 |
long usec = 0; |
| 158 |
RTime result = null; |
| 159 |
int cnt = rb.ScanArgs(args, "11", argv); |
| 160 |
if (argv[0] is RTime) |
| 161 |
{ |
| 162 |
DateTime tm = ((RTime)argv[0]).ToDateTime(); |
| 163 |
if (cnt == 2) |
| 164 |
{ |
| 165 |
usec = RInteger.ToLong(rb, argv[1]); |
| 166 |
usec *= 10; |
| 167 |
result = new RTime(rb, tm.ToFileTime() + usec); |
| 168 |
} |
| 169 |
else |
| 170 |
{ |
| 171 |
result = new RTime(rb, tm); |
| 172 |
} |
| 173 |
result.CopyFormat((RTime)argv[0]); |
| 174 |
} |
| 175 |
else |
| 176 |
{ |
| 177 |
if (cnt == 2) |
| 178 |
{ |
| 179 |
tmv = RInteger.ToLong(rb, argv[0]); |
| 180 |
usec = RInteger.ToLong(rb, argv[1]); |
| 181 |
usec *= 10; |
| 182 |
} |
| 183 |
else |
| 184 |
{ |
| 185 |
tmv = RInteger.ToLong(rb, argv[0]); |
| 186 |
} |
| 187 |
// Adjust Unix Epoch to .NET |
| 188 |
tmv *= 1000; // mill second |
| 189 |
tmv *= 10000; // 100-nanosecond |
| 190 |
tmv += epoch; |
| 191 |
tmv += usec; |
| 192 |
result = new RTime(rb, tmv); |
| 193 |
} |
| 194 |
return result; |
| 195 |
} |
| 196 |
static readonly long epoch = (new DateTime(1970, 1, 1, 0, 0, 0)).ToFileTime(); |
| 197 |
public static long Epoch |
| 198 |
{ |
| 199 |
get { return epoch; } |
| 200 |
} |
| 201 |
static internal object s_mkutc(RBasic r, params object[] args) |
| 202 |
{ |
| 203 |
return null; |
| 204 |
} |
| 205 |
static internal object s_mktime(RBasic r, params object[] args) |
| 206 |
{ |
| 207 |
return null; |
| 208 |
} |
| 209 |
static internal object s_times(RBasic r, params object[] args) |
| 210 |
{ |
| 211 |
return null; |
| 212 |
} |
| 213 |
static internal object to_i(RBasic r, params object[] args) |
| 214 |
{ |
| 215 |
return ((RTime)r).ToInteger(); |
| 216 |
} |
| 217 |
static internal object to_f(RBasic r, params object[] args) |
| 218 |
{ |
| 219 |
return ((RTime)r).ToFloat(); |
| 220 |
} |
| 221 |
static internal object cmp(RBasic r, params object[] args) |
| 222 |
{ |
| 223 |
return ((IComparable)r).CompareTo(args[0]); |
| 224 |
} |
| 225 |
static internal object plus(RBasic r, params object[] args) |
| 226 |
{ |
| 227 |
NetRuby rb = r.ruby; |
| 228 |
if (args[0] is RTime) |
| 229 |
{ |
| 230 |
throw new eTypeError("time + time?"); |
| 231 |
} |
| 232 |
long l = RInteger.ToLong(rb, args[0]); |
| 233 |
l += ((RTime)r).ToLong(); |
| 234 |
RTime result = new RTime(rb, l * 10000000 + RTimeClass.Epoch); |
| 235 |
return result.CopyFormat((RTime)r); |
| 236 |
} |
| 237 |
static internal object minus(RBasic r, params object[] args) |
| 238 |
{ |
| 239 |
NetRuby rb = r.ruby; |
| 240 |
if (args[0] is RTime) |
| 241 |
{ |
| 242 |
double d = ((RTime)args[0]).ToDouble(); |
| 243 |
return new RFloat(rb, (((RTime)r).ToDouble() - d) / 10000000); |
| 244 |
} |
| 245 |
|
| 246 |
long l = ((RTime)r).ToLong() - RInteger.ToLong(rb, args[0]); |
| 247 |
RTime result = new RTime(rb, l * 10000000 + RTimeClass.Epoch); |
| 248 |
return result.CopyFormat((RTime)r); |
| 249 |
} |
| 250 |
internal static void Init(NetRuby rb) |
| 251 |
{ |
| 252 |
RTimeClass t = new RTimeClass(rb); |
| 253 |
t.DefineClass("Time", rb.cObject); |
| 254 |
rb.cTime = t; |
| 255 |
|
| 256 |
t.DefineSingletonMethod("now", new RMethod(s_now), 0); |
| 257 |
t.DefineSingletonMethod("new", new RMethod(s_new), -1); |
| 258 |
t.DefineSingletonMethod("at", new RMethod(s_at), -1); |
| 259 |
t.DefineSingletonMethod("utc", new RMethod(s_mkutc), -1); |
| 260 |
t.DefineSingletonMethod("gm", new RMethod(s_mkutc), -1); |
| 261 |
t.DefineSingletonMethod("local", new RMethod(s_mktime), -1); |
| 262 |
t.DefineSingletonMethod("mktime", new RMethod(s_mktime), -1); |
| 263 |
|
| 264 |
t.DefineSingletonMethod("times", new RMethod(s_times), 0); |
| 265 |
|
| 266 |
t.DefineMethod("to_i", new RMethod(to_i), 0); |
| 267 |
t.DefineMethod("to_f", new RMethod(to_f), 0); |
| 268 |
t.DefineMethod("<=>", new RMethod(cmp), 1); |
| 269 |
|
| 270 |
t.DefineMethod("+", new RMethod(plus), 1); |
| 271 |
t.DefineMethod("-", new RMethod(minus), 1); |
| 272 |
} |
| 273 |
} |
| 274 |
} |