Adding a number of days to a JodaTime Instant

11,719

Solution 1

This is the solution that was chosen.

/**
* Zone to use for input and output
*/
private static final DateTimeZone ZONE = DateTimeZone.forId("Europe/London");

/**
 * Adds a number of days specified to the instant in time specified.
 *
 * @param instant - the date to be added to
 * @param numberOfDaysToAdd - the number of days to be added to the instant specified
 * @return an instant that has been incremented by the number of days specified
 */
public static Instant addNumberOfDaysToInstant(final Instant instant, final int numberOfDaysToAdd) {
    return instant.toDateTime(ZONE).withFieldAdded(DurationFieldType.days(), numberOfDaysToAdd).toInstant();
}

Solution 2

If you want to deal with dates, don't use instants. I suspect it's correctly adding 48 hours to the instant.

Use a LocalDate instead, and then the plusDays method.

If you want to know the instant that occurs n days after the specified instant, at the same time of day, we could no doubt work out a way of doing that (split the instant into a LocalDate and a LocalTime, advance the LocalDate and then reassemble, or check whether LocalDateTime does what you want) but you need to work out what you want to happen if the original time occurs twice on the new day, or doesn't occur at all.

EDIT: Okay, so you need to work with an instant. Does that have to be in an original time zone? Could you use UTC? That would take away the DST issues. If not, what do you want it to do in cases of ambiguity or non-existence (e.g. at 12.30am before each of the transitions).

Solution 3

Assuming the rest of your code:

public static void main(String[] args) {

  DateTime dateTime = FORMATTER.parseDateTime("24/10/2009");
  Instant pInstant = dateTime.withFieldAdded(DurationFieldType.days(),2).toInstant();
  System.out.println("24/10/2009  + 2 Days = " + pInstant.toString(FORMATTER));
}
Share:
11,719

Related videos on Youtube

mR_fr0g
Author by

mR_fr0g

I'm a physics graduate, but i have been working a enterprise java developer for about 3 years.

Updated on June 04, 2022

Comments

  • mR_fr0g
    mR_fr0g almost 2 years

    I'm trying to write a simple utility method for adding aninteger number of days to a Joda time instant. Here is my first stab.

    /**
     * Adds a number of days specified to the instant in time specified.
     *
     * @param instant - the date to be added to
     * @param numberOfDaysToAdd - the number of days to be added to the instant specified
     * @return an instant that has been incremented by the number of days specified
     */
    public static Instant addNumberOfDaysToInstant(final Instant instant, final int numberOfDaysToAdd) {
        Days days = Days.days(numberOfDaysToAdd);
        Interval interval = new Interval(instant, days);
        return interval.getEnd().toInstant();
    }
    

    This works fine for the most part except when you consider the example when the number of days added takes you across the BST / GMT boundary. Here is a small example.

    public class DateAddTest {
    

    /** * Zone to use for input and output */ private static final DateTimeZone ZONE = DateTimeZone.forId("Europe/London");

    /**
     * Formatter used to translate Instant objects to & from strings.
     */
    private static final DateTimeFormatter FORMATTER = DateTimeFormat.forPattern(DATE_FORMAT).withZone(ZONE);
    
    
    /**
     * Date format to be used
     */
    private static final String DATE_FORMAT = "dd/MM/yyyy";
    
    
    public static void main(String[] args) {
    
     DateTime dateTime = FORMATTER.parseDateTime("24/10/2009");
     Instant toAdd = dateTime.toInstant();
     Instant answer = JodaTimeUtils.addNumberOfDaysToInstant(toAdd, 2);
    
     System.out.println(answer.toString(FORMATTER)); //25/10/2009
    }
    

    }

    I think this problem is because the interval does not take into acount the fact that it has crossing the bst boundary. Any ideas of a better way to implement this would be appreciated.

    • laz
      laz almost 15 years
      What time zone are you expecting the Instant argument to be created from? Will it be consistent? The calculation is meaningless without that value being factored in somehow since you are unable to utilize the original fix suggested by Jon.
  • mR_fr0g
    mR_fr0g almost 15 years
    I am aware that LocalDate is more apporpriate than instant in this case, but cannot change it due to other constraints.
  • JodaStephen
    JodaStephen almost 15 years
    This is simpler: return instant.toDateTime(ZONE).plusDays(numberOfDaysToAdd).toInsta‌​nt();