Android Question Date manipulation

Mattiaf

Active Member
Licensed User
Hey guys,

I wrote a vb.net code where I'm going to guess which shift I'll be working on a working cycle like
5 afternoon shifts
1 day off
5 morning shifts
1 day off
5 night shift
1 day off
and so forth

But I'm trying to replicate it for b4x but to be honest, I literally don't know where to start :\

Would someone mind to help me?
Much thanks..
Code

B4X:
Public Class Form1

    Private Sub DisplayShifts()
        Dim startdate = New DateTime(2022, 12, 24)
        Dim selectedDate = DateTimePicker1.Value

        Dim shift = GetShift(startdate, selectedDate)
        MsgBox(shift.ToString())
    End Sub
    Function GetShift(startDate As Date, selectedDate As Date) As ShiftKind
        Dim days = (selectedDate - startDate).TotalDays
        Dim intervals = days \ 18
        Dim normalizedSelected = selectedDate.AddDays(intervals * -18)
        days = (normalizedSelected - startDate).TotalDays
        Select Case days
            Case 0 To 4
                Return ShiftKind.Afternoon
            Case 6 To 10
                Return ShiftKind.Morning
            Case 12 To 16
                Return ShiftKind.Night
        End Select
        Return ShiftKind.Off
    End Function
    Public Structure Shift
        Public Property StartDate As Date
        Public Property EndDate As Date
        Public Property Kind As ShiftKind
        Public Function Contains(value As Date) As Boolean
            Return value >= StartDate AndAlso value <= EndDate
        End Function
        Public Overrides Function ToString() As String
            Return $"{StartDate} - {EndDate} : {Kind}"
        End Function
    End Structure
    Public Enum ShiftKind
        Off = 1
        Morning
        Afternoon
        Night
    End Enum

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        DisplayShifts()
    End Sub
End Class
 

Mattiaf

Active Member
Licensed User
I thought we were going with date format DD-MM-YYYY :



As noted earlier, for doing Map lookups, dates have to be in the chosen format precisely:



but these dates:



are instead MM/DD/YYYY.
hmm i don't get it.. I would like the date to be in dd-mm-yyyy like stated before...
B4X:
ShiftSchedule.Put(ZeroPadLeft(D, 2) & "-" & ZeroPadLeft(M, 2) & "-" & Y, ShiftPattern.CharAt(ShiftPatternDay).As(String))

do you mean i can't choose this kind of date type?
 
Upvote 0

emexes

Expert
Licensed User

That's no problem, you can use whatever date format you like ? as long as you use the same format for Map.Get as you did for Map.Put ?

do you mean i can't choose this kind of date type?

no, I mean that if you don't keep to the one consistent format, then you're going to get stuff like this:


where (I am guessing) that Map.Get("12/30/2022") is not finding the entry added as Map.Put("30/12/2022"...)
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Add in B4XPage_Created the line below and it will work.
B4X:
DateTime.DateFormat = "dd-MM-yyyy"
Your problem is that you use a specific date format for the map but you use the default date format else where !
As emexes already told you, if you check for the shift with the wrong format nothing will be found.
 
Upvote 0

Mattiaf

Active Member
Licensed User
Thanks a lot to bot of you guys!
Just a question..
B4X:
    Dim ShiftName As Map

    ShiftName.Initialize
    ShiftName.Put("Mattino", "Morning   9am to 5pm")
    ShiftName.Put("Pomeriggio", "Afternoon 5pm to 1am next day")
    ShiftName.Put("Notte", "Night     1am to 9am")
    ShiftName.Put("off", "?")

    Dim ShiftSchedule As Map = ConstructShiftSchedule(2020, 2026, "mmmmm-aaaaa-nnnnn-",9)

How can I make appear on the logs "Mattino" instead of "m"?

I would like also to take the advantage of this situation to implement a new shift system
If I work like
2 mornings
2afternoons
2nights ( nights from 22 to 06 am)
1.5 days off ( 0.5 less than 2 days because on the second night, when i will end the shift, from 6 am to midnight I will consider it off)

what should I change in the code?
 
Upvote 0

emexes

Expert
Licensed User
Just a question..

Lol I might be one step ahead of you now that I've seen that you're using words to indicate shifts, rather than single characters like "m", "p", "n", "-"

but let's see what the question is ?


I'd go back to using single-character codes, and then change the description(s), which I think in your project would then look something like:

B4X:
ShiftName.Initialize
ShiftName.Put("m", "Mattino    09:00-17:00")
ShiftName.Put("p", "Pomeriggio 17:00-01:00 del giorno successivo")
ShiftName.Put("n", "Notte      01:00-09:00")
ShiftName.Put("-", "? dormire, non lavorare ?")


Firstly, change the shift single-character codes and whatever-you-like descriptions to:

B4X:
ShiftName.Initialize
ShiftName.Put("m", "Mattino")
ShiftName.Put("p", "Pomeriggio")
ShiftName.Put("n", "Notte 22:00-06:00 del giorno successivo")
ShiftName.Put("-", "? dormire, non lavorare ?")

and the shift pattern to:

B4X:
Dim ShiftSchedule As Map = ConstructShiftSchedule(2020, 2026, "mmppnn--", 3)    '6 days on, 2 days off

(you might need to adjust the 3 to another number between 0 and 5, to align the shift pattern with calendar date)

but I can't help you much with the 1.5 days finessing because calendars do only whole days, not half days. We can either have:

- one day break, eg Sunday night shift finishes Monday morning 06:00, then you have one day off ( no shift scheduled starting Monday) and back to work Tuesday morning

or:

-two day break, eg Sunday night shift finishes Monday morning 06:00, then you have two days off (no shift scheduled starting Monday and Tuesday) and back to work Wednesday morning
 
Last edited:
Upvote 0

Mattiaf

Active Member
Licensed User
i like the way you put some beers here and there around ?
and how you translate some italian too, quite funny!!
I m working at the moment, I ll try it in the morning!!
what do you think about leaving the 2nd day as day off, but the first one, instead, put like "riposo smontante", which means "rest after I get off work"?

somm/pp/nnoff/off

?
just assuming ?
 
Upvote 0

emexes

Expert
Licensed User
somm/pp/nnoff/off

Need to use one-character (single character) shift codes when specifying shift pattern.

what do you think about leaving the 2nd day as day off, but the first one, instead, put like "riposo smontante", which means "rest after I get off work"?

Righto, changes are:

- date format for ShiftSchedule Map lookups is DD-MM-YYYY (as settled on by you, me and @klaus ???)
- added Modulus function (Sub) because I am tired of working around broken -n Mod m operator
- added a second day-off shift type ("-" is first day off, possibly not a full day; "+" is second and subsequent full days off)
- changed shift schedule to ""mmppnn-+" ie 2 x morning, 2 x afternoon, 2 x night, 2 x days off
- adjusted ShiftDateAlign to 6, so that Christmas Day is Party Day

Your mission, should you choose to accept it or not, is to link your calendar with shift information looked up by ShiftSchedule.Get("DD-MM-YYYY"). ???

I think you'll be needing more than one beer for that job. ?

B4X:
Sub ConstructShiftSchedule(FromYear As Int, ToYear As Int, ShiftPattern As String, ShiftDateAlign As Int) As Map
   
    Dim ShiftSchedule As Map
    ShiftSchedule.Initialize
   
    Dim ShiftPatternDay As Int = Modulus(ShiftDateAlign, ShiftPattern.Length)    'get into range 0 .. (ShiftPattern.Length - 1) inclusive
   
    For Y = FromYear To ToYear
        For M = 1 To 12
            For D = 1 To NumDaysInMonth(Y, M)
                ShiftSchedule.Put(ZeroPadLeft(D, 2) & "-" & ZeroPadLeft(M, 2) & "-" & Y, ShiftPattern.CharAt(ShiftPatternDay).As(String))
                ShiftPatternDay = (ShiftPatternDay + 1) Mod ShiftPattern.Length    'keep within range
            Next
        Next
    Next
   
    Return ShiftSchedule
   
End Sub

Sub Modulus(N As Int, D As Int) As Int
   
    Return ((N Mod D) + D) Mod D    'fix for negative N
   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   
    Activity.LoadLayout("Layout")

    Dim ShiftName As Map
    ShiftName.Initialize
    ShiftName.Put("m", "Mattino    09:00-17:00")
    ShiftName.Put("p", "Pomeriggio 17:00-01:00 del giorno successivo")
    ShiftName.Put("n", "Notte      01:00-09:00")
    ShiftName.Put("-", "    ? dormire, non lavorare ?")
    ShiftName.Put("+", "    ? festa tutto il giorno ?")

    Dim ShiftSchedule As Map = ConstructShiftSchedule(2020, 2026, "mmppnn-+", 6)
   
    For D = 10 To 31
        Dim DateToGet As String = D & "-12-2022"
        Log(                                                     _
            DateToGet                                    & TAB & _
            ShiftSchedule.Get(DateToGet)                & TAB & _
            ShiftName.Get(ShiftSchedule.Get(DateToGet))         _
        )
    Next

End Sub

Log output:
Logger connected to:  TCL 5009A
** Activity (main) Create, isFirst = true **
10-12-2022    m    Mattino    09:00-17:00
11-12-2022    m    Mattino    09:00-17:00
12-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
13-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
14-12-2022    n    Notte      01:00-09:00
15-12-2022    n    Notte      01:00-09:00
16-12-2022    -        ? dormire, non lavorare ?
17-12-2022    +        ? festa tutto il giorno ?
18-12-2022    m    Mattino    09:00-17:00
19-12-2022    m    Mattino    09:00-17:00
20-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
21-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
22-12-2022    n    Notte      01:00-09:00
23-12-2022    n    Notte      01:00-09:00
24-12-2022    -        ? dormire, non lavorare ?
25-12-2022    +        ? festa tutto il giorno ?
26-12-2022    m    Mattino    09:00-17:00
27-12-2022    m    Mattino    09:00-17:00
28-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
29-12-2022    p    Pomeriggio 17:00-01:00 del giorno successivo
30-12-2022    n    Notte      01:00-09:00
31-12-2022    n    Notte      01:00-09:00
** Activity (main) Resume **
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…