Я пытался найти способ сделать это правильно, но, возможно, кто-то мог бы направить меня в правильном направлении, поскольку я потратил довольно много времени, пытаясь сделать это без успеха.
Я пытаюсьразработать в моем приложении функцию для моего игрового центра, которая позволяет пользователю устанавливать различные ценовые предложения в зависимости от времени входа / выхода, вот пример того, чего я хочу достичь:
В настоящее время у меня есть два ценовых предложения (в качестве примера я буду использовать валюту USD):
1-й диапазон предложений:
Offer_Start_Time Offer_End_Time ------------------------------------------------
10:00:00 AM 05:00:00 PM
2-й диапазон предложений:
- это то, что находится за пределами диапазона 1-го Оффера (что-то вроде 05:05:00 PM to 09:59:59 AM
)
Предполагается, что у меня в клубе Table Tennis
, и он имеет следующие настройки:
1st Offer Pricing is 5 USD
2nd Offer Pricing is 10 USD
Так, если клиент приходит IN
в 11 AM
и идет OUT
в 1:15 PM
, тогда приложение будет взимать с него 5 USD
Если клиент приходит IN
в 4:40 PM
и идет OUT
в 09:00 PM
, то приложение должно разделитьсястоимость в двух диапазонах следующим образом:
4:40 PM to 05:00 PM will cost him 5 USD
5:00 PM to 09:00 PM will cost him 10 USD
- То же самое должно работать, если клиент приходит
IN
в 11:40 PM
и идет OUT
в 02:00 AM (which is the next day)
То, что я сделал до сих пор, которое работает нормально только тогда, когда диапазон находится в пределах 1 дня: </p>
<p>I first fetch the saved <code>Offer_Start_Time and Offer_End_Time
из базы данных, затем сделайте это
If New TimeSpan(TimeOfDay.Hour, TimeOfDay.Minute, TimeOfDay.Second) >= New TimeSpan(24, 0, 0) And New TimeSpan(TimeOfDay.Hour, TimeOfDay.Minute, TimeOfDay.Second) < New TimeSpan( Offer_End_Time.Hour, Offer_End_Time.Minute, Offer_End_Time.Second) Then
Offer_Start_Time= Date.Today.AddDays(-1)
Offer_End_Time = Date.Today.AddDays(-1)
Offer_Start_Time_NextDay = Date.Today
Else
Offer_Start_Time= Date.Today
Offer_End_Time = Date.Today
Offer_Start_Time_NextDay = Date.Today.AddDays(1)
End If
Затем я использую приведенный ниже код дляполучить диапазон, цену и т. д. </p>
<pre><code>If (INTIME >= Offer_Start_Time And OUTTIME <= Offer_End_Time And OUTTIME < Offer_Start_Time_NextDay) Then
' MsgBox("offer 1")
xTotal_1 = CalculatePrice_Time(Table_Number, INTIME, OUTTIME, PerHour_Price1,PriceType, "Price1")
ElseIf (INTIME >= Offer_Start_Time And INTIME <= Offer_End_Time And OUTTIME > Offer_End_Time And OUTTIME < Offer_Start_Time_NextDay) Then
'MsgBox("offer 1+2")
xTotal_1 = CalculatePrice_Time(Table_Number, INTIME, Offer_End_Time, PerHour_Price1,PriceType, "Price1")
'+'
xTotal_2 = CalculatePrice_Time(Table_Number, Offer_End_Time, OUTTIME, PerHour_Price2,PriceType, "Price2")
ElseIf (INTIME >= Offer_Start_Time And INTIME > Offer_End_Time And OUTTIME > Offer_End_Time And OUTTIME < Offer_Start_Time_NextDay) Then
' MsgBox("Offer 2")
xTotal_2 = CalculatePrice_Time(Table_Number, INTIME, OUTTIME, PerHour_Price2,PriceType, "Price2")
ElseIf (INTIME >= Offer_Start_Time And OUTTIME > Offer_End_Time And OUTTIME >= Offer_Start_Time_NextDay) Then
'MsgBox("Offer 2+3") '3 is the 2nd offer range which is outside 1st offer range
xTotal_1 = CalculatePrice_Time(Table_Number, INTIME, Offer_Start_Time_NextDay, PerHour_Price1,PriceType, "Price1")
'+'
xTotal_2 = CalculatePrice_Time(Table_Number, Offer_Start_Time_NextDay, OUTTIME, PerHour_Price2,PriceType, "Price2")
End If
PerHour_Price1
и PerHour_Price2
значения будут получены из базы данных, в которой он имеетКарта Table Number
и ее столбца Price1
и переменной Price2
PriceType
содержит "C" или "N", где C - форум пользовательских цен с использованием блоков 0-5,5-10 ... 55-60, а "N" - это формула Normal, в которой она будет умножать общее количество использованных минут на (PerHour_Price1 or PerHour_Price2)/60
. Мне нужноНиже приведена справка:
- Я получаю неправильную длительность и цену, если предположить, что клиент приходит
IN
по 10:00 PM 20/09/2018
и идет OUT
по 01:00 PM 21/09/2018
, имея в виду, что у меня только значение Time
вOffer_Start_Time
и Offer_End_Time
переменная диапазона - Я хочу иметь возможность добавлять несколько предложений в один и тот же день вместо двух в текущей настройке.например:
Offer 1 Range 10:00 AM to 01:00 PM
Offer 2 Range 01:00 PM to 06:00 PM
Offer 3 Range 06:00 PM to 09:59 AM
Я надеюсь, что моя проблема объяснена четко
Я был бы благодарен, если кто-нибудь может помочь мне с этим или поделиться наилучшим способом сделать это, как я считаюмой код громоздок и не будет работать для определенных сценариев
EDIT (добавлены коды):
Public Function CalculatePrice_Time(ByVal Table_Number As String, ByVal xDateTime_IN As DateTime, ByVal xDateTime_OUT As DateTime _
, ByVal Price As Double, ByVal PriceType As String, ByVal Price_DBColumn As String) As Double
Dim Result As Double = 0.0
Dim Hours_Used As Double = 0
Dim Minutes_Used As Double = 0
Dim HourToPrice As Double = 0
Dim MinutesToPrice As Double = 0
Dim Usage_Duration As TimeSpan = Calculate_Usage_Time(xDateTime_IN, xDateTime_OUT, True) 'True means return result without rounding to nearest 5 minutes
Dim Usage_Duration_Rounded As TimeSpan = Calculate_Usage_Time(xDateTime_IN, xDateTime_OUT)
Hours_Used = Usage_Duration.Hours
Minutes_Used = Usage_Duration.Minutes
If PriceType = "C" Then 'Custom pricing in blocks 0-5, 5-10 ... 55-60
MinutesToPrice = GetCustomPrice(Table_Number, "C", Minutes_Used, Price_DBColumn) '<-- this is where I fetch the pricing from database, Price_DBColumn = "Price1" will point to the database column for pricing of Offer 1, and Price2 means Offer 2
End If
HourToPrice = Hours_Used * Price
If PriceType = "C" Then
Result = HourToPrice + MinutesToPrice
ElseIf PriceType = "N" Then
Result = (Price / 60) * Usage_Duration_Rounded.TotalMinutes
End If
Return Result
End Function
GetCustomPrice()
функция будет искать базу данных, которая содержит данные в видеПример ниже:
Table_Number Minutes_Start Minutes_End Price1 Price2
1 0 5 0.050 0.100
1 5 10 0.100 0.150
1 10 15 0.400 0.500
. .. .. ..... .....
1 55 60 5.000 10.00
РЕДАКТИРОВАТЬ: (показывая, что я сделал с примером кода Дэвида)
-Output Test for CalculateOverlapPrice and CalculateOverlapMinutes functions
for the Range (IN : 23/09/2018 12:00:00 AM , OUT : 23/09/2018 01:00:00 AM)
[custArrival] : 23/09/2018 12:00:00 AM
[custExit] : 23/09/2018 01:00:00 AM
[currentDateOfferStart] : 23/09/2018 10:00:00 AM
[currentDateOfferEnd] : 23/09/2018 01:00:00 PM
[offer] : 5 Timing : 10:00 AM - 01:00 PM
Used Minutes : 0
Block Price : 0
-------------------
[custArrival] : 23/09/2018 12:00:00 AM
[custExit] : 23/09/2018 01:00:00 AM
[currentDateOfferStart] : 23/09/2018 01:00:00 PM
[currentDateOfferEnd] : 23/09/2018 06:00:00 PM
[offer] : 10 Timing : 01:00 PM - 06:00 PM
Used Minutes : 0
Block Price : 0
-------------------
[custArrival] : 23/09/2018 12:00:00 AM
[custExit] : 23/09/2018 01:00:00 AM
[currentDateOfferStart] : 23/09/2018 06:00:00 PM
[currentDateOfferEnd] : 24/09/2018 10:00:00 AM
[offer] : 5 Timing : 06:00 PM - 10:00 AM
Used Minutes : 0
Block Price : 0
-------------------
Total : 0
-------------------
-Подбор предложения отбазы данных и добавив их в список:
Dim Offer_Start As Date = CDate(dRow("TablePrice_StartPeriod"))
Dim Offer_End As Date = CDate(dRow("TablePrice_EndPeriod"))
Dim Price As Double = CDbl(dRow("TablePrice_HourlyRate"))
Offer_Start = New Date(1, 1, 1, Offer_Start.Hour, Offer_Start.Minute, 0)
If Offer_Start.Hour > Offer_End.Hour Or (Offer_Start.Hour = Offer_End.Hour And Offer_Start.Minute = Offer_End.Minute) Then ' it means offer end next day
Offer_End = New Date(1, 1, 2, Offer_End.Hour, Offer_End.Minute, 0)
Else
Offer_End = New Date(1, 1, 1, Offer_End.Hour, Offer_End.Minute, 0)
End If
Dim T_Offer As New Offer(Offer_Start, Offer_End, Price)
CurrentOffers.Add(T_Offer)
Новый
Я обновил свой код, чтобы получать предложения из базы данных, чтобы они были совместимы с новыми разделенными изменениями, предоставленными Дэвидом.а также настроил его для сортировки в противном случае CurrentOffers (0) .StartTime вернет неправильное время, которое я не выяснил, пока не использовал образец, предоставленный для тестирования.
Dim DB_Offer_Start As Date = CDate(dRow("TablePrice_StartPeriod"))
Dim DB_Offer_End As Date = CDate(dRow("TablePrice_EndPeriod"))
Dim Price As Double = CDbl(dRow("TablePrice_HourlyRate"))
Dim New_Offer_Start As Date = Nothing
Dim New_Offer_End As Date = Nothing
If DB_Offer_Start.Hour > DB_Offer_End.Hour Or (DB_Offer_Start.Hour = DB_Offer_End.Hour And DB_Offer_Start.Minute = DB_Offer_End.Minute) Then ' it means offer end next day
'================ Split offer into two ranges [Before Midnight to midnight PM to AM]
New_Offer_Start = New Date(1, 1, 1, DB_Offer_Start.Hour, DB_Offer_Start.Minute, 0)
New_Offer_End = New Date(1, 1, 2, 0, 0, 0)
CurrentOffers.Add(New Offer(New_Offer_Start, New_Offer_End, Price))
'======================================
'================ Split offer into two ranges [After Midnight to end time AM to AM/PM]
New_Offer_Start = New Date(1, 1, 1, 0, 0, 0)
New_Offer_End = New Date(1, 1, 1, DB_Offer_End.Hour, DB_Offer_End.Minute, 0)
CurrentOffers.Add(New Offer(New_Offer_Start, New_Offer_End, Price))
'======================================
Else
New_Offer_Start = New Date(1, 1, 1, DB_Offer_Start.Hour, DB_Offer_Start.Minute, 0)
New_Offer_End = New Date(1, 1, 1, DB_Offer_End.Hour, DB_Offer_End.Minute, 0)
CurrentOffers.Add(New Offer(New_Offer_Start, New_Offer_End, Price))
End If
Next
If CurrentOffers.Count > 0 Then 'Sort to had 0 or 12 AM as first
CurrentOffers.Sort(Function(x, y) x.StartTime.CompareTo(y.StartTime))
End If
Добавлено:Результаты тестов
Offers List
[offer] : 5 Timing : 01/01/0001 12:00:00 AM - 01/01/0001 10:00:00 AM
[offer] : 10 Timing : 01/01/0001 10:00:00 AM - 01/01/0001 01:00:00 PM
[offer] : 5 Timing : 01/01/0001 01:00:00 PM - 01/01/0001 06:00:00 PM
[offer] : 5 Timing : 01/01/0001 06:00:00 PM - 02/01/0001 12:00:00 AM
=====================================================
Output for range 22/09/2018 11:00:00 PM - 23/09/2018 11:00:00 AM
-------------------
[offer] : 5 Timing : 12:00 AM - 10:00 AM
Used Minutes : 0
Block Price : 0
-------------------
[offer] : 10 Timing : 10:00 AM - 01:00 PM
Used Minutes : 0
Block Price : 0
-------------------
[offer] : 5 Timing : 01:00 PM - 06:00 PM
Used Minutes : 0
Block Price : 0
-------------------
[offer] : 5 Timing : 06:00 PM - 12:00 AM
Used Minutes : 60
Block Price : 5
-------------------
This is inside the [If custExit.DayOfYear <> custArrival.DayOfYear Then] block
[offer] : 5 Timing : 12:00 AM - 10:00 AM
Cust Arrival/Exit Timing : 23/09/2018 12:00:00 AM - 23/09/2018 11:00:00 AM <--- Output of (New Date(custExit.Year, custExit.Month, custExit.Day, 0, 0, 0)) to custExit
Used Minutes : 600 <---- CalculateOverlapprice ignored the extra 1 hour, because offer block ended at 10 AM?
Block Price : 50
-------------------
Total : 55
-------------------
</code>