Reputation: 53
I am developing an Android app using Kotlin and I would like to achieve the following:
What is the best way to deal with time operations (subtract current time to the alert time) in Kotlin?
Upvotes: 1
Views: 1997
Reputation: 53
According to Basil Bourque, the following is the code he proposed (in Java) converted to Kotlin, just in case someone is interested.
// Credit to Basil Bourque Answer
// https://stackoverflow.com/questions/59846004/what-is-the-best-way-to-operate-with-time-in-kotlin/59846550#59846550
lateinit var zdt: ZonedDateTime
val targetLocaltime = LocalTime.of(21, 0)
val z = ZoneId.of("Europe/Madrid")
val now = ZonedDateTime.now(z)
val runToday = now.toLocalTime().isBefore(targetLocaltime)
zdt = if (runToday){
now.with(targetLocaltime)
}
else{
now.toLocalDate().plusDays(1).atStartOfDay(z).with(targetLocaltime)
}
val eta = Duration.between(now.toInstant(), zdt.toInstant()).toMinutes()
if(eta > 60){
val hours = eta / 60
val minutes = eta % 60
print("$hours:$minutes remaining")
}
else{
print("$eta minutes remaining")
}
Upvotes: 0
Reputation: 338775
All your questions have been asked and answered many times on Stack Overflow. So I’ll be brief. Search to learn more.
Use only java.time classes, never the terrible legacy classes such as Date
and Calendar
.
For Android before 26, see the ThreeTen-Backport library and its Android-specific wrapper ThreeTenABP.
Represent a time-of-day with LocalTime
.
LocalTime targetLocalTime = LocalTime.of( 15 , 0 ) ;
Get current moment. Requires a time zone. 2-4 letter codes like CST
are not real time zones. Real zones are named Continent/Region
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
Compare time portion. Extract a LocalTime
to compare.
Boolean runToday = now.toLocalTime().isBefore( targetLocalTime ) ;
Determining next alarm time.
ZonedDateTime zdt = now.with( targetLocalTime ) ;
Or if needed on next day, tomorrow.
ZonedDateTime zdt = now.toLocalDate().plusDays( 1 ).atStartOfDay( z ).with( targetLocalTime ) ;
Calculate elapsed time. Adjust to UTC by extracting an Instant
.
Duration d = Duration.between( now.toInstant() , zdt.toInstant() ) ;
Generate string in standard ISO 8601 format.
String output = d.toString() ;
Or generate a string in another format by calling the Duration::to…Part
methods.
As for firing the alarm, in straight Java use the Executors framework, specifically ScheduledExecutorService
. This framework makes it simple to run a background thread that fires a task Runnable
at a certain moment. Well, nearly certain — slight delays may occur for garbage-collection or thread/process scheduling on the CPU, but good enough for business apps (not good enough for NASA).
Android may also provide some alarm-setting feature. (I don’t know)
Never ever access or manipulate your user-interface from a background thread. Use whatever hook Android provides to update the UI from another thread, such as refreshing a UI widget or presenting a notification.
Upvotes: 4