Вопрос

I'm about to write lines of some simple math and wanted to make sure that there wasn't some simple high level construct in Joda-Time to do this already.

I have an object that represents a day of the week, an hour of the day, and a minute of the hour. For example "Wednesday at 10:14am".

I want to calculate the number of milliseconds until the next occurrence. For example if now is Thursday at 10:14 it would be 6 days worth of milliseconds. This is because Wednesday has already passed so it will take 6 days to get to the next Wednesday. If now is Wednesday at 10:13.0001 it will be 999.

Is there a high level construct in Joda-Time so I can do this in one or two lines of code or do I need to do the math myself (including edge cases to wrap on stuff like DOW < DOW_NOW).

Thanks!

Here's my novice try that does not yet work to give you some reference:

public MutableDateTime getDateTime() {
    MutableDateTime date = MutableDateTime.now();
    date.setDayOfWeek(this.day);
    date.setHourOfDay(this.hour);
    return date;
}

public long getTimeUntilNextFrom( DateTime from ) {
    MutableDateTime to = getDateTime();
    if (to.isBefore( from )) {
        to.setWeekOfWeekyear(from.getWeekOfWeekyear() + 1);
    }

    return new Interval(from, to).toDurationMillis();
}
Это было полезно?

Решение

You could do something like this:

import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Interval;
import org.joda.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        Interval interval = betweenNowAndNext(DateTimeConstants.MONDAY, new LocalTime(10, 14));
        System.out.println(interval.toDurationMillis());
    }

    public static Interval betweenNowAndNext(int dayOfWeek, LocalTime time) {
        DateTime now = DateTime.now();
        DateTime closest = time.toDateTime(now).withDayOfWeek(dayOfWeek);
        return new Interval(now, closest.isBefore(now) ? closest.plusWeeks(1) : closest);
    }
}

Другие советы

I would do it like this:

public class DistanceCalculator {
    public long getMillisecondTillNext(int dayOfWeek, int hourOfDay, int minuteOfHour) {
        DateTime now = DateTime.now();
        DateTime next = DateTime.now().withDayOfWeek(dayOfWeek).withHourOfDay(hourOfDay).withMinuteOfHour(minuteOfHour);
        long distance = next.getMillis() - now.getMillis();
        return distance > 0 ? distance : week() - distance;
    }

    private long week() {
        return new DateTime(0).plusWeeks(1).getMillis();
    }
}

Haven't hear of any readymade method to get this in Joda...

Here's what I came up with on my own. Still, would be nice to have a solution in fewer lines of code. They DayHour is the class I am working with. It contains a day of the week and the hour of the day.

public class DayHour {
    int day;
    int hour;

    public DayHour(int day, int hour) {
        this.day = day;
        this.hour = hour;
    }

    public MutableDateTime getDateTime(DateTime base) {
        MutableDateTime date = base.toMutableDateTime();
        date.setDayOfWeek(this.day);
        date.setHourOfDay(this.hour);
        return date;
    }

    public long getTimeUntilNextFrom(DateTime from) {
        MutableDateTime to = getDateTime(from);
        if (to.isBefore(from)) {
            to.setWeekOfWeekyear(from.getWeekOfWeekyear() + 1);
        }

        return new Interval(from, to).toDurationMillis();
    }
}

@Test
public void testDayHour() {
    DateTime now = DateTime.now();
    DayHour date = new DayHour(now.getDayOfWeek(), now.getHourOfDay());

    MutableDateTime yesterday = now.toMutableDateTime();
    yesterday.addDays(-1);
    assertEquals(TimeUnit.DAYS.toMillis(1), date.getTimeUntilNextFrom(yesterday.toDateTime()));

    MutableDateTime tomorrow = now.toMutableDateTime();
    tomorrow.addDays(1);
    assertEquals(TimeUnit.DAYS.toMillis(6), date.getTimeUntilNextFrom(tomorrow.toDateTime()));
}

Not quite sure what you are doing. But if what you want is a countdown in milliseconds, I would use the Joda-Time Seconds class with its secondsBetween method. Multiply by 1,000 to report approximate milliseconds. On the last second, switch gears to use the .getMillis method if you truly need that.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top