small problem here. I have an android countdown timer that works fine, but the issue is the countdown timer will be different between users/timezone. By this I mean, for every timezone, users of my app will see a different countdown that may end earlier or later relative to their timezone.I don't want this, I want it so all countdowns end at the same time for THIS movie release.
My code:
Note: some code is omitted for brevity and please check out the comments below for some explanation of the code
// the current date and time
Calendar today = Calendar.getInstance();
// release.date is in milliseconds at 12am and in GMT, example: GMT: Friday, September 29, 2017 12:00:00 AM
long currentTimeMillis = today.getTimeInMillis();
long expiryTime = releaseDate.date - currentTimeMillis;
holder.mTextCountdown.setText("");
if (holder.timer != null) {
// Cancel if not null to stop flickering
holder.timer.cancel();
}
holder.timer = new CountDownTimer(expiryTime, 500) {
public void onTick(long millisUntilFinished) {
long seconds = millisUntilFinished / 1000; // reminder: 1 sec = 1000 millis
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
String dayFormat = "days";
String hoursFormat = "hours";
if (days == 1) {
dayFormat = "day";
}
if (hours == 1) {
hoursFormat = "hour";
}
String time = days + " " + dayFormat + " : " + hours % 24 + " " + hoursFormat +" : " + minutes % 60 + " : " + seconds % 60;
holder.mTextCountdown.setText(time);
}
// Finished: counted down to 0
public void onFinish() {
holder.mTextCountdown.setText("Now out!");
}
}.start();
How can I count down a timer in GMT/UTC, where for every user it's sure to end at the same time?
Thank you
I'd recommend you to do following 2 things:
- Store all times in UTC, and convert it to local timezone only for UI output
- Synchronize time (and set it) from server side. Anyway, you can't control what time is it now at client device — it can be in wrong timezone, or have time servers off by some reason, and local time can be incorrect. Just sync time on user device with server time, store the delta if any, and show countdown based on server time.
Use modern java.time classes rather than the troublesome old Calendar
/Date
classes. For Android, see the last bullets below.
Say your movie releases at 5 PM in Los Angeles time on September 23rd.
LocalDate ld = LocalDate.of( 2017 , 9 , 23 ) ;
LocalTime lt = LocalTime.of( 17 , 0 ) ;
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
Convert that to UTC, a Instant
object.
Instant instant = zdt.toInstant() ; // Convert from a time zone to UTC. Same point on the timeline.
Calculate the time until then, as a Duration
.
Duration d = Duration.between( Instant.now() , instant ) ;
Extract your number of milliseconds.
long millis = d.toMillis() ;
Perhaps you want to show the movie release date-time to a user in Québec.
ZonedId zUser = ZoneId.of( "America/Quebec" ) ;
ZonedDateTime zdtUser = instant.atZone( zUser ) ; // Adjust into user’s time zone. Some point on the timeline.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH ) ;
String output = zdtUser.format( f ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
- See How to use ThreeTenABP….