Namespace System

/*!
	@brief	時刻の種類
*/
Enum DateTimeKind
	Local
	Unspecified
	Utc
End Enum

/*!
	@brief	曜日
*/
Enum DayOfWeek
	Sunday = 0
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
End Enum


/*!
	@brief	時刻を表すクラス
*/

Class DateTime
	m_Date As Int64
Public
	Static Const MaxValue = 3162240000000000000 As Int64 'Const TicksPerDay*366*10000
	Static Const MinValue = 316224000000000 As Int64     'Const TicksPerDay*366

	'----------------------------------------------------------------
	' パブリック コンストラクタ
	'----------------------------------------------------------------

	/*!
	@brief	コンストラクタ
	*/
	Sub DateTime()
		initialize(MinValue, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  100ナノ秒単位で表した時刻
	*/
	Sub DateTime(ticks As Int64)
		initialize(ticks, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  100ナノ秒単位で表した時刻
	@param  時刻の種類
	*/
	Sub DateTime(ticks As Int64, kind As DateTimeKind)
		initialize(ticks, kind)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	*/
	Sub DateTime(year As Long, month As Long, day As Long)
		initialize(year, month, day, 0, 0, 0, 0, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時刻の種類
	*/
	Sub DateTime(year As Long, month As Long, day As Long, kind As DateTimeKind)
		initialize(year, month, day, 0, 0, 0, 0, kind)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時
	@param  分
	@param  秒
	*/
	Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long)
		initialize(year, month, day, hour, minute, second, 0, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時
	@param  分
	@param  秒
	@param  時刻の種類
	*/
	Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, kind As DateTimeKind)
		initialize(year, month, day, hour, minute, second, 0, kind)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時
	@param  分
	@param  秒
	@param  ミリ秒
	*/
	Sub DateTime(year As Long, month As Long, day As Long, hour As Long, minute As Long, second As Long, millisecond As Long)
		initialize(year, month, day, hour, minute, second, millisecond, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時
	@param  分
	@param  秒
	@param  ミリ秒
	@param  時刻の種類
	*/
	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)
		initialize(year, month, day, hour, minute, second, millisecond, kind)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  SYSTEMTIME構造体
	*/
	Sub DateTime(ByRef time As SYSTEMTIME)
		initialize(time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, DateTimeKind.Unspecified)
	End Sub

	/*!
	@brief	時刻を指定して初期化する
	@param  SYSTEMTIME構造体
	@param  時刻の種類
	*/
	Sub DateTime(ByRef time As SYSTEMTIME, kind As DateTimeKind)
		initialize(time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, kind)
	End Sub

	/*!
	@brief	コピーコンストラクタ
	@param  コピーするDateTime
	*/
	Sub DateTime(dateTime As DateTime)
		This.m_Date = dateTime.m_Date
	End Sub

	'----------------------------------------------------------------
	' オペレータ
	'----------------------------------------------------------------

	Function Operator + (value As TimeSpan) As DateTime
		Return New DateTime(Ticks + value.Ticks)
	End Function

	Function Operator - (value As DateTime) As TimeSpan
		Return TimeSpan.FromTicks(Ticks - value.Ticks)
	End Function

	Function Operator - (value As TimeSpan) As DateTime
		Return New DateTime(Ticks - value.Ticks)
	End Function

	Function Operator == (value As DateTime) As Boolean
		Return Equals(value)
	End Function

	Function Operator <> (value As DateTime) As Boolean
		Return Not Equals(value)
	End Function

	Function Operator > (value As DateTime) As Boolean
		If DateTime.Compare(This, value) > 0 Then
			Return True
		Else
			Return False
		End If
	End Function

	Function Operator < (value As DateTime) As Boolean
		If DateTime.Compare(This, value) < 0 Then
			Return True
		Else
			Return False
		End If
	End Function

	Function Operator >= (value As DateTime) As Boolean
		If DateTime.Compare(This, value) => 0 Then
			Return True
		Else
			Return False
		End If
	End Function

	Function Operator <= (value As DateTime) As Boolean
		If DateTime.Compare(This, value) <= 0 Then
			Return True
		Else
			Return False
		End If
	End Function
	
	'----------------------------------------------------------------
	' パブリック プロパティ
	'----------------------------------------------------------------

	/*!
	@brief	時刻を100ナノ秒単位で取得する
	@return 時刻
	*/
	Function Ticks() As Int64
		Return (m_Date And &H3FFFFFFFFFFFFFFF)
	End Function

	/*!
	@brief	時刻のミリ秒単位部分を取得する
	@return ミリ秒の部分
	*/
	Function Millisecond() As Long
		Return (Ticks \ TimeSpan.TicksPerMillisecond Mod 1000) As Long
	End Function

	/*!
	@brief	時刻の秒単位部分を取得する
	@return 秒の部分
	*/
	Function Second() As Long
		Return (Ticks \ TimeSpan.TicksPerSecond Mod 60) As Long
	End Function

	/*!
	@brief	時刻の分単位部分を取得する
	@return 分の部分
	*/
	Function Minute() As Long
		Return (Ticks \ TimeSpan.TicksPerMinute Mod 60) As Long
	End Function

	/*!
	@brief	時刻の時単位部分を取得する
	@return 時の部分
	*/
	Function Hour() As Long
		Return (Ticks \ TimeSpan.TicksPerHour Mod 24) As Long
	End Function

	/*!
	@brief	時刻の日単位部分を取得する
	@return 日の部分
	*/
	Function Day() As Long
		Return DayOfYear - totalDaysOfMonth(Year, Month - 1)
	End Function

	/*!
	@brief	時刻の月単位部分を取得する
	@return 月の部分
	*/
	Function Month() As Long
		Dim year = Year As Long
		Dim day = DayOfYear As Long
		Dim i = 1 As Long
		While day > totalDaysOfMonth(year, i)
			i++
		Wend
		Return i
	End Function

	/*!
	@brief	時刻の年単位部分を取得する
	@return 西暦
	*/
	Function Year() As Long
		Dim day = (Ticks \ TimeSpan.TicksPerDay) As Long
		Dim year = Int((day + day \ 36524 - day \ 146097) / 365.25) + 1 As Long
		If day - yearToDay(year - 1) + 1 = 366 Then
			Return year + 1
		Else
			Return year
		End If
	End Function

	/*!
	@brief	時刻の曜日部分を取得する
	@return 曜日の部分
	*/
	Function DayOfWeek() As DayOfWeek
		Return New DayOfWeek( (((Ticks \ TimeSpan.TicksPerDay) Mod 7) + 1) As Long, "DayOfWeek")
	End Function

	/*!
	@brief	時刻の種類を取得する
	@return 種類
	*/
	Function Kind() As DateTimeKind
		Return kindFromBinary(m_Date)
	End Function

	/*!
	@brief	その年の何日目かを取得する
	@return 日数
	*/
	Function DayOfYear() As Long
		Return ((Ticks \ TimeSpan.TicksPerDay) - yearToDay(Year) + 1) As Long
	End Function

	/*!
	@brief	時刻の日付の部分を取得する
	@return 日付
	*/
	Function Date() As DateTime
		Return New DateTime(Year, Month, Day, Kind)
	End Function

	/*!
	@brief	現在の時刻を取得する
	@return 時刻
	*/
	Static Function Now() As DateTime
		Dim time As SYSTEMTIME
		GetLocalTime(time)
		Return New DateTime(time, DateTimeKind.Local)
	End Function

	/*!
	@brief	今日を表す時刻を取得する(時間は0時0分)
	@return 時刻
	*/
	Static Function Today() As DateTime
		Dim time As SYSTEMTIME
		GetLocalTime(time)
		Return New DateTime(time.wYear, time.wMonth, time.wDay, DateTimeKind.Local)
	End Function

	/*!
	@brief	現在の時刻をUTC時刻で取得する
	@return 時刻
	*/
	Static Function UtcNow() As DateTime
		Dim time As SYSTEMTIME
		GetSystemTime(time)
		Return New DateTime(time, DateTimeKind.Utc)
	End Function
		
	'----------------------------------------------------------------
	' パブリック メソッド
	'----------------------------------------------------------------

	/*!
	@brief	二つの時刻の差を求める
	@return 差(単位は100ナノ秒)
	*/
	Static Function Compare(t1 As DateTime, t2 As DateTime) As Int64
		Return t1.Ticks - t2.Ticks
	End Function

	/*!
	@brief	等しいどうかを取得する
	@param  比較する値
	@retval True  等しい
	@retval False 等しくない
	*/
	Function Equals(value As DateTime) As Boolean
		If value.m_Date = m_Date Then
			Return True
		Else
			Return False
		End If
	End Function

	/*!
	@brief	等しいどうかを取得する
	@param  比較される値
	@param  比較する値
	@retval True  等しい
	@retval False 等しくない
	*/
	Static Function Equals(t1 As DateTime, t2 As DateTime) As Boolean
		If t1.m_Date = t2.m_Date Then
			Return True
		Else
			Return False
		End If
	End Function

	/*!
	@brief	ハッシュコードを取得する
	@return ハッシュコード
	*/
	Override Function GetHashCode() As Long
		Return HIDWORD(m_Date) Xor LODWORD(m_Date)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間
	@return 進めた後の時刻
	*/
	Function Add(value As TimeSpan) As DateTime
		Return This + value
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(100ナノ秒単位)
	@return 進めた後の時刻
	*/
	Function AddTicks(value As Int64) As DateTime
		Return New DateTime(Ticks + value, Kind )
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(ミリ秒単位)
	@return 進めた後の時刻
	*/
	Function AddMilliseconds(value As Double) As DateTime
		Return AddTicks((value * TimeSpan.TicksPerMillisecond) As Int64)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(秒単位)
	@return 進めた後の時刻
	*/
	Function AddSeconds(value As Double) As DateTime
		Return AddTicks((value * TimeSpan.TicksPerSecond) As Int64)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(分単位)
	@return 進めた後の時刻
	*/
	Function AddMinutes(value As Double) As DateTime
		Return AddTicks((value * TimeSpan.TicksPerMinute) As Int64)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(時単位)
	@return 進めた後の時刻
	*/
	Function AddHours(value As Double) As DateTime
		Return AddTicks((value * TimeSpan.TicksPerHour) As Int64)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(日単位)
	@return 進めた後の時刻
	*/
	Function AddDays(value As Double) As DateTime
		Return AddTicks((value * TimeSpan.TicksPerDay) As Int64)
	End Function

	/*!
	@brief	時刻を進める
	@param  進める時間(年単位)
	@return 進めた後の時刻
	*/
	Function AddYears(value As Double) As DateTime
		Dim date = New DateTime(Year + Int(value), Month, Day, Hour, Minute, Second, Millisecond, Kind)
		Dim ticks = Ticks _
				- (yearToDay(Year) + totalDaysOfMonth(Year, Month - 1) + Day - 1) * TimeSpan.TicksPerDay _
				- Hour * TimeSpan.TicksPerHour _
				- Minute * TimeSpan.TicksPerMinute _
				- Second * TimeSpan.TicksPerSecond _
				- Millisecond * TimeSpan.TicksPerMillisecond As Int64
		If IsLeapYear(Year + Int(value)) Then
			ticks += ( (value - Int(value)) * 366 * TimeSpan.TicksPerDay ) As Int64
		Else
			ticks += ( (value - Int(value)) * 365 * TimeSpan.TicksPerDay ) As Int64
		End If
		Return date.AddTicks(ticks)
	End Function

	/*!
	@brief	時刻の差を取得する
	@param  比較する値
	@return 時刻の差
	*/
	Function Subtract(value As DateTime) As TimeSpan
		Return This - value
	End Function

	/*!
	@brief	時刻を戻す
	@param  戻す時間
	@return 時刻
	*/
	Function Subtract(value As TimeSpan) As DateTime
		Return This - value
	End Function

	/*!
	@brief	指定した年月が、その月の何日目かを取得する
	@param  西暦
	@param  月
	@return 日数
	*/
	Static Function DaysInMonth(year As Long, month As Long) As Long
		If year < 1 Or year > 9999 Then
			Throw New ArgumentOutOfRangeException("DateTime.DaysInMonth: One or more arguments are out of range value.", "year")
		End If
		If month < 1 Or month > 12 Then
			Throw New ArgumentOutOfRangeException("DateTime.DaysInMonth: One or more arguments are out of range value.", "month")
		End If

		If IsLeapYear(year) And month = 2 Then
			Return 29
		Else
			Dim daysInMonth[11] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] As Byte
			Return daysInMonth[month - 1]
		End If
	End Function

	/*!
	@brief	年が閏年かどうかを取得する
	@param  西暦
	@retval True  閏年
	@retval False 閏年でない
	*/
	Static Function IsLeapYear(year As Long) As Boolean
		If (year Mod 400) = 0 Then Return True
		If (year Mod 100) = 0 Then Return False
		If (year Mod 4) = 0 Then Return True
		Return False
	End Function

	/*!
	@brief	時刻を文字列に変換する
	@return 時刻を表した文字列
	*/
	Function GetDateTimeFormats() As String
		Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生
		Dim dateFormatSize = GetDateFormat(LOCALE_USER_DEFAULT, 0, time, NULL, NULL, 0)
		Dim timeFormatSize = GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, NULL, NULL, 0)
		Dim strLength = dateFormatSize + timeFormatSize
		Dim dateTimeFormats = GC_malloc_atomic(SizeOf (TCHAR) * (strLength)) As PTSTR
		GetDateFormat(LOCALE_USER_DEFAULT, 0, time, NULL, dateTimeFormats, dateFormatSize)
		dateTimeFormats[dateFormatSize - 1] = &H20 As TCHAR 'Asc(" ") As TCHAR
		GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, NULL, dateTimeFormats + dateFormatSize, timeFormatSize)
		Return New String(dateTimeFormats, strLength)
	End Function

	/*!
	@brief	時刻を指定した書式で文字列に変換する
	@param  書式
	@return 時刻を表した文字列
	*/
	Function GetDateTimeFormats(format As *TCHAR) As String
		Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生
		Dim dateFormatSize = GetDateFormat(LOCALE_USER_DEFAULT, 0, time, format, NULL, 0)
		Dim dateFormats = malloc(dateFormatSize) As PTSTR
		GetDateFormat(LOCALE_USER_DEFAULT, 0, time, format, dateFormats, dateFormatSize)

		Dim dateTimeFormatSize = GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, dateFormats, NULL, 0)
		Dim dateTimeFormats = GC_malloc_atomic(dateTimeFormatSize) As PTSTR
		GetTimeFormat(LOCALE_USER_DEFAULT, 0, time, dateFormats, dateTimeFormats, dateTimeFormatSize)

		Return New String(dateTimeFormats)
	End Function

	/*!
	@brief	バイナリデータからDateTimeを作成する
	@return DateTimeクラス
	*/
	Static Function FromBinary(date As Int64) As DateTime
		Return New DateTime((date And &H3FFFFFFFFFFFFFFF), kindFromBinary(date))
	End Function

	/*!
	@brief	バイナリデータに変換する
	@return バイナリデータ
	*/
	Function ToBinary() As Int64
		Return m_Date
	End Function

	/*!
	@brief	FILETIME構造体からDateTimeを作成する
	@return DateTimeクラス
	*/
	Static Function FromFileTime(ByRef fileTime As FILETIME) As DateTime
		Dim localTime As FILETIME
		Dim time As SYSTEMTIME
		FileTimeToLocalFileTime(fileTime, localTime)
		FileTimeToSystemTime(localTime, time)
		Return New DateTime(time, DateTimeKind.Local)
	End Function

	/*!
	@brief	FILETIME構造体に変換する
	@return FILETIME構造体
	*/
	Function ToFileTime() As FILETIME
		Dim time = getSystemTime() 'As SYSTEMTIME を記述すると内部エラーが発生 rev.207
		Dim fileTime As FILETIME
		SystemTimeToFileTime(time, fileTime)
		Return fileTime
	End Function

	/*!
	@brief	UTC時刻を表すFILETIME構造体からDateTimeを作成する
	@return DateTimeクラス
	*/
	Static Function FromFileTimeUtc(ByRef fileTime As FILETIME) As DateTime
		Dim time As SYSTEMTIME
		FileTimeToSystemTime(fileTime, time)
		Return New DateTime(time, DateTimeKind.Utc)
	End Function

	/*!
	@brief	UTC時刻のFILETIME構造体に変換する
	@return FILETIME構造体
	*/
	Function ToFileTimeUtc() As FILETIME
		Dim fileTime = ToFileTime() 'As FILETIME を記述すると内部エラー rev.207
		If Kind = DateTimeKind.Utc Then
			Return fileTime
		Else
			Dim utcTime As FILETIME
			LocalFileTimeToFileTime(fileTime, utcTime)
			Return utcTime
		End If
	End Function

	/*!
	@brief	現地時刻に変換する
	@return 現地時刻に変換したDateTime
	*/
	Function ToLocalTime() As DateTime
		If Kind = DateTimeKind.Local Then
			Return New DateTime(This)
		Else
			Dim fileTime = ToFileTime() '直接入れると計算できなくなります。 rev.207
			Return DateTime.FromFileTime(fileTime)
		End If
	End Function

	/*!
	@brief	このインスタンスを文字列で取得する
	@return 文字列
	*/
	Override Function ToString() As String
		Return GetDateTimeFormats()
	End Function

	/*!
	@brief	世界協定時刻(UTC)に変換する
	@return 世界協定時刻(UTC)に変換したDateTime
	*/
	Function ToUniversalTime() As DateTime
		If Kind = DateTimeKind.Utc Then
			Return New DateTime(m_Date)
		Else
			Dim fileTime = ToFileTimeUtc() '直接入れると計算できなくなります。 rev.207
			Return DateTime.FromFileTimeUtc(fileTime)
		End If
	End Function

	'----------------------------------------------------------------
	' プライベート メソッド
	'----------------------------------------------------------------
Private

	/*!
	@brief	インスタンスを初期化する
	@param  時刻(100ナノ秒単位)
	@param  時刻の種類
	*/
	Sub initialize(ticks As Int64, kind As DateTimeKind)
		Kind = kind
		Ticks = ticks
	End Sub

	/*!
	@brief	インスタンスを初期化する
	@param  西暦
	@param  月
	@param  日
	@param  時
	@param  分
	@param  秒
	@param  ミリ秒
	@param  時刻の種類
	*/
	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)
		If month < 1 Or month > 12 Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "month")
		End If
		If day < 1 Or day > DaysInMonth(year, month) Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "day")
		End If
		If hour < 0 Or hour => 24 Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "hour")
		End If
		If minute < 0 Or minute => 60 Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "minute")
		End If
		If second < 0 Or second => 60 Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "second")
		End If
		If millisecond < 0 Or millisecond  => 1000 Then
			Throw New ArgumentOutOfRangeException("DateTime.initialize: One or more arguments are out of range value.", "millisecond")
		End If

		initialize(
			yearToDay(year) * TimeSpan.TicksPerDay _
			+ totalDaysOfMonth(year, month - 1) * TimeSpan.TicksPerDay _
			+ (day - 1) * TimeSpan.TicksPerDay _
			+ hour * TimeSpan.TicksPerHour _
			+ minute * TimeSpan.TicksPerMinute _
			+ second * TimeSpan.TicksPerSecond _
			+ millisecond * TimeSpan.TicksPerMillisecond,
			kind
			)
	End Sub

	/*!
	@brief	時刻を設定する
	@param  時刻(100ナノ秒単位)
	*/
	Sub Ticks(value As Int64)
		If value < MinValue Or value > MaxValue Then
			Throw New ArgumentOutOfRangeException("DateTime.value: One or more arguments are out of range value.", "value")
		End If

		Dim temp = Kind As DateTimeKind
		m_Date = value
		Kind = temp
	End Sub

	/*!
	@brief	時刻の種類を設定する
	@param  時刻の種類
	*/
	Sub Kind(kind As DateTimeKind)
		Dim temp As Int64
		temp = kind
		temp = (temp << 62) And &HC000000000000000
		m_Date = (m_Date And &H3FFFFFFFFFFFFFFF) Or temp
	End Sub

	/*!
	@brief	バイナリデータから時刻の種類を取得する
	@return 時刻の種類
	*/
	Static Function kindFromBinary(date As Int64) As DateTimeKind
		date = (date >> 62) And &H03
		If date = &H01 Then
			Return DateTimeKind.Local
		ElseIf date = &H02 Then
			Return DateTimeKind.Unspecified
		ElseIf date = &H03 Then
			Return DateTimeKind.Utc
		End If
	End Function

	/*!
	@brief	インスタンスをSYSTEMTIME構造体に変換する
	@return SYSTEMTIME構造体
	*/
	Function getSystemTime() As SYSTEMTIME
		Dim dayOfWeek = DayOfWeek As Long
		Dim time As SYSTEMTIME
		With time
			.wYear = Year As Word
			.wMonth = Month As Word
			.wDayOfWeek = dayOfWeek As Word
			.wDay = Day As Word
			.wHour = Hour As Word
			.wMinute = Minute As Word
			.wSecond = Second As Word
			.wMilliseconds = Millisecond As Word
		End With
		Return time
	End Function

	/*!
	@brief	西暦から日数に変換する
	@return 日数
	*/
	Static Function yearToDay(year As Long) As Long
		year--
		Return (Int(year * 365.25) - Int(year * 0.01) + Int(year * 0.0025))
	End Function

	/*!
	@brief	その月までその年の元旦から何日経っているかを取得する
	@return 日数
	*/
	Static Function totalDaysOfMonth(year As Long, month As Long) As Long
		Dim days As Long
		Dim i As Long
		For i = 1 To month
			days += DaysInMonth(year, i)
		Next
		Return days
	End Function
End Class

End Namespace
