1

I need to show a red dot inside a recyclerView when a list item business working and red when it does not.

I use databinding, API 24, with the ability to use Java 8 calls (particularly API 26 new java.Time and its LocalTime and LocalDate).

//Get local date way 1
var day: String = LocalDate.now().dayOfWeek.name
var time: String = LocalTime.now().toString()//.hour.toString()
//Get local date way 2
val calendar = Calendar.getInstance()
val dateInfo = DateFormat.getDateInstance(DateFormat.FULL).format(calendar.time)
//Get local date way 3
var date = Date()

I receive working hours from the server in the following format:

"schedule_1": "09:00 22:00",
"schedule_2": "09:00 22:00",
"schedule_3": "09:00 22:00",
"schedule_4": "09:00 22:00",
"schedule_5": "09:00 22:00",
"schedule_6": "09:00 17:00",
"schedule_7": "",

Each schedule is the day of the week, so I need to check if it is today.

Most of the questions on Stack Overflow compare two timestamps or two dates and they are all one-pagers, but I want time inside working hours one-liner.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • I don't understand your question exactly. do you want to parse this String "09:10 22:10" to two dateTime? – mohamad jalali Jul 15 '21 at 08:16
  • No. I want function which takes current system time and compares it with time period and returns boolean if to say narrowly. But If somebody will be so kind to copy full solution from his project elegant and short this will be appreciated. – Vitaly Kononenko Jul 15 '21 at 08:21
  • Just compare the time? Doesn't the day matter? – mohamad jalali Jul 15 '21 at 08:31
  • It is matter because it is working hours with are different. How exactly do you propose to compare times? StartOfDay.compare(now) && EndOfDay.compare(now)? Or StartWorkingHours + duration > now? It is about elegance and speed (given it recyclerview). I want to comeback to this code and reuse it and never think about how to do it fast again. May be someone will propose good extension function? I want to say that it should be library function for such trivial task but we still reinvent the wheel everyone by himself – Vitaly Kononenko Jul 15 '21 at 08:43
  • 1
    Hello Arvind. Thank you for your solution. It is fine. Additionally I will post how I solved it. I upvote your unswer but unfortunately my rating does not allow me to upvote publicly - it just say "your vote recorded". – Vitaly Kononenko Jul 16 '21 at 13:21
  • What do you mean by "one liner"? – Peter Mortensen Jul 17 '21 at 00:40
  • @VitalyKononenko - As long as you found my answer helpful, that's the biggest reward for me. You become eligible to upvote when you have 15+ points before which you can only accept the answer (i.e. click the ✅ mark left to the answer). – Arvind Kumar Avinash Jul 17 '21 at 09:18

2 Answers2

1

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

Solution using java.time, the modern Date-Time API:

You can compare the current time with the start and the end of the business hours using the functions LocalTime#isAfter and LocalTime#isBefore.

Demo:

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Map;

public class Main {
    public static void main(String[] args) {
        //Test      
        System.out.println(isBusinessHour());
    }
    static boolean isBusinessHour() {
        boolean businessHour = false;
        
        Map<String, String> map = Map.of(
                "schedule_1", "09:00 22:00", 
                "schedule_2", "09:00 22:00", 
                "schedule_3", "09:00 22:00", 
                "schedule_4", "09:00 22:00", 
                "schedule_5", "09:00 22:00", 
                "schedule_6", "09:00 17:00",
                "schedule_7", ""
        );
        
        LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Europe/Moscow"));
        String key = "schedule_" + ldt.getDayOfWeek().getValue();
        String[] businessHours = map.get(key).split(" ");
        if(businessHours.length == 2) {
            LocalTime start = LocalTime.parse(businessHours[0]);
            LocalTime end = LocalTime.parse(businessHours[1]);
            LocalTime now = ldt.toLocalTime();
            businessHour = !now.isBefore(start) && !now.isAfter(end);
        }
        
        return businessHour;
    }
}

The output from a sample run:

false

ONLINE DEMO

Learn more about the modern Date-Time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
1

Icon color tint implementation of working hours switching between green and red.

 @BindingAdapter("app:workingHoursColoredDot")
    fun workingHoursColoredDot(view: ImageView, terminalItem:NetworkTerminal){
        terminalItem?.let {
            var day = LocalDate.now().dayOfWeek.value//.ordinal
            var time = LocalTime.now()
            val networkDate = when (day) {
                1 -> terminalItem.schedule_1
                2 -> terminalItem.schedule_2
                3 -> terminalItem.schedule_3
                4 -> terminalItem.schedule_4
                5 -> terminalItem.schedule_5
                6 -> terminalItem.schedule_6
                7 -> terminalItem.schedule_7
                else -> throw IllegalArgumentException()
            }
            Log.d("BindingAdapters", "val networkDate = terminalItem.schedule_1 $networkDate")
            if (!networkDate.isNullOrEmpty()) {
                val (startTimeString, endTimeString) = networkDate.split(" ")
                Log.d("BindingAdapters", "val (startTime, endTime) = $startTimeString $endTimeString")
                val startTime: LocalTime = LocalTime.parse(startTimeString, DateTimeFormatter.ofPattern("H:mm"))
                val endTime: LocalTime= LocalTime.parse(endTimeString, DateTimeFormatter.ofPattern("H:mm"))
                var businessWorking = time.isAfter(startTime) and time.isBefore(endTime)
                if (businessWorking)view.backgroundTintList = ContextCompat.getColorStateList(view.context, R.color.green_dot) else view.backgroundTintList = ContextCompat.getColorStateList(view.context, R.color.red)
            }
        }
    }