Android日期,在正确的时间添加毫秒

时间:2016-04-20 02:17:46

标签: java android date

我要做的是存储一个日期,以毫秒为单位,即当前时间的下一个午夜。所以,在晚上10:11发布,我想要一个代表明天早上12:00的日期。为此,我写了这行代码(知道一天有86400000毫秒):

long time = System.currentTimeMillis() + (86400000 - (System.currentTimeMillis() % 86400000));

该行旨在计算从上一个午夜开始的额外毫秒数,减去一整天的时间以查找到下一个午夜的时间,然后将其添加到当前时间,以便新值为下一个午夜的值午夜。无论出于何种原因,我用于调试的日期对象吐出" Wed Apr 20 20:00:00 EDT 2016"调用#toString()方法时。据说目前的时间是“2016年4月19日22:08:34 EDT 2016"在计算另一个日期的同时。

这意味着长毫秒实际上代表第二天晚上8点,而我希望它代表12:00 AM。任何人都可以帮助我发现我逻辑中的缺陷吗?

我很可能错过了一些明显的东西,所以请耐心等待。

注意:我也尝试过像这样计算时间:

long time = System.currentTimeMillis() - (System.currentTimeMillis() % 86400000) + 86400000;

但是这导致了相同的Date对象。

3 个答案:

答案 0 :(得分:1)

您忘记调整时区。这是实现这一目标的简单方法。

TimeZone tz = TimeZone.getDefault();
long time = System.currentTimeMillis() + (86400000 - (System.currentTimeMillis() % 86400000));
time -= tz.getOffset(time);

System.out.println(new Date(time));

答案 1 :(得分:1)

java.time

你正在使用长期被取代的有缺陷的麻烦的日期时间类,首先是Joda-Time库,现在是它的继承者,Java 8及更高版本中内置的java.time框架。很多java.time已经被反向移植到Java 6& 7然后由ThreeTenABP项目改编为Android。

Instant是UTC时间轴上的一个时刻,分辨率为纳秒。

Instant instant = Instant.now();

应用时区以获得ZonedDateTime。时区对于确定日期至关重要。它可能已经在你的东边“明天”或西边的“昨天”。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( zoneId );

要获得当天的第一时刻,请不要认为时间是00:00:00.0。夏令时等异常可能会导致不同的时间。让java.time确定那个时间。要做到这一点,我们必须通过LocalDate课程。

LocalDate today = zdt.toLocalDate();

天数并不总是24小时,这在您的问题和代码中是不正确的假设。再次,让java.time通过调用plusDays确定第二天。

LocalDate tomorrow = LocalDate.plusDays( 1 );
ZonedDateTime zdtTomorrowStart = tomorrow.atStartOfDay( zoneId );

我建议您避免将日期时间值作为纪元的计数进行跟踪。这容易出错,并且非常难以调试。当你从纳秒分辨率变为毫秒时,你将丢失数据。但如果你坚持的话。

long millis = zdtTomorrowStart.toInstant().toEpochMilli();

答案 2 :(得分:0)

直接时间计算可能很棘手,有很多极端情况。我认为避免它的最简单的解决方案是:

    // now, with current timezone and locale
    Calendar calendar = new GregorianCalendar();
    // tomorrow
    calendar.add(Calendar.DAY_OF_MONTH, 1);
    // midnight
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    // get the resulting date
    Date date = calendar.getTime();