time.monkey2 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #Import "native/time.h"
  2. #Import "native/time.cpp"
  3. Namespace std.time
  4. Private
  5. Function to_ticks:Long( time:libc.time_t )
  6. Local secs:Long
  7. If libc.sizeof( time )=8
  8. secs=Cast<Long Ptr>( Varptr time )[0]
  9. Else If libc.sizeof( time )=4
  10. secs=Cast<Int Ptr>( Varptr time )[0]
  11. Else
  12. RuntimeError( "time_t error" )
  13. Endif
  14. Return secs*TimeSpan.TicksPerSecond
  15. End
  16. Function to_time:libc.time_t( ticks:Long )
  17. Local secs:=ticks/TimeSpan.TicksPerSecond
  18. Local time:libc.time_t
  19. If libc.sizeof<libc.time_t>()=8
  20. time=Cast<libc.time_t Ptr>( Varptr secs )[0]
  21. Else If libc.sizeof<libc.time_t>()=4
  22. Local isecs:=Int( secs )
  23. time=Cast<libc.time_t Ptr>( Varptr isecs )[0]
  24. Else
  25. RuntimeError( "time_t error" )
  26. Endif
  27. Return time
  28. End
  29. Extern
  30. #rem monkeydoc Gets the number of seconds elapsed since the app started.
  31. #end
  32. Function Now:Double()="bbTime::now"
  33. #rem monkeydoc Puts thread to sleep.
  34. Note: this will also cause all fibers to sleep.
  35. #end
  36. Function Sleep( seconds:Double )="bbTime::sleep"
  37. Public
  38. #rem monkeydoc Gets the number of microseconds since the app started.
  39. #end
  40. Function Microsecs:Long()
  41. Return Now() * 1000000
  42. End
  43. #rem monkeydoc Gets the number of milliseconds since the app started.
  44. #end
  45. Function Millisecs:Int()
  46. Return Now() * 1000
  47. End
  48. #rem monkeydoc TimeSpan class.
  49. A time span represents the difference between 2 times. A time span can also be thought of as 'duration' or 'interval'.
  50. Time spans are produced by subtracting times, and can be added to times to produce new times that are 'in the future' or 'in the past'.
  51. Internally, a timespan is represented by a single signed 64 bit ticks value. A tick is 1 ten millionth of a second.
  52. #end
  53. Struct TimeSpan
  54. Const TicksPerMillisec:=Long( 10000 )
  55. Const TicksPerSecond:=TicksPerMillisec*1000
  56. Const TicksPerMinute:=TicksPerSecond*60
  57. Const TicksPerHour:=TicksPerMinute*60
  58. Const TicksPerDay:=TicksPerHour*24
  59. #rem monkeydoc Creates a new TimeSpan
  60. #end
  61. Method New( days:Int,hours:Int,minutes:Int,seconds:Int,millisecs:Int )
  62. _ticks=days*TicksPerDay + hours*TicksPerHour + minutes*TicksPerMinute + seconds*TicksPerSecond + millisecs*TicksPerMillisec
  63. End
  64. Method New( ticks:Long )
  65. _ticks=ticks
  66. End
  67. #rem monkeydoc Converts the time span to a string.
  68. #end
  69. Operator To:String()
  70. Return "TimeSpan("+Days+","+Hours+","+Minutes+","+Seconds+","+Millisecs+")"
  71. End
  72. #rem monkeydoc Days in the time span.
  73. #end
  74. Property Days:Int()
  75. Return _ticks/TicksPerDay
  76. End
  77. #rem monkeydoc Hours in the time span.
  78. #end
  79. Property Hours:Int()
  80. Return (_ticks Mod TicksPerDay)/TicksPerHour
  81. End
  82. #rem monkeydoc Minutes in the time span.
  83. #end
  84. Property Minutes:Int()
  85. Return (_ticks Mod TicksPerHour)/TicksPerMinute
  86. End
  87. #rem monkeydoc Seconds in the time span.
  88. #end
  89. Property Seconds:Int()
  90. Return (_ticks Mod TicksPerMinute)/TicksPerSecond
  91. End
  92. #rem monkeydoc Millisecs in the time span.
  93. #end
  94. Property Millisecs:Int()
  95. Return (_ticks Mod TicksPerSecond)/TicksPerMillisec
  96. End
  97. #rem monkeydoc Ticks in the time span.
  98. #end
  99. Property Ticks:Long()
  100. Return _ticks
  101. End
  102. #rem monkeydoc Total days in the time span.
  103. #end
  104. Property TotalDays:Int()
  105. Return _ticks/TicksPerDay
  106. End
  107. #rem monkeydoc Total hours in the time span.
  108. #end
  109. Property TotalHours:Int()
  110. Return _ticks/TicksPerHour
  111. End
  112. #rem monkeydoc Total minutes in the time span.
  113. #end
  114. Property TotalMinutes:Int()
  115. Return _ticks/TicksPerMinute
  116. End
  117. #rem monkeydoc Total seconds in the time span.
  118. #end
  119. Property TotalSeconds:Int()
  120. Return _ticks/TicksPerSecond
  121. End
  122. #rem monkeydoc Total milliseconds in the time span.
  123. #end
  124. Property TotalMillisecs:Int()
  125. Return _ticks/TicksPerMillisec
  126. End
  127. Private
  128. Field _ticks:Long
  129. End
  130. #rem monkeydoc The Time class.
  131. The Time class represents a point in time.
  132. Note that the current implementation of the time class only has second precision.
  133. On some 32 bit targets, it may also be suject to the year 2038 problem:
  134. https://en.wikipedia.org/wiki/Year_2038_problem
  135. #end
  136. Class Time
  137. Const DayNames:=New String[]( "Sun","Mon","Tue","Wed","Thu","Fri","Sat" )
  138. Const MonthNames:=New String[]( "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" )
  139. #rem monkeydoc Creates a new time.
  140. Creating a time with no parameters creates a time representing 'now' in local time.
  141. #end
  142. Method New()
  143. Local ticks:=to_ticks( libc.time( Null ) )
  144. Init( ticks )
  145. End
  146. Method New( day:Int,month:Int,year:Int,hours:Int,minutes:Int,seconds:Int )
  147. Local tm:libc.tm_t
  148. tm.tm_mday=day
  149. tm.tm_mon=month
  150. tm.tm_year=year-1900
  151. tm.tm_hour=hours
  152. tm.tm_min=minutes
  153. tm.tm_sec=seconds
  154. Local ticks:=to_ticks( libc.mktime( Varptr tm ) )
  155. Init( ticks )
  156. End
  157. #rem monkeydoc Seconds (0-61)
  158. May include 'leap' seconds.
  159. #end
  160. Property Seconds:Int()
  161. Return _tm.tm_sec
  162. End
  163. #rem monkeydoc Minutes (0-59)
  164. #end
  165. Property Minutes:Int()
  166. Return _tm.tm_min
  167. End
  168. #rem monkeydoc Hours since midnight (0-23)
  169. #end
  170. Property Hours:Int()
  171. Return _tm.tm_hour
  172. End
  173. #rem monkeydoc Day of the month (1-31)
  174. #end
  175. Property Day:Int()
  176. Return _tm.tm_mday
  177. End
  178. #rem monkeydoc Week day since Sunday (0-6)
  179. #end
  180. Property WeekDay:Int()
  181. Return _tm.tm_wday
  182. End
  183. #rem monkeydoc Days since January 1 (0-365)
  184. #end
  185. Property YearDay:Int()
  186. Return _tm.tm_yday
  187. End
  188. #rem monkeydoc Month since January (0-11)
  189. #end
  190. Property Month:Int()
  191. Return _tm.tm_mon
  192. End
  193. #rem monkeydoc Year
  194. #end
  195. Property Year:Int()
  196. Return _tm.tm_year+1900
  197. End
  198. #rem monkeydoc True if daylight savings is in effect.
  199. #end
  200. Property DaylightSavings:Bool()
  201. Return _tm.tm_isdst
  202. End
  203. #rem monkeydoc Converts time to a string.
  204. #end
  205. Operator To:String()
  206. Return ToString()
  207. End
  208. #rem monkeydoc Converts time to a string.
  209. The string format is: WeekDay Day Month Year Hours:Minutes:Seconds
  210. #end
  211. Method ToString:String()
  212. local day:=("0"+Day).Slice( -2 )
  213. Local hours:=("0"+Hours).Slice( -2 )
  214. Local minutes:=("0"+Minutes).Slice( -2 )
  215. Local seconds:=("0"+Seconds).Slice( -2 )
  216. Return DayNames[ WeekDay ]+" "+day+" "+MonthNames[ Month ]+" "+Year+" "+hours+":"+minutes+":"+seconds
  217. End
  218. #rem monkeydoc Overloaded comparison operator.
  219. Time x is 'less than' time y if time x represents a time 'earlier' than time y.
  220. #end
  221. Operator<=>:Int( time:Time )
  222. Return _ticks<=>time._ticks
  223. End
  224. #rem monkeydoc Overloaded subtraction operator.
  225. Subtracts `time` from self and return a new [[TimeSpan]].
  226. #end
  227. Operator-:TimeSpan( time:Time )
  228. Return New TimeSpan( _ticks-time._ticks )
  229. End
  230. #rem monkeydoc Overloaded addition operator.
  231. Adds `timeSpan` to self and returns a new Time.
  232. #end
  233. Operator+:Time( timeSpan:TimeSpan )
  234. Return New Time( _ticks+timeSpan.Ticks )
  235. End
  236. #rem monkeydoc Gets current time.
  237. #end
  238. Function Now:Time()
  239. Local ticks:=to_ticks( libc.time( Null ) )
  240. Return New Time( ticks )
  241. End
  242. #rem monkeydoc Parses a time from a string.
  243. The string format is: 'WeekDay' Day 'Month' Year Hours:Minutes:Seconds.
  244. WeekDay may be omitted.
  245. #end
  246. Function Parse:Time( str:String )
  247. Local p:=New TimeParser
  248. If Not p.Parse( str ) Return Null
  249. Return New Time( p.day,p.month,p.year,p.hours,p.minutes,p.seconds )
  250. End
  251. #rem monkeydoc Converts a file time to a time.
  252. Converts a file time as returned by [[GetFileTime]] to a time.
  253. #end
  254. Function FromFileTime:Time( fileTime:Long )
  255. Return New Time( fileTime * TimeSpan.TicksPerSecond )
  256. End
  257. Private
  258. Const _days:=New String[]( "Sun","Mon","Tue","Wed","Thu","Fri","Sat" )
  259. Const _months:=New String[]( "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" )
  260. Field _ticks:Long
  261. Field _tm:libc.tm_t
  262. Method New( ticks:Long )
  263. Init( ticks )
  264. End
  265. Method Init( ticks:Long )
  266. _ticks=ticks
  267. Local time:=to_time( _ticks )
  268. Local p:=libc.localtime( Varptr time )
  269. If Not p RuntimeError( "time_t error" )
  270. _tm=p[0]
  271. End
  272. End