Android倒计时基于GMT / UTC而非用户的时区

时间:2017-09-20 21:59:18

标签: android datetime calendar timezone

这里的小问题。我有一个Android倒计时器工作正常,但问题是倒数计时器将在用户/时区之间有所不同。我的意思是,对于每个时区,我的应用程序的用户都会看到不同的倒计时,可能会相对于他们的时区更早或更晚结束。我不想要这个,我想要它所以所有倒计时都会同时结束这部电影发布。

我的代码: 注意:为简洁起见,省略了一些代码,请查看下面的注释以获得代码的一些解释

        // 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();

如何计算GMT / UTC中的计时器,对于每个用户,它肯定会同时结束?

谢谢

2 个答案:

答案 0 :(得分:2)

使用现代java.time类而不是麻烦的旧Calendar / Date类。对于Android,请参阅下面的最后一个项目符号。

说你的电影将于9月23日洛杉矶时间下午5点发布。

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

将其转换为UTC,Instant对象。

Instant instant = zdt.toInstant() ;  // Convert from a time zone to UTC. Same point on the timeline.

计算到那时为止的时间,为Duration

Duration d = Duration.between( Instant.now() , instant ) ;

提取您的毫秒数。

long millis = d.toMillis() ;

也许您想向魁北克的用户展示电影发布日期时间。

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

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

答案 1 :(得分:1)

我建议你做两件事:

  1. 以UTC格式存储所有时间,并仅将其转换为本地时区以进行UI输出
  2. 从服务器端同步时间(并设置它)。无论如何,您无法控制客户端设备现在的时间 - 它可能处于错误的时区,或者由于某种原因关闭时间服务器,并且本地时间可能不正确。只需将用户设备上的时间与服务器时间同步,存储增量(如果有),并根据服务器时间显示倒计时。