I'm trying to create a flow with coroutines but it's not giving to me the expected result. What I'd like to have is giving an expiration time (doesn't matter if it's in millis, seconds, etc..) when the time arrives to 0 it stops the countdown. What I have now is :
private fun tickerFlow(start: Long, end: Long = 0L) = flow {
var count = start
while (count >= end) {
emit(Unit)
count--
delay(1_000L)
}
}
And then I call this function as :
val expireDate = LocalDateTime.now().plusSeconds(10L).toEpochSecond(ZoneOffset.UTC)
tickerFlow(expireDate)
.map { LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - expireDate }
.distinctUntilChanged { old, new ->
old == new
}
.onEach {
//Here I should print the timer going down with this pattern
//00h: 00m: 00s I did it with String.format("%02dh: %02dm: %02ds") and it works though.
}
.onCompletion {
//Setting the text when completed
}
.launchIn(scope = scope)
But even with this test that what I'm trying is to have the expiry time as 10 seconds from now it doesn't print nor end as I would. Am I missing something? Is there any way I could emit the local date time so I have the hours, minutes and seconds? perhaps I have to do the calculus to get the seconds, minutes hours from milis / seconds.
TLDR;
I'm getting from backend an expiry date, and I want to know when this expiry date finish so I have to calculate it with the now() and check when it is expired.
You don't really need a flow here. Try this code:
Also, this code is safe to run on main thread as
delaydoesn't block.In your code, the problem is that you are passing the
expireDateitself totickerFlow.expireDatecontains the time in seconds from epoch and not the seconds difference from current time. Just passexpireDate - LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)to tickerFlow and it will work.EDIT: Complete implementation using flow