2009-06-29 8 views
6

J'essaie d'écrire une méthode utilitaire simple pour ajouter un nombre entier de jours à un temps Joda instant. Voici mon premier coup de couteau.Ajout d'un nombre de jours à un JodaTime Instant

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

Cela fonctionne très bien pour la plupart, sauf si l'on considère l'exemple lorsque le nombre de jours supplémentaires vous emmène à travers la frontière BST/GMT. Voici un petit exemple.

public class DateAddTest { 

/** * Zone à utiliser pour l'entrée et la sortie */ private static final DateTimeZone ZONE = DateTimeZone.forId ("Europe/Londres");

/** 
* 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 
} 

}

Je pense que ce problème est que l'intervalle ne prend pas en acount le fait qu'il a traversé la frontière bst. Toute idée d'un meilleur moyen de mettre en œuvre ceci serait appréciée.

+1

De quel fuseau horaire souhaitez-vous créer l'argument instantané? Est-ce que ce sera cohérent? Le calcul est dénué de sens sans que cette valeur soit prise en compte d'une manière ou d'une autre puisque vous ne pouvez pas utiliser le correctif original proposé par Jon. – laz

Répondre

0

Ceci est la solution qui a été choisie.

/** 
* 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(); 
} 
+4

Ceci est plus simple: renvoie instant.toDateTime (ZONE) .plusDays (numberOfDaysToAdd) .toInstant(); – JodaStephen

7

Si vous voulez traiter avec dates, n'utilisez pas d'instants. Je suppose que cela ajoute correctement 48 heures à l'instant. À la place, utilisez un LocalDate, puis la méthode plusDays.

Si vous voulez connaître l'instant qui se produit n jours après l'instant spécifié, à la même heure, nous pourrions sans aucun doute trouver un moyen de le faire (diviser l'instant en LocalDate et un , avance LocalDate puis réassemblez ou vérifiez si LocalDateTime fait ce que vous voulez) mais vous devez déterminer ce que vous voulez faire si l'heure d'origine arrive deux fois le jour suivant ou ne se produit pas du tout.

EDIT: Bon, vous devez donc travailler en un instant. Est-ce que cela doit être dans un fuseau horaire d'origine? Pourriez-vous utiliser UTC? Cela enlèverait les problèmes de DST. Sinon, que voulez-vous faire en cas d'ambiguïté ou de non-existence (par exemple à 12h30 avant chacune des transitions).

+0

Je suis conscient que LocalDate est plus apparent que instantané dans ce cas, mais ne peut pas le modifier en raison d'autres contraintes. –

2

En supposant que le reste de votre 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)); 
}