Je travaille dans un projet et j'ai deux types dans Date. Je veux calculer le nombre de semaines entre ces deux dates. Les dates peuvent être différentes années. Y a-t-il une bonne solution pour cela?
J'ai essayé d'implémenter cela avec Joda-time, ce qui a été suggéré dans d'autres sujets.
Je ne suis pas familier avec cette bibliothèque, mais j'ai essayé de faire quelque chose comme ceci:
public static int getNumberOfWeeks(Date f, Date l){
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(f);
c2.setTime(l);
DateTime start = new DateTime(c1.YEAR, c1.MONTH, c1.DAY_OF_MONTH, 0, 0, 0, 0);
DateTime end = new DateTime(c2.YEAR, c2.MONTH, c2.DAY_OF_MONTH, 0, 0, 0, 0);
Interval interval = new Interval(start, end);
Period p = interval.toPeriod();
return p.getWeeks();
}
Mais c'est complètement faux ... des suggestions?
C'est assez facile avec joda time :
DateTime dateTime1 = new DateTime(date1);
DateTime dateTime2 = new DateTime(date2);
int weeks = Weeks.weeksBetween(dateTime1, dateTime2).getWeeks();
Mise à jour de la réponse au compte pour Java 8
// TechTrip - ASSUMPTION d1 is earlier than d2
// leave that for exercise
public static long getFullWeeks(Calendar d1, Calendar d2){
Instant d1i = Instant.ofEpochMilli(d1.getTimeInMillis());
Instant d2i = Instant.ofEpochMilli(d2.getTimeInMillis());
LocalDateTime startDate = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault());
LocalDateTime endDate = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault());
return ChronoUnit.WEEKS.between(startDate, endDate);
}
Utilisation de l'arithmétique de date dans Java.util.Calendar
:
public static int getWeeksBetween (Date a, Date b) {
if (b.before(a)) {
return -getWeeksBetween(b, a);
}
a = resetTime(a);
b = resetTime(b);
Calendar cal = new GregorianCalendar();
cal.setTime(a);
int weeks = 0;
while (cal.getTime().before(b)) {
// add another week
cal.add(Calendar.WEEK_OF_YEAR, 1);
weeks++;
}
return weeks;
}
public static Date resetTime (Date d) {
Calendar cal = new GregorianCalendar();
cal.setTime(d);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
Calendar a = new GregorianCalendar(2002,1,22);
Calendar b = new GregorianCalendar(2002,1,28);
System.out.println(a.get(Calendar.WEEK_OF_YEAR));
System.out.println(b.get(Calendar.WEEK_OF_YEAR));
int weeks = b.get(Calendar.WEEK_OF_YEAR)-a.get(Calendar.WEEK_OF_YEAR);
System.out.println(weeks);
essayez ça doit marcher
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(2007, 01, 10);
calendar2.set(2007, 07, 01);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
int diffWeeks = (int)diff / (7*24 * 60 * 60 * 1000);
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces nouvelles classes supplantent les anciennes classes date-heure fournies avec les premières versions de Java. Ces classes supplantent également le très performant framework Joda-Time , et sont construites par les mêmes personnes, notamment sous la direction de Stephen Colbourne .
Le projet ThreeTen-Extra est l'extension officielle du framework Java.time intégré à Java 8 et versions ultérieures. Ce projet est le terrain d’essai pour d’éventuels ajouts à Java.time, et se veut utile en soi.
Weeks
classeCe projet inclut une classe Weeks
représentant un nombre de semaines. Non seulement il peut calculer, mais il est également destiné à être utilisé dans votre code comme un objet sûr pour le type. Une telle utilisation contribue également à rendre votre code auto-documenté.
Vous pouvez instancier en fournissant une paire de points dans le temps avec la méthode Weeks.between
. Ces moments-là peuvent être tout ce qui implémente (Java.time.temporal.Temporal }, y compris Instant
, LocalDate
, OffsetDateTime
, ZonedDateTime
_, Year
, YearMonth
, et plus.
Vos objets Java.util.Date
peuvent être facilement convertis en objets Instant
, moments sur la ligne de temps au format UTC avec une résolution en nanosecondes. Regardez les nouvelles méthodes ajoutées aux anciennes classes date-heure. Pour passer de Date à Instant, appelez _ { Java.util.Date::toInstant
_.
Instant start = utilDateStart.toInstant();
Instant stop = utilDateStop.toInstant();
Weeks weeks = Weeks.between( start , stop );
Vous pouvez demander le nombre de semaines. Vous pouvez aussi faire beaucoup plus.
int weeksNumber = weeks.getAmount(); // The number of weeks in this Weeks object.
Le cadre Java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes gênantes héritées _ date-heure telles que Java.util.Date
, Calendar
_, & SimpleDateFormat
.
Le projet Joda-Time , désormais en mode { mode maintenance }, conseille la migration vers les classes Java.time .
Pour en savoir plus, consultez le Oracle Tutorial . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou une version ultérieure. Pas besoin de chaînes, pas besoin de Java.sql.*
classes.
Où obtenir les classes Java.time?
Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez y trouver des classes utiles telles que Interval
_, YearWeek
, YearQuarter
_ et plus _.
Si vous souhaitez utiliser le nombre exact de semaines complètes, utilisez la méthode ci-dessous, où la date de fin est exclusive:
public static long weeksBetween(Date date1, Date date2) {
return WEEKS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
}
Si vous voulez une version de ceil, utilisez ci-dessous:
public static long weeksBetween(Date date1, Date date2) {
long daysBetween = DAYS.between(date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(),
date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) + 1;
return daysBetween / 7 + (daysBetween % 7 == 0 ? 0 : 1);
}
Joda Time calcule des semaines avec des durées de deux dates qui peuvent ne pas répondre à nos besoins dans certains cas. J'ai une méthode avec Joda Time pour calculer les semaines naturelles entre deux dates. J'espère que ça peut t'aider. Si vous n'utilisez pas Joda Time, vous pouvez modifier le code avec Calendar pour faire la même chose.
//Unlike Joda Time Weeks.weeksBetween() that returns whole weeks computed
//from duration, we return natural weeks between two dates based on week of year
public static int weeksBetween(ReadablePartial date1, ReadablePartial date2) {
int comp = date1.compareTo(date2);
if (comp == 0) {
return 0;
}
if (comp > 0) {
ReadablePartial mid = date2;
date2 = date1;
date1 = mid;
}
int year1 = date1.get(DateTimeFieldType.weekyear());
int year2 = date2.get(DateTimeFieldType.weekyear());
if (year1 == year2) {
return date2.get(DateTimeFieldType.weekOfWeekyear()) - date1.get(DateTimeFieldType.weekOfWeekyear());
}
int weeks1 = 0;
LocalDate lastDay1 = new LocalDate(date1.get(DateTimeFieldType.year()), 12, 31);
if (lastDay1.getWeekyear() > year1) {
lastDay1 = lastDay1.minusDays(7);
weeks1++;
}
weeks1 += lastDay1.getWeekOfWeekyear() - date1.get(DateTimeFieldType.weekOfWeekyear());
int midWeeks = 0;
for (int i = year1 + 1; i < year2; i++) {
LocalDate y1 = new LocalDate(i, 1, 1);
int yearY1 = y1.getWeekyear();
if (yearY1 < i) {
y1 = y1.plusDays(7);
midWeeks++;
}
LocalDate y2 = new LocalDate(i, 12, 31);
int yearY2 = y2.getWeekyear();
if (yearY2 > i) {
y2 = y2.minusDays(7);
midWeeks++;
}
midWeeks += y2.getWeekOfWeekyear() - y1.getWeekOfWeekyear();
}
int weeks2 = 0;
LocalDate firstDay2 = new LocalDate(date2.get(DateTimeFieldType.year()), 1, 1);
if (firstDay2.getWeekyear() < firstDay2.getYear()) {
firstDay2 = firstDay2.plusDays(7);
weeks2++;
}
weeks2 += date2.get(DateTimeFieldType.weekOfWeekyear()) - firstDay2.getWeekOfWeekyear();
return weeks1 + midWeeks + weeks2;
}
Vous pouvez le faire de la manière suivante:
// method header not shown
// example dates:
f = new GregorianCalendar(2009,Calendar.AUGUST,1);
l = new GregorianCalendar(2010,Calendar.SEPTEMBER,1);
DateTime start = new DateTime(f);
DateTime end = new DateTime(l);
// Alternative to above - example dates with joda:
// DateTime start = new DateTime(2009,8,1,0,0,0,0);
// DateTime end = new DateTime(2010,9,1,0,0,0,0);
Interval interval = new Interval(start,end);
int weeksBetween = interval.toPeriod(PeriodType.weeks()).getWeeks();
// return weeksBetween;
Cela devrait vous donner un int représentant le nombre de semaines entre les deux dates.
Jetez un oeil à l'article suivant: Java - calcule la différence entre deux dates
La méthode daysBetween vous permettra d'obtenir le nombre de jours entre les dates. Ensuite, vous pouvez simplement diviser par 7 pour obtenir le nombre de semaines complètes.
int startWeek = c1.get(Calendar.WEEK_OF_YEAR);
int endWeek = c2.get(Calendar.WEEK_OF_YEAR);
int diff = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
int deltaYears = 0;
for(int i = 0;i < diff;i++){
deltaYears += c1.getWeeksInWeekYear();
c1.add(Calendar.YEAR, 1);
}
diff = (endWeek + deltaYears) - startWeek;
Inclut les différences d’année . Cela a fonctionné pour moi :)
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.clear();
date1.set(datePicker1.getYear(), datePicker1.getMonth(),
datePicker1.getDayOfMonth());
date2.clear();
date2.set(datePicker2.getYear(), datePicker2.getMonth(),
datePicker2.getDayOfMonth());
long diff = date2.getTimeInMillis() - date1.getTimeInMillis();
float dayCount = (float) diff / (24 * 60 * 60 * 1000);
int week = (dayCount / 7) ;
J'espère que cela pourrait vous aider
private int weeksBetween(Calendar startDate, Calendar endDate) {
startDate.set(Calendar.HOUR_OF_DAY, 0);
startDate.set(Calendar.MINUTE, 0);
startDate.set(Calendar.SECOND, 0);
int start = (int)TimeUnit.MILLISECONDS.toDays(
startDate.getTimeInMillis())
- startDate.get(Calendar.DAY_OF_WEEK);
int end = (int)TimeUnit.MILLISECONDS.toDays(
endDate.getTimeInMillis());
return (end - start) / 7;
}
si cette méthode retourne 0 ils sont dans la même semaine
si cette méthode retourne 1 endDate est la semaine après startDate
si cette méthode retourne -1 endDate est la semaine précédant startDate
vous avez eu l'idée