首先,你不清楚你如何設置最初的星期五(當這一切開始時)。所以,我正在考慮2017-06-16 15:00
作爲第一個星期五(我的算法開始的地方;發生變化的最後一天)。
的算法基本上是:
- 獲得最後的更改日期(星期五有些15:00),如果今天的日期是之前計算何時會發生下一變化(2周後)
- 檢查接下來的變化提前(如果它是等於或之後,重新計算更改日期)
- 得到下週一4周最後改變
import java.time.temporal.TemporalAdjusters;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
// starting at 2017-06-16 15:00:00 (the last date when a change occured)
LocalDateTime lastChange = LocalDateTime.of(2017, 6, 16, 15, 0);
// nextChange: 2 weeks after the last change
LocalDateTime nextChange = lastChange.plusWeeks(2);
// get the current date
LocalDateTime today = LocalDateTime.now();
// check if today is after or equals the nextChange
if (!today.isBefore(nextChange)) {
// today is equal or after the next change, adjust the last and next change dates
lastChange = nextChange;
nextChange = lastChange.plusWeeks(2);
}
LocalDate futureDate = futureDate(lastChange);
System.out.println(futureDate);
// auxiliary method: get the future date based on the last change date
// using LocalDate because time (hour/minute/second) doesn't seem to matter in output
// (but if it does, use a LocalDateTime instead - don't call toLocalDate() in the last line)
public LocalDate futureDate(LocalDateTime lastChange) {
// double checking (last change date is a Friday at 15:00) - not sure if it's really needed
if (lastChange.getDayOfWeek() != DayOfWeek.FRIDAY || (!lastChange.toLocalTime().equals(LocalTime.of(15, 0)))) {
return null; // if the change it's not Friday or it's not 15:00, it should return null? (not sure)
}
// get the next Monday and add 4 weeks
return lastChange.with(TemporalAdjusters.next(DayOfWeek.MONDAY))
.plusWeeks(4).toLocalDate();
}
輸出(考慮到今天2017-06-19
)將是:
2017年7月17日
我也有2017-06-30
測試時間爲14:00(返回2017-07-17
)和15:00(返回2017-07-31
)。用你的例子進行測試也給了我相同的結果。
注:
- 在你的輸出例子,你剛剛印刷年/月/日,所以我用
LocalDate
類。如果還需要時間字段(小時/分鐘/秒),請改爲改爲返回LocalDateTime
的方法,並在return
語句中刪除對toLocalDate()
的呼叫。
- 因爲我不清楚這是第一個星期五(當這一切開始?),我假設它是
2017-06-16
。
- 在您的示例輸出中,
2017-06-15
的結果不應該是2017-07-03
?因爲2017-07-04
是星期二。
如果要相同的輸出,可以使像下方的循環(使用相同的futureDate()
方法,並假定爲2017-06-15
結果是2017-07-03
如上所述)。
請注意,我使用java.time.temporal.TemporalAdjuster
來獲取下一個日期 - 因爲當它是星期五時,我必須檢查它是否爲更改日期並在14:00,15:00和16:00得到結果,然後去到第二天(所以有時我需要將時間設置爲14:00,或者增加1小時,或者增加1天 - 並且我爲每種情況選擇相應的調節器)。
我還使用了java.time.format.DateTimeFormatter
改變輸出格式(當它是星期五的變化,它有幾個小時的自定義格式):
// starting 2 weeks before 2017-06-16 15:00:00 (the last date when a change occured)
LocalDateTime lastChange = LocalDateTime.of(2017, 6, 16, 15, 0).minusWeeks(2);
// nextChange: 2 weeks after the last change
LocalDateTime nextChange = lastChange.plusWeeks(2);
// starting at 2017-06-15
LocalDateTime today = LocalDateTime.of(2017, 6, 15, 0, 0);
LocalTime twoPM = LocalTime.of(14, 0);
LocalTime threePM = LocalTime.of(15, 0);
LocalTime fourPM = LocalTime.of(16, 0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
TemporalAdjuster adjuster; // adjuster for the next date
// adjuster for next hour
TemporalAdjuster nextHour = t -> t.plus(1, ChronoUnit.HOURS);
// adjuster for next day
TemporalAdjuster nextDay = t -> t.plus(1, ChronoUnit.DAYS);
System.out.println("| on | date is |");
System.out.println("|------------------------------------------------|------------|");
for (int i = 0; i < 40; i++) {
String sep = "";
StringBuilder sb = new StringBuilder("| ");
if (today.getDayOfWeek() == DayOfWeek.FRIDAY) {
if (ChronoUnit.DAYS.between(lastChange.toLocalDate(), today.toLocalDate()) == 7) {
sep = " (friday again, dates do not change)";
adjuster = nextDay;
sb.append(today.toLocalDate());
} else {
LocalTime time = today.toLocalTime();
if (time.equals(twoPM)) {
sep = " (friday before 15:00) ";
adjuster = nextHour;
sb.append(formatter.format(today));
} else if (time.equals(threePM)) {
sep = " (friday after 15:00) ";
adjuster = nextHour;
sb.append(formatter.format(today));
} else if (time.equals(fourPM)) {
sep = " ";
adjuster = nextDay;
sb.append(formatter.format(today));
} else {
sep = " (friday before 15:00) ";
adjuster = nextHour;
today = today.with(twoPM);
sb.append(formatter.format(today));
}
}
} else {
// get the next day at start of day
sep = " ";
adjuster = t -> LocalDate.from(t).plusDays(1).atStartOfDay();
sb.append(today.toLocalDate());
}
// check if today is after or equals the nextChange
if (!today.isBefore(nextChange)) {
// today is equal or after the next change, adjust the last and next change dates
lastChange = nextChange;
nextChange = lastChange.plusWeeks(2);
}
LocalDate futureDate = futureDate(lastChange);
sb.append(sep).append(" | ").append(futureDate).append(" |");
System.out.println(sb.toString());
// get the next date
today = today.with(adjuster);
}
輸出是:
| on | date is |
|------------------------------------------------|------------|
| 2017-06-15 | 2017-07-03 |
| 2017-06-16 14:00:00 (friday before 15:00) | 2017-07-03 |
| 2017-06-16 15:00:00 (friday after 15:00) | 2017-07-17 |
| 2017-06-16 16:00:00 | 2017-07-17 |
| 2017-06-17 | 2017-07-17 |
| 2017-06-18 | 2017-07-17 |
| 2017-06-19 | 2017-07-17 |
| 2017-06-20 | 2017-07-17 |
| 2017-06-21 | 2017-07-17 |
| 2017-06-22 | 2017-07-17 |
| 2017-06-23 (friday again, dates do not change) | 2017-07-17 |
| 2017-06-24 | 2017-07-17 |
| 2017-06-25 | 2017-07-17 |
| 2017-06-26 | 2017-07-17 |
| 2017-06-27 | 2017-07-17 |
| 2017-06-28 | 2017-07-17 |
| 2017-06-29 | 2017-07-17 |
| 2017-06-30 14:00:00 (friday before 15:00) | 2017-07-17 |
| 2017-06-30 15:00:00 (friday after 15:00) | 2017-07-31 |
| 2017-06-30 16:00:00 | 2017-07-31 |
| 2017-07-01 | 2017-07-31 |
| 2017-07-02 | 2017-07-31 |
| 2017-07-03 | 2017-07-31 |
| 2017-07-04 | 2017-07-31 |
| 2017-07-05 | 2017-07-31 |
| 2017-07-06 | 2017-07-31 |
| 2017-07-07 (friday again, dates do not change) | 2017-07-31 |
| 2017-07-08 | 2017-07-31 |
| 2017-07-09 | 2017-07-31 |
| 2017-07-10 | 2017-07-31 |
| 2017-07-11 | 2017-07-31 |
| 2017-07-12 | 2017-07-31 |
| 2017-07-13 | 2017-07-31 |
| 2017-07-14 14:00:00 (friday before 15:00) | 2017-07-31 |
| 2017-07-14 15:00:00 (friday after 15:00) | 2017-08-14 |
| 2017-07-14 16:00:00 | 2017-08-14 |
| 2017-07-15 | 2017-08-14 |
| 2017-07-16 | 2017-08-14 |
| 2017-07-17 | 2017-08-14 |
| 2017-07-18 | 2017-08-14 |
另一種方法是創建一個地圖來存儲相對於發生更改的日期的所有未來日期(因此您不需要一直計算):
// maps a change date with the respective future date
Map<LocalDateTime, LocalDate> futureDates = new HashMap<>();
// starting at 2017-06-16
LocalDateTime change = LocalDateTime.of(2017, 6, 16, 15, 0);
// storing just 30 dates, but you can change this accordingly, with as many dates as you need
for (int i = 0; i < 30; i++) {
futureDates.put(change, futureDate(change));
change = change.plusWeeks(2);
}
支票將改變一點點,因爲你需要確切地知道什麼是與您正在檢查的日期的關鍵是:
LocalDateTime today = LocalDateTime.now();
// find the future date
for (LocalDateTime dt : futureDates.keySet()) {
long days = ChronoUnit.DAYS.between(dt, today);
if (days >= 0 && days <= 13) {
System.out.println(today + " " + futureDates.get(dt));
break;
}
}
這樣的工作方式與上面的第一個版本相同。
你可以使用https://momentjs.com/? – user3080953
「用任何語言」 - 你打算如何整合? –
「2017-06-15」的結果不應該是「2017-07-03」?因爲'2017-07-04'是星期二 – 2017-06-19 17:37:03