# **[JAVA] 假日查詢API Calendar型別運用**
###### tags: `Java` `Restful API` `工作筆記`
## [實作目的] 專案需求,需要開一個假日查詢的API,給各個部屬於不同AP的服務call ##
## [前情提要] 後台有假日管理功能,可以手動加入補班日/颱風假/彈性放假

#### DTO ####
```java=
package gov.pcc.pwc.service.dto;
public class HolidayApiDTO {
private String calendarDay;
private String workingDay;
private String dateStart;
private String dateEnd;
private String date;
private Integer days;
private Boolean isWorkingDay;
public String getCalendarDay() {
return calendarDay;
}
public void setCalendarDay(String calendarDay) {
this.calendarDay = calendarDay;
}
public String getWorkingDay() {
return workingDay;
}
public void setWorkingDay(Boolean workingDay) {
isWorkingDay = workingDay;
}
public void setWorkingDay(String workingDay) {
this.workingDay = workingDay;
}
public String getDateStart() {
return dateStart;
}
public void setDateStart(String dateStart) {
this.dateStart = dateStart;
}
public String getDateEnd() {
return dateEnd;
}
public void setDateEnd(String dateEnd) {
this.dateEnd = dateEnd;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public Integer getDays() {
return days;
}
public void setDays(Integer days) {
this.days = days;
}
public Boolean getIsWorkingDay() {
return isWorkingDay;
}
public void setIsWorkingDay(Boolean isWorkingDay) {
this.isWorkingDay = isWorkingDay;
}
}
```
#### controller類別 ####
```java=
package gov.pcc.pwc.pwb.rest;
/**
* REST controller for managing {@link HolidayApiDTO}.
*/
@RestController
@RequestMapping("/api")
public class HolidayApiResource {
private final Logger log = LoggerFactory.getLogger(HolidayApiResource.class);
private static final String ENTITY_NAME = "HolidayApiDAO";
@Value("${jhipster.clientApp.name}")
private String applicationName;
private final AdmHolidayService admHolidayService;
private final AdmHolidayRepository admHolidayRepository;
private final HolidayApiService holidayApiService;
public HolidayApiResource(AdmHolidayService admHolidayService, AdmHolidayRepository admHolidayRepository, HolidayApiService holidayApiService) {
this.admHolidayService = admHolidayService;
this.admHolidayRepository = admHolidayRepository;
this.holidayApiService = holidayApiService;
}
@PostMapping("/holiday-api/is-holiday")
public boolean isHoliday(@Valid @RequestBody HolidayApiDTO holidayApiDTO) throws ParseException {
log.debug("REST request to get isHoliday : date:{}", holidayApiDTO.getDate());
return holidayApiService.isHoliday(holidayApiDTO.getDate());
}
@PostMapping("/holiday-api/getDate")
public String getCalendarDayOrWorkingDay(@Valid @RequestBody HolidayApiDTO holidayApiDTO) throws ParseException {
log.debug("REST request to get calendarDay Or workingDay : date:{}, days:{} ,isWorkingDay:{}", holidayApiDTO.getDate(), holidayApiDTO.getDays(), holidayApiDTO.getIsWorkingDay());
return holidayApiService.getCalendarDayOrWorkingDay(holidayApiDTO.getDate(), holidayApiDTO.getDays(), holidayApiDTO.getIsWorkingDay());
}
@PostMapping("/holiday-api/getDays")
public HolidayApiDTO getCalendarDayAndWorkingDay(@Valid @RequestBody HolidayApiDTO holidayApiDTO) throws ParseException {
log.debug("REST request to get calendarDay And workingDay : dateStart:{}, dateEnd:{}", holidayApiDTO.getDateStart(), holidayApiDTO.getDateEnd());
return holidayApiService.getCalendarDayAndWorkingDay(holidayApiDTO.getDateStart(), holidayApiDTO.getDateEnd());
}
}
```
#### service類別 ####
```java=
package gov.pcc.pwc.service;
@Service
public class HolidayApiService {
private final Logger log = LoggerFactory.getLogger(HolidayApiService.class);
private final AdmHolidayRepository admHolidayRepository;
public HolidayApiService(AdmHolidayRepository admHolidayRepository) {
this.admHolidayRepository = admHolidayRepository;
}
/**
* 判斷是否為假日:
* 輸入111/02/28,於ADM_HOLIDAY找到二二八,回傳true
* 輸入111/03/05,為星期六,回傳true
* 輸入111/01/22,為星期六,但在ADM_HOLIDAY找到圍捕般日,回傳false
* @param date
* @return boolean
* @throws ParseException
*/
public Boolean isHoliday(String date) throws ParseException {
String addDate = transferMinguoDateToADDate(date);
Calendar calendarDate = transferADDateStringToCalendar(addDate);
LocalDate localDate = LocalDate.ofInstant(calendarDate.toInstant(), ZoneId.systemDefault());
//查詢AMD_HOLIDAY判斷是否是節日、補班日
if (!admHolidayRepository.existsByHolidayDate(localDate)) {
//如果不是,繼續判斷是否為星期六、星期日
switch (calendarDate.get(Calendar.DAY_OF_WEEK)) {
case Calendar.SATURDAY:
case Calendar.SUNDAY:
return true;
default:
return false;
}
} else {
return true;
}
}
/**
* 回傳以當日日期開始的工作日or日曆日
* 輸入111/03/01、5、false,回傳111/03/05
* 輸入111/03/01、5、true,回傳111/03/07
* @param date
* @param days
* @param isWorkingDay
* @return
* @throws ParseException
*/
public String getCalendarDayOrWorkingDay(String date, Integer days, Boolean isWorkingDay) throws ParseException {
String adDate = transferMinguoDateToADDate(date);
Calendar calendarDate = transferADDateStringToCalendar(adDate);
if (isWorkingDay) {
try {
if (isHoliday(transferADDateToMinguoDate(transferCalendarToADDateString(calendarDate)))) {
days++;
}
for (int i = 0; i < days-1 ; i++) {
calendarDate.add(Calendar.DAY_OF_MONTH, 1);
if(isHoliday(transferADDateToMinguoDate(transferCalendarToADDateString(calendarDate)))){
i--;
}
}
return transferADDateToMinguoDate(transferCalendarToADDateString(calendarDate));
} catch (Exception e) {
log.error(e.getMessage());
}
} else {
calendarDate.add(Calendar.DAY_OF_MONTH, days-1);
String adDateString = transferCalendarToADDateString(calendarDate);
String minguoDateString = transferADDateToMinguoDate(adDateString);
return minguoDateString;
}
return null;
}
public HolidayApiDTO getCalendarDayAndWorkingDay(String dateStart, String dateEnd) throws ParseException {
String adDateStart = transferMinguoDateToADDate(dateStart);
Calendar calendarDateStart = transferADDateStringToCalendar(adDateStart);
long timeStart = calendarDateStart.getTimeInMillis();
String adDateEnd = transferMinguoDateToADDate(dateEnd);
Calendar calendarDateEnd = transferADDateStringToCalendar(adDateEnd);
long timeEnd = calendarDateEnd.getTimeInMillis();
int betweenDays = Integer.parseInt(String.valueOf((timeEnd - timeStart) / (1000 * 60 * 60 * 24)));
//日曆日
String calendarDays = String.valueOf(betweenDays + 1);
//工作日
int workingDaysCount = 0;
if (!isHoliday(transferADDateToMinguoDate(transferCalendarToADDateString(calendarDateStart)))) {
workingDaysCount++;
}
for (int i = 0; i < betweenDays; i++) {
calendarDateStart.add(Calendar.DAY_OF_MONTH, 1);
workingDaysCount++;
if (isHoliday(transferADDateToMinguoDate(transferCalendarToADDateString(calendarDateStart)))) {
workingDaysCount--;
}
}
String workingDays = String.valueOf(workingDaysCount);
HolidayApiDTO holidayApiDTO = new HolidayApiDTO();
holidayApiDTO.setCalendarDay(calendarDays);
holidayApiDTO.setWorkingDay(workingDays);
return holidayApiDTO;
}
```
#### 日期Util ####
```java=
/**
* Transfer AD date to minguo date.
* 西元年 yyyyMMdd 轉 民國年 yyy/MM/dd
*
* @param dateString the String dateString
* @return the string
*/
public static String transferADDateToMinguoDate(String dateString) {
LocalDate localDate = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyyMMdd"));
return MinguoDate.from(localDate).format(DateTimeFormatter.ofPattern("yyy/MM/dd"));
}
/**
* Transfer minguo date to AD date.
* 民國年 yyy/MM/dd 轉 西元年 yyyyMMdd
*
* @param dateString the String dateString
* @return the string
*/
public static String transferMinguoDateToADDate(String dateString) {
Chronology chrono = MinguoChronology.INSTANCE;
DateTimeFormatter df = new DateTimeFormatterBuilder().parseLenient()
.appendPattern("yyy/MM/dd")
.toFormatter()
.withChronology(chrono)
.withDecimalStyle(DecimalStyle.of(Locale.getDefault()));
ChronoLocalDate chDate = chrono.date(df.parse(dateString));
return LocalDate.from(chDate).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
}
public static Calendar transferADDateStringToCalendar(String dateString) throws ParseException {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.TAIWAN);
cal.setTime(sdf.parse(dateString));
return cal;
}
public static String transferCalendarToADDateString(Calendar calendar) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.TAIWAN);
return sdf.format(calendar.getTime());
}
}
```