source: trunk/Include/Classes/System/DateTime.ab@ 400

Last change on this file since 400 was 400, checked in by イグトランス (egtra), 16 years ago

_System_CThreadCollectionでのクラスインスタンスへのポインタの使用を除去、参照変数構文へ。

File size: 13.7 KB
RevLine 
[275]1Namespace System
[36]2
[275]3
[36]4Class DateTime
5 m_Date As Int64
6Public
[209]7 Static MaxValue = 3162240000000000000 As Int64 'Const TicksPerDay*366*10000
8 Static MinValue = 316224000000000 As Int64 'Const TicksPerDay*366
[36]9
[163]10 Sub DateTime()
[209]11 initialize(MinValue, DateTimeKind.Unspecified)
[163]12 End Sub
13
[36]14 Sub DateTime(ticks As Int64)
[209]15 initialize(ticks, DateTimeKind.Unspecified)
[36]16 End Sub
17
18 Sub DateTime(ticks As Int64, kind As DateTimeKind)
[209]19 initialize(ticks, kind)
[36]20 End Sub
21
22 Sub DateTime(year As Long, month As Long, day As Long)
[209]23 initialize(year, month, day, 0, 0, 0, 0, DateTimeKind.Unspecified)
[36]24 End Sub
25
26 Sub DateTime(year As Long, month As Long, day As Long, kind As DateTimeKind)
[209]27 initialize(year, month, day, 0, 0, 0, 0, kind)
[36]28 End Sub
29
30 Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long)
[209]31 initialize(year, month, day, hour, minute, second, 0, DateTimeKind.Unspecified)
[36]32 End Sub
33
[103]34 Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, kind As DateTimeKind)
[209]35 initialize(year, month, day, hour, minute, second, 0, kind)
[103]36 End Sub
[36]37
38 Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, millisecond As Long)
[209]39 initialize(year, month, day, hour, minute, second, millisecond, DateTimeKind.Unspecified)
[36]40 End Sub
41
42 Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, millisecond As Long, kind As DateTimeKind)
[209]43 initialize(year, month, day, hour, minute, second, millisecond, kind)
[36]44 End Sub
45
46 Sub DateTime(ByRef time As SYSTEMTIME)
[209]47 initialize(time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, DateTimeKind.Unspecified)
[36]48 End Sub
49
50 Sub DateTime(ByRef time As SYSTEMTIME, kind As DateTimeKind)
[209]51 initialize(time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, kind)
[36]52 End Sub
53
[40]54 'Copy Constructor
[268]55 Sub DateTime(dateTime As DateTime)
[209]56 This.m_Date = dateTime.m_Date
[40]57 End Sub
58
[36]59 Sub ~DateTime()
60 End Sub
61
[268]62 Function Operator + (value As TimeSpan) As DateTime
[209]63 Return New DateTime(Ticks + value.Ticks)
[107]64 End Function
65
[268]66 Function Operator - (value As DateTime) As TimeSpan
[107]67 Return TimeSpan.FromTicks(Ticks - value.Ticks)
68 End Function
69
[268]70 Function Operator - (value As TimeSpan) As DateTime
[209]71 Return New DateTime(Ticks - value.Ticks)
[107]72 End Function
73
[268]74 Function Operator == (value As DateTime) As Boolean
[36]75 Return Equals(value)
76 End Function
77
[268]78 Function Operator <> (value As DateTime) As Boolean
[36]79 Return Not Equals(value)
80 End Function
81
[268]82 Function Operator > (value As DateTime) As Boolean
[36]83 If DateTime.Compare(This, value) > 0 Then
[93]84 Return True
[36]85 Else
[93]86 Return False
[36]87 End If
88 End Function
89
[268]90 Function Operator < (value As DateTime) As Boolean
[36]91 If DateTime.Compare(This, value) < 0 Then
[93]92 Return True
[36]93 Else
[93]94 Return False
[36]95 End If
96 End Function
97
[268]98 Function Operator >= (value As DateTime) As Boolean
[36]99 If DateTime.Compare(This, value) => 0 Then
[93]100 Return True
[36]101 Else
[93]102 Return False
[36]103 End If
104 End Function
105
[268]106 Function Operator <= (value As DateTime) As Boolean
[36]107 If DateTime.Compare(This, value) <= 0 Then
[93]108 Return True
[36]109 Else
[93]110 Return False
[36]111 End If
112 End Function
113
[209]114 'Public Properties
[36]115 Function Ticks() As Int64
116 Return (m_Date And &H3FFFFFFFFFFFFFFF)
117 End Function
118
119 Function Millisecond() As Long
[107]120 Return (Ticks \ TimeSpan.TicksPerMillisecond Mod 1000) As Long
[36]121 End Function
122
123 Function Second() As Long
[107]124 Return (Ticks \ TimeSpan.TicksPerSecond Mod 60) As Long
[36]125 End Function
126
127 Function Minute() As Long
[107]128 Return (Ticks \ TimeSpan.TicksPerMinute Mod 60) As Long
[36]129 End Function
130
131 Function Hour() As Long
[107]132 Return (Ticks \ TimeSpan.TicksPerHour Mod 24) As Long
[36]133 End Function
134
135 Function Day() As Long
[263]136 Return DayOfYear - totalDaysOfMonth(Year, Month - 1)
[36]137 End Function
138
139 Function Month() As Long
[209]140 Dim year = Year As Long
141 Dim day = DayOfYear As Long
142 Dim i = 1 As Long
[263]143 While day > totalDaysOfMonth(year, i)
[209]144 i++
145 Wend
146 Return i
[36]147 End Function
148
149 Function Year() As Long
[209]150 Dim day = (Ticks \ TimeSpan.TicksPerDay) As Long
[263]151 Dim year = Int((day + day \ 36524 - day \ 146097) / 365.25) + 1 As Long
152 If day - yearToDay(year - 1) + 1 = 366 Then
[209]153 Return year + 1
154 Else
155 Return year
156 End If
[36]157 End Function
158
[209]159 Function DayOfWeek() As Long 'As DayOfWeek
[263]160 Return ((Ticks \ TimeSpan.TicksPerDay) Mod 7) As Long + 1
[36]161 End Function
162
[81]163 Function Kind() As DateTimeKind
[36]164 Return kindFromBinary(m_Date)
165 End Function
166
167 Function DayOfYear() As Long
[263]168 Return ((Ticks \ TimeSpan.TicksPerDay) - yearToDay(Year) + 1) As Long
[36]169 End Function
170
171 Function Date() As DateTime
[209]172 Return New DateTime(Year, Month, Day, Kind)
[36]173 End Function
174
175 Static Function Now() As DateTime
176 Dim time As SYSTEMTIME
177 GetLocalTime(time)
[209]178 Return New DateTime(time, DateTimeKind.Local)
[36]179 End Function
180
[272]181 Static Function Today() As DateTime
[36]182 Dim time As SYSTEMTIME
183 GetLocalTime(time)
[209]184 Return New DateTime(time.wYear, time.wMonth, time.wDay, DateTimeKind.Local)
[36]185 End Function
186
187 Static Function UtcNow() As DateTime
188 Dim time As SYSTEMTIME
189 GetSystemTime(time)
[209]190 Return New DateTime(time, DateTimeKind.Utc)
[36]191 End Function
192
[209]193 'Public Methods
[268]194 Static Function Compare(t1 As DateTime, t2 As DateTime) As Int64
[36]195 Return t1.Ticks - t2.Ticks
196 End Function
197
[268]198 Function Equals(value As DateTime) As Boolean
[36]199 If value.m_Date = m_Date Then
[93]200 Return True
[36]201 Else
[93]202 Return False
[36]203 End If
204 End Function
205
[268]206 Static Function Equals(t1 As DateTime, t2 As DateTime) As Boolean
[36]207 If t1.m_Date = t2.m_Date Then
[93]208 Return True
[36]209 Else
[93]210 Return False
[36]211 End If
212 End Function
213
[166]214 Override Function GetHashCode() As Long
215 Return HIDWORD(m_Date) Xor LODWORD(m_Date)
216 End Function
217
[268]218 Function Add(value As TimeSpan) As DateTime
[107]219 Return This + value
220 End Function
221
222 Function AddTicks(value As Int64) As DateTime
[209]223 Return New DateTime(Ticks + value, Kind )
[107]224 End Function
[36]225
[107]226 Function AddMilliseconds(value As Double) As DateTime
227 Return AddTicks((value * TimeSpan.TicksPerMillisecond) As Int64)
228 End Function
[36]229
[107]230 Function AddSeconds(value As Double) As DateTime
231 Return AddTicks((value * TimeSpan.TicksPerSecond) As Int64)
232 End Function
[36]233
[107]234 Function AddMinutes(value As Double) As DateTime
235 Return AddTicks((value * TimeSpan.TicksPerMinute) As Int64)
236 End Function
[36]237
[107]238 Function AddHours(value As Double) As DateTime
239 Return AddTicks((value * TimeSpan.TicksPerHour) As Int64)
240 End Function
[36]241
[107]242 Function AddDays(value As Double) As DateTime
243 Return AddTicks((value * TimeSpan.TicksPerDay) As Int64)
244 End Function
245
246 Function AddYears(value As Double) As DateTime
[263]247 Dim date = New DateTime(Year + Int(value), Month, Day, Hour, Minute, Second, Millisecond, Kind)
248 Dim ticks = Ticks _
249 - (yearToDay(Year) + totalDaysOfMonth(Year, Month - 1) + Day - 1) * TimeSpan.TicksPerDay _
250 - Hour * TimeSpan.TicksPerHour _
251 - Minute * TimeSpan.TicksPerMinute _
252 - Second * TimeSpan.TicksPerSecond _
253 - Millisecond * TimeSpan.TicksPerMillisecond As Int64
254 If IsLeapYear(Year + Int(value)) Then
[370]255 ticks += ( (value - Int(value)) * 366 * TimeSpan.TicksPerDay ) As Int64
[36]256 Else
[370]257 ticks += ( (value - Int(value)) * 365 * TimeSpan.TicksPerDay ) As Int64
[36]258 End If
[263]259 Return date.AddTicks(ticks)
[107]260 End Function
[36]261
[268]262 Function Subtract(value As DateTime) As TimeSpan
263 Return This - value
[107]264 End Function
265
[268]266 Function Subtract(value As TimeSpan) As DateTime
267 Return This - value
[107]268 End Function
269
[93]270 Static Function DaysInMonth(year As Long, month As Long) As Long
[36]271 If year < 1 Or year > 9999 Or month < 1 Or month > 12 Then
272 'ArgumentOutOfRangeException
273 debug
274 End If
[209]275
[93]276 If IsLeapYear(year) And month = 2 Then
277 Return 29
278 Else
279 Dim daysInMonth[11] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] As Byte
280 Return daysInMonth[month - 1]
281 End If
[36]282 End Function
283
[93]284 Static Function IsLeapYear(year As Long) As Boolean
285 If (year Mod 400) = 0 Then Return True
286 If (year Mod 100) = 0 Then Return False
287 If (year Mod 4) = 0 Then Return True
[103]288 Return False
[36]289 End Function
290
291 Function GetDateTimeFormats() As String
[209]292 Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生
293 Dim dateFormatSize = GetDateFormat(LOCALE_USER_DEFAULT, 0, time, NULL, NULL, 0)
294 Dim timeFormatSize = GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, NULL, NULL, 0)
[272]295 Dim strLength = dateFormatSize + timeFormatSize
296 Dim dateTimeFormats = GC_malloc_atomic(SizeOf (TCHAR) * (strLength)) As PTSTR
[209]297 GetDateFormat(LOCALE_USER_DEFAULT, 0, time, NULL, dateTimeFormats, dateFormatSize)
[400]298 dateTimeFormats[dateFormatSize - 1] = &H20 As TCHAR 'Asc(" ") As TCHAR
[209]299 GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, NULL, dateTimeFormats + dateFormatSize, timeFormatSize)
[272]300'Debug
301 Return New String(dateTimeFormats, strLength)
[36]302 End Function
303
[209]304 Function GetDateTimeFormats(format As *TCHAR) As String
305 Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生
306 Dim dateFormatSize = GetDateFormat(LOCALE_USER_DEFAULT, 0, time, format, NULL, 0)
307 Dim dateFormats = malloc(dateFormatSize) As PTSTR
308 GetDateFormat(LOCALE_USER_DEFAULT, 0, time, format, dateFormats, dateFormatSize)
[73]309
[209]310 Dim dateTimeFormatSize = GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, dateFormats, NULL, 0)
311 Dim dateTimeFormats = malloc(dateTimeFormatSize) As PTSTR
312 GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, dateFormats, dateTimeFormats, dateTimeFormatSize)
[207]313
[209]314 Return New String(dateTimeFormats)
[73]315 End Function
316
[209]317 Static Function FromBinary(date As Int64) As DateTime
318 Return New DateTime((date And &H3FFFFFFFFFFFFFFF), kindFromBinary(date))
[36]319 End Function
320
321 Function ToBinary() As Int64
322 Return m_Date
323 End Function
324
[209]325 Static Function FromFileTime(ByRef fileTime As FILETIME) As DateTime
[36]326 Dim localTime As FILETIME
[82]327 Dim time As SYSTEMTIME
[36]328 FileTimeToLocalFileTime(fileTime, localTime)
329 FileTimeToSystemTime(localTime, time)
[209]330 Return New DateTime(time, DateTimeKind.Local)
[36]331 End Function
332
333 Function ToFileTime() As FILETIME
[209]334 Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生 rev.207
[36]335 Dim fileTime As FILETIME
336 SystemTimeToFileTime(time, fileTime)
337 Return fileTime
338 End Function
339
[209]340 Static Function FromFileTimeUtc(ByRef fileTime As FILETIME) As DateTime
[36]341 Dim time As SYSTEMTIME
342 FileTimeToSystemTime(fileTime, time)
[209]343 Return New DateTime(time, DateTimeKind.Utc)
[36]344 End Function
345
346 Function ToFileTimeUtc() As FILETIME
[209]347 Dim fileTime = ToFileTime() 'As FILETIME を記述すると内部エラー rev.207
[103]348 If Kind = DateTimeKind.Utc Then
[209]349 Return fileTime
[36]350 Else
[209]351 Dim utcTime As FILETIME
352 LocalFileTimeToFileTime(fileTime, utcTime)
353 Return utcTime
[36]354 End If
355 End Function
356
357 Function ToLocalTime() As DateTime
[103]358 If Kind = DateTimeKind.Local Then
[209]359 Return New DateTime(This)
[82]360 Else
[209]361 Dim fileTime = ToFileTime() '直接入れると計算できなくなります。 rev.207
362 Return DateTime.FromFileTime(fileTime)
[81]363 End If
[36]364 End Function
[81]365
[228]366 Override Function ToString() As String
367 Return GetDateTimeFormats()
368 End Function
369
[81]370 Function ToUniversalTime() As DateTime
[103]371 If Kind = DateTimeKind.Utc Then
[209]372 Return New DateTime(m_Date)
[82]373 Else
[209]374 Dim fileTime = ToFileTimeUtc() '直接入れると計算できなくなります。 rev.207
375 Return DateTime.FromFileTimeUtc(fileTime)
[81]376 End If
377 End Function
[209]378
[36]379Private
[209]380 Sub initialize(ticks As Int64, kind As DateTimeKind)
381 Kind = kind
382 Ticks = ticks
383 End Sub
384
385 Sub initialize(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, millisecond As Long, kind As DateTimeKind)
386 If month < 1 Or month > 12 _
387 Or day < 1 Or day > DaysInMonth(year, month) _
388 Or hour < 0 Or hour => 24 _
389 Or minute < 0 Or minute => 60 _
390 Or second < 0 Or second => 60 _
391 Or millisecond < 0 Or millisecond => 1000 Then
392 debug 'ArgumentOutOfRangeException
393 End If
394
395 initialize(
[263]396 yearToDay(year) * TimeSpan.TicksPerDay _
397 + totalDaysOfMonth(year, month - 1) * TimeSpan.TicksPerDay _
[209]398 + (day - 1) * TimeSpan.TicksPerDay _
399 + hour * TimeSpan.TicksPerHour _
400 + minute * TimeSpan.TicksPerMinute _
401 + second * TimeSpan.TicksPerSecond _
402 + millisecond * TimeSpan.TicksPerMillisecond,
403 kind
404 )
405 End Sub
406
[36]407 Sub Ticks(value As Int64)
[209]408 If value < MinValue Or value > MaxValue Then
409 debug 'ArgumentOutOfRangeException
410 End If
411
412 Dim temp = Kind As DateTimeKind
[36]413 m_Date = value
[209]414 Kind = temp
[36]415 End Sub
416
417 Sub Kind(kind As DateTimeKind)
418 Dim temp As Int64
419 temp = kind
420 temp = (temp << 62) And &HC000000000000000
421 m_Date = (m_Date And &H3FFFFFFFFFFFFFFF) Or temp
422 End Sub
423
[209]424 Static Function kindFromBinary(date As Int64) As DateTimeKind
425 date = (date >> 62) And &H03
426 If date = &H01 Then
[103]427 Return DateTimeKind.Local
[209]428 ElseIf date = &H02 Then
[103]429 Return DateTimeKind.Unspecified
[209]430 ElseIf date = &H03 Then
[103]431 Return DateTimeKind.Utc
[36]432 End If
[246]433
434 ' ここにはこないはず
435 debug
[36]436 End Function
[209]437
438 Function getSystemTime() As SYSTEMTIME
439 Dim time As SYSTEMTIME
440 With time
441 .wYear = Year As Word
442 .wMonth = Month As Word
443 .wDayOfWeek = DayOfWeek As Word
444 .wDay = Day As Word
445 .wHour = Hour As Word
446 .wMinute = Minute As Word
447 .wSecond = Second As Word
448 .wMilliseconds = Millisecond As Word
449 End With
450 Return time
451 End Function
452
[263]453 Static Function yearToDay(year As Long) As Long
454 year--
[209]455 Return (Int(year * 365.25) - Int(year * 0.01) + Int(year * 0.0025))
456 End Function
457
[263]458 Static Function totalDaysOfMonth(year As Long, month As Long) As Long
[209]459 Dim days As Long
460 Dim i As Long
461 For i = 1 To month
462 days += DaysInMonth(year, i)
463 Next
464 Return days
465 End Function
[36]466End Class
467
[103]468Enum DateTimeKind
[36]469 Local
470 Unspecified
471 Utc
472End Enum
473
[103]474Enum DayOfWeek
[36]475 Sunday = 0
476 Monday
477 Tuesday
478 Wednesday
479 Thursday
480 Friday
481 Saturday
[275]482End Enum
483
484
485End Namespace
Note: See TracBrowser for help on using the repository browser.