1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 namespace System
  7 {
  8     public class TimePoint
  9     {
 10         public nothrow TimePoint() : nanosecs(0)
 11         {
 12         }
 13         public explicit nothrow TimePoint(long nanosecs_) : nanosecs(nanosecs_)
 14         {
 15         }
 16         public inline nothrow long Rep() const
 17         {
 18             return nanosecs;
 19         }
 20         private long nanosecs;
 21     }
 22     
 23     public class Duration
 24     {
 25         public nothrow Duration() : nanosecs(0)
 26         {
 27         }
 28         public explicit nothrow Duration(long nanosecs_) : nanosecs(nanosecs_)
 29         {
 30         }
 31         public nothrow long Hours() const
 32         {
 33             return nanosecs / (3600 * long(1000000000));
 34         }
 35         public nothrow long Minutes() const
 36         {
 37             return nanosecs / (60 * long(1000000000));
 38         }
 39         public nothrow long Seconds() const
 40         {
 41             return nanosecs / long(1000000000);
 42         }
 43         public nothrow long Milliseconds() const
 44         {
 45             return nanosecs / long(1000000);
 46         }
 47         public nothrow long Microseconds() const
 48         {
 49             return nanosecs / long(1000);
 50         }
 51         public nothrow long Nanoseconds() const
 52         {
 53             return nanosecs;
 54         }
 55         public static nothrow Duration FromHours(long hours)
 56         {
 57             return Duration(3600 * long(1000000000) * hours);
 58         }
 59         public static nothrow Duration FromMinutes(long minutes)
 60         {
 61             return Duration(60 * long(1000000000) * minutes);
 62         }
 63         public static nothrow Duration FromSeconds(long seconds)
 64         {
 65             return Duration(long(1000000000) * seconds);
 66         }
 67         public static nothrow Duration FromMilliseconds(long milliseconds)
 68         {
 69             return Duration(long(1000000) * milliseconds);
 70         }
 71         public static nothrow Duration FromMicroseconds(long microseconds)
 72         {
 73             return Duration(long(1000) * microseconds);
 74         }
 75         public static nothrow Duration FromNanoseconds(long nanoseconds)
 76         {
 77             return Duration(nanoseconds);
 78         }
 79         public inline nothrow long Rep() const
 80         {
 81             return nanosecs;
 82         }
 83         private long nanosecs;
 84     }
 85 
 86     public inline nothrow bool operator==(const Duration& leftconst Duration& right)
 87     {
 88         return left.Rep() == right.Rep();
 89     }
 90 
 91     public inline nothrow bool operator<(const Duration& leftconst Duration& right)
 92     {
 93         return left.Rep() < right.Rep();
 94     }
 95 
 96     public inline nothrow bool operator==(const TimePoint& leftconst TimePoint& right)
 97     {
 98         return left.Rep() == right.Rep();
 99     }
100 
101     public inline nothrow bool operator<(const TimePoint& leftconst TimePoint& right)
102     {
103         return left.Rep() < right.Rep();
104     }
105 
106     public inline nothrow Duration operator+(const Duration& leftconst Duration& right)
107     {
108         return Duration(left.Rep() + right.Rep());
109     }
110 
111     public inline nothrow Duration operator-(const Duration& leftconst Duration& right)
112     {
113         return Duration(left.Rep() - right.Rep());
114     }
115 
116     public inline nothrow Duration operator*(const Duration& leftconst Duration& right)
117     {
118         return Duration(left.Rep() * right.Rep());
119     }
120 
121     public inline nothrow Duration operator/(const Duration& leftconst Duration& right)
122     {
123         return Duration(left.Rep() / right.Rep());
124     }
125 
126     public inline nothrow Duration operator%(const Duration& leftconst Duration& right)
127     {
128         return left.Rep() % right.Rep();
129     }
130 
131     public inline nothrow Duration operator-(const TimePoint& leftconst TimePoint& right)
132     {
133         long diff = left.Rep() - right.Rep();
134         return Duration(diff);
135     }
136 
137     public inline nothrow TimePoint operator+(const TimePoint& tpconst Duration& d)
138     {
139         return TimePoint(tp.Rep() + d.Rep());
140     }
141 
142     public inline nothrow TimePoint operator+(const Duration& dconst TimePoint& tp)
143     {
144         return TimePoint(tp.Rep() + d.Rep());
145     }
146 
147     public inline nothrow TimePoint operator-(const TimePoint& tpconst Duration& d)
148     {
149         return TimePoint(tp.Rep() - d.Rep());
150     }
151     
152     public nothrow TimePoint Now()
153     {
154         return TimePoint(current_time_point());
155     }
156     
157     public void Sleep(const Duration& duration)
158     {
159         int result = sleep(duration.Rep());
160         if (result == -1)
161         {
162             ThrowSystemError();
163         }
164     }
165     
166     public void Times(Duration& userTimeDuration& sleepTimeDuration& systemTime)
167     {
168         long userTm = 0;
169         long sleepTm = 0;
170         long systemTm = 0;
171         int result = times(&userTm&sleepTm&systemTm);
172         if (result == -1)
173         {
174             ThrowSystemError();
175         }
176         userTime = Duration(userTm);
177         sleepTime = Duration(sleepTm);
178         systemTime = Duration(systemTm);
179     }
180     
181     public void ChildTimes(Duration& userTimeDuration& sleepTimeDuration& systemTime)
182     {
183         long userTm = 0;
184         long sleepTm = 0;
185         long systemTm = 0;
186         int result = child_times(&userTm&sleepTm&systemTm);
187         if (result == -1)
188         {
189             ThrowSystemError();
190         }
191         userTime = Duration(userTm);
192         sleepTime = Duration(sleepTm);
193         systemTime = Duration(systemTm);
194     }
195 
196     public nothrow string HourStr(const Duration& duration)
197     {
198         string s;
199         long hours = duration.Hours();
200         long hh = hours % 24;
201         s.Append(cast<char>(cast<byte>('0') + cast<byte>(hh / 10 % 10)));
202         s.Append(cast<char>(cast<byte>('0') + cast<byte>(hh % 10)));
203         return s;
204     }
205     
206     public nothrow string MinuteStr(const Duration& duration)
207     {
208         string s;
209         long minutes = duration.Minutes();
210         long mm = minutes % 60;
211         s.Append(cast<char>(cast<byte>('0') + cast<byte>(mm / 10 % 10)));
212         s.Append(cast<char>(cast<byte>('0') + cast<byte>(mm % 10)));
213         return s;
214     }
215     
216     public nothrow string SecondStr(const Duration& duration)
217     {
218         string s;
219         long seconds = duration.Seconds();
220         long ss = seconds % 60;
221         s.Append(cast<char>(cast<byte>('0') + cast<byte>(ss / 10 % 10)));
222         s.Append(cast<char>(cast<byte>('0') + cast<byte>(ss % 10)));
223         return s;
224     }
225     
226     public nothrow string MillisecondStr(const Duration& duration)
227     {
228         string s;
229         long milliseconds = duration.Milliseconds();
230         long ms = milliseconds % 1000;
231         s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms / 100 % 10)));
232         s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms / 10 % 10)));
233         s.Append(cast<char>(cast<byte>('0') + cast<byte>(ms % 10)));
234         return s;
235     }
236     
237     public nothrow string MicrosecondStr(const Duration& duration)
238     {
239         string s;
240         long microseconds = duration.Microseconds();
241         long us = microseconds % 1000;
242         s.Append(cast<char>(cast<byte>('0') + cast<byte>(us / 100 % 10)));
243         s.Append(cast<char>(cast<byte>('0') + cast<byte>(us / 10 % 10)));
244         s.Append(cast<char>(cast<byte>('0') + cast<byte>(us % 10)));
245         return s;
246     }
247 
248     public nothrow string DurationStr(const Duration& duration)
249     {
250         string s;
251         s.Append(HourStr(duration));
252         s.Append(':');
253         s.Append(MinuteStr(duration));
254         s.Append(':');
255         s.Append(SecondStr(duration));
256         s.Append('.');
257         s.Append(MillisecondStr(duration));
258         s.Append('.');
259         s.Append(MicrosecondStr(duration));
260         return s;
261     }
262     
263     public enum Month : sbyte
264     {
265          january = 1februarymarchaprilmayjunejulyaugustseptemberoctobernovemberdecember
266     }
267     
268     public class Date
269     {
270         public nothrow Date() : year(0)month(Month.january)day(1)
271         {
272         }
273         public nothrow Date(short year_Month month_sbyte day_) : year(year_)month(month_)day(day_)
274         {
275         }
276         public inline nothrow short Year() const
277         {
278             return year;
279         }
280         public inline nothrow Month GetMonth() const
281         {
282             return month;
283         }
284         public inline nothrow sbyte Day() const
285         {
286             return day;
287         }
288         public nothrow string ToString() const
289         {
290             return this->ToString(false);
291         }
292         public nothrow string ToString(bool omitDashes) const
293         {
294             string date;
295             date.Append(cast<char>(cast<short>('0') + ((year / 1000) % 10)));
296             date.Append(cast<char>(cast<short>('0') + ((year / 100) % 10)));
297             date.Append(cast<char>(cast<short>('0') + ((year / 10) % 10)));
298             date.Append(cast<char>(cast<short>('0') + (year % 10)));
299             if (!omitDashes)
300             {
301                 date.Append('-');
302             }
303             date.Append(cast<char>(cast<sbyte>('0') + ((cast<sbyte>(month) / 10) % 10)));
304             date.Append(cast<char>(cast<sbyte>('0') + (cast<sbyte>(month) % 10)));
305             if (!omitDashes)
306             {
307                 date.Append('-');
308             }
309             date.Append(cast<char>(cast<sbyte>('0') + ((day / 10) % 10)));
310             date.Append(cast<char>(cast<sbyte>('0') + (day % 10)));
311             return date;
312         }
313         private short year;
314         private Month month;
315         private sbyte day;
316     }
317     
318     public nothrow Date GetCurrentDate()
319     {
320         short y;
321         sbyte m;
322         sbyte d;
323         current_date(&y&m&d);
324         return Date(ycast<Month>(m)d);
325     }
326     
327     public nothrow bool operator==(const Date& leftconst Date& right)
328     {
329         return left.Year() == right.Year() && left.GetMonth() == right.GetMonth() && left.Day() == right.Day();
330     }
331     
332     public nothrow bool operator<(const Date& leftconst Date& right)
333     {
334         if (left.Year() < right.Year()) return true;
335         if (left.Year() > right.Year()) return false;
336         if (left.GetMonth() < right.GetMonth()) return true;
337         if (left.GetMonth() > right.GetMonth()) return false;
338         return left.Day() < right.Day();
339     }
340     
341     public class DateTime
342     {
343         public nothrow DateTime() : date()secs(0)
344         {
345         }
346         public nothrow DateTime(Date date_) : date(date_)secs(0)
347         {
348         }
349         public nothrow DateTime(Date date_int secs_) : date(date_)secs(secs_)
350         {
351         }
352         public inline nothrow Date GetDate() const
353         {
354             return date;
355         }
356         public inline nothrow int Hours() const
357         {
358             return secs / 3600;
359         }
360         public inline nothrow int Minutes() const
361         {
362             return secs / 60;
363         }
364         public inline nothrow int Seconds() const
365         {
366             return secs;
367         }
368         public nothrow string TimeString() const
369         {
370             string timeString;
371             int hh = Hours() % 24;
372             int mm = Minutes() % 60;
373             int ss = Seconds() % 60;
374             timeString.Append(cast<char>(cast<int>('0') + ((hh / 10) % 10)));
375             timeString.Append(cast<char>(cast<int>('0') + (hh % 10)));
376             timeString.Append(':');
377             timeString.Append(cast<char>(cast<int>('0') + ((mm / 10) % 10)));
378             timeString.Append(cast<char>(cast<int>('0') + (mm % 10)));
379             timeString.Append(':');
380             timeString.Append(cast<char>(cast<int>('0') + ((ss / 10) % 10)));
381             timeString.Append(cast<char>(cast<int>('0') + (ss % 10)));
382             return timeString;
383         }
384         public nothrow string ToString()
385         {
386             return this->ToString(falsefalsefalsefalse);
387         }
388         public nothrow string ToString(bool omitDashesbool omitColonsbool omitMinsbool omitSecs)
389         {
390             string dateTime = date.ToString(omitDashes);
391             dateTime.Append('T');
392             int hh = Hours() % 24;
393             int mm = Minutes() % 60;
394             int ss = Seconds() % 60;
395             dateTime.Append(cast<char>(cast<int>('0') + ((hh / 10) % 10)));
396             dateTime.Append(cast<char>(cast<int>('0') + (hh % 10)));
397             if (!omitMins)
398             {
399                 if (!omitColons)
400                 {
401                     dateTime.Append(':');
402                 }
403                 dateTime.Append(cast<char>(cast<int>('0') + ((mm / 10) % 10)));
404                 dateTime.Append(cast<char>(cast<int>('0') + (mm % 10)));
405                 if (!omitSecs)
406                 {
407                     if (!omitColons)
408                     {
409                         dateTime.Append(':');
410                     }
411                     dateTime.Append(cast<char>(cast<int>('0') + ((ss / 10) % 10)));
412                     dateTime.Append(cast<char>(cast<int>('0') + (ss % 10)));
413                 }
414             }
415             return dateTime;
416         }
417         private Date date;
418         private int secs;
419     }
420     
421     public nothrow DateTime GetCurrentDateTime()
422     {
423         short y;
424         sbyte m;
425         sbyte d;
426         int secs;
427         current_date_time(&y&m&d&secs);
428         return DateTime(Date(ycast<Month>(m)d)secs);
429     }
430     
431     public nothrow bool operator==(const DateTime& leftconst DateTime& right)
432     {
433         return left.GetDate() == right.GetDate() && left.Seconds() == right.Seconds();
434     }
435     
436     public nothrow bool operator<(const DateTime& leftconst DateTime& right)
437     {
438         if (left.GetDate() < right.GetDate()) return true;
439         if (left.GetDate() > right.GetDate()) return false;
440         return left.Seconds() < right.Seconds();
441     }
442 }