Vitaly Kononenko
Vitaly Kononenko

Reputation: 21

Time within working hours - check one liner in Kotlin

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.

Upvotes: 1

Views: 1225

Answers (2)

Vitaly Kononenko
Vitaly Kononenko

Reputation: 21

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)
            }
        }
    }

Upvotes: 1

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79105

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.

Upvotes: 1

Related Questions