컬렉션 및 날짜 관련 유틸리티 클래스 추가
src/main/java/egovframework/util/CollectionUtil.java: - 컬렉션 관련 유틸리티 메소드 추가 - Null 체크(isEmpty, isNotEmpty) 및 크기 반환(size) 메소드 - 변환 메소드(toList, toSet) - 필터링, 매핑, 정렬과 같은 스트림 처리 메소드(filter, map, sort 등) - 합집합, 교집합, 차집합 및 그룹화 기능(union, intersection, difference, groupBy 등) src/main/java/egovframework/util/DateUtil.java: - 날짜 및 시간 관련 유틸리티 메소드 추가 - 현재 날짜/시간 반환 메소드(getCurrentYearMonth, getCurrentDateTime 등) - 형식 변환 및 파싱 메소드(parseLocalDate, formatLocalDate 등) - 날짜 추가/계산(addDays, daysBetween 등) 및 범위 처리(periodBetween 등) - 요일, 월의 첫날 및 마지막 날 계산(getDayOfWeekName, getFirstDayOfMonth 등) - 공통적으로 null 안전성 및 유효성 검사에 초점.multiDB
parent
8aac5e0bfa
commit
a731ab19e8
@ -0,0 +1,31 @@
|
||||
#-------------------------------------------------------------------------------#
|
||||
# Qodana analysis is configured by qodana.yaml file #
|
||||
# https://www.jetbrains.com/help/qodana/qodana-yaml.html #
|
||||
#-------------------------------------------------------------------------------#
|
||||
version: "1.0"
|
||||
|
||||
#Specify inspection profile for code analysis
|
||||
profile:
|
||||
name: qodana.starter
|
||||
|
||||
#Enable inspections
|
||||
#include:
|
||||
# - name: <SomeEnabledInspectionId>
|
||||
|
||||
#Disable inspections
|
||||
#exclude:
|
||||
# - name: <SomeDisabledInspectionId>
|
||||
# paths:
|
||||
# - <path/where/not/run/inspection>
|
||||
|
||||
projectJDK: "8" #(Applied in CI/CD pipeline)
|
||||
|
||||
#Execute shell command before Qodana execution (Applied in CI/CD pipeline)
|
||||
#bootstrap: sh ./prepare-qodana.sh
|
||||
|
||||
#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline)
|
||||
#plugins:
|
||||
# - id: <plugin.id> #(plugin id can be found at https://plugins.jetbrains.com)
|
||||
|
||||
#Specify Qodana linter for analysis (Applied in CI/CD pipeline)
|
||||
linter: jetbrains/qodana-jvm:2025.1
|
||||
@ -0,0 +1,47 @@
|
||||
package egovframework.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* packageName : egovframework.config
|
||||
* fileName : FileUploadProperties
|
||||
* author : 시스템 관리자
|
||||
* date : 25. 5. 23.
|
||||
* description : 파일 업로드 관련 설정 속성
|
||||
* ===========================================================
|
||||
* DATE AUTHOR NOTE
|
||||
* -----------------------------------------------------------
|
||||
* 25. 5. 23. 시스템 관리자 최초 생성
|
||||
*/
|
||||
@Setter
|
||||
@Getter
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "file.upload")
|
||||
public class FileUploadProperties {
|
||||
|
||||
/** 파일 저장 기본 경로 */
|
||||
private String path;
|
||||
|
||||
/** 최대 파일 크기 (단일 파일) - 기본값 10MB */
|
||||
private long maxSize;
|
||||
|
||||
/** 최대 총 파일 크기 - 기본값 50MB */
|
||||
private long maxTotalSize;
|
||||
|
||||
/** 허용된 파일 확장자 */
|
||||
private String allowedExtensions;
|
||||
|
||||
/** 최대 파일 개수 - 기본값 10개 */
|
||||
private int maxFiles;
|
||||
|
||||
/** 실제 파일 삭제 여부 - 기본값 true */
|
||||
private boolean realFileDelete;
|
||||
|
||||
/** 하위 디렉토리 설정 */
|
||||
private Map<String, String> subDirs;
|
||||
}
|
||||
@ -0,0 +1,440 @@
|
||||
package egovframework.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 컬렉션 관련 공통 유틸리티 클래스
|
||||
*/
|
||||
@Component
|
||||
public class CollectionUtil {
|
||||
|
||||
/**
|
||||
* 컬렉션이 null이거나 비어있는지 확인
|
||||
* @param collection 검사할 컬렉션
|
||||
* @return null이거나 비어있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isEmpty(Collection<?> collection) {
|
||||
return collection == null || collection.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션이 null이 아니고 비어있지 않은지 확인
|
||||
* @param collection 검사할 컬렉션
|
||||
* @return null이 아니고 비어있지 않으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNotEmpty(Collection<?> collection) {
|
||||
return !isEmpty(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 맵이 null이거나 비어있는지 확인
|
||||
* @param map 검사할 맵
|
||||
* @return null이거나 비어있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isEmpty(Map<?, ?> map) {
|
||||
return map == null || map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 맵이 null이 아니고 비어있지 않은지 확인
|
||||
* @param map 검사할 맵
|
||||
* @return null이 아니고 비어있지 않으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNotEmpty(Map<?, ?> map) {
|
||||
return !isEmpty(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열이 null이거나 비어있는지 확인
|
||||
* @param array 검사할 배열
|
||||
* @return null이거나 비어있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static <T> boolean isEmpty(T[] array) {
|
||||
return array == null || array.length == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열이 null이 아니고 비어있지 않은지 확인
|
||||
* @param array 검사할 배열
|
||||
* @return null이 아니고 비어있지 않으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static <T> boolean isNotEmpty(T[] array) {
|
||||
return !isEmpty(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션의 크기 반환 (null 안전)
|
||||
* @param collection 검사할 컬렉션
|
||||
* @return 컬렉션의 크기, null이면 0 반환
|
||||
*/
|
||||
public static int size(Collection<?> collection) {
|
||||
return collection == null ? 0 : collection.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 맵의 크기 반환 (null 안전)
|
||||
* @param map 검사할 맵
|
||||
* @return 맵의 크기, null이면 0 반환
|
||||
*/
|
||||
public static int size(Map<?, ?> map) {
|
||||
return map == null ? 0 : map.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열의 크기 반환 (null 안전)
|
||||
* @param array 검사할 배열
|
||||
* @return 배열의 크기, null이면 0 반환
|
||||
*/
|
||||
public static <T> int size(T[] array) {
|
||||
return array == null ? 0 : array.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션이 null이면 빈 컬렉션 반환, 그렇지 않으면 원래 컬렉션 반환
|
||||
* @param collection 처리할 컬렉션
|
||||
* @return null이면 빈 컬렉션, 그렇지 않으면 원래 컬렉션
|
||||
*/
|
||||
public static <T> Collection<T> emptyIfNull(Collection<T> collection) {
|
||||
return collection == null ? Collections.emptyList() : collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 리스트가 null이면 빈 리스트 반환, 그렇지 않으면 원래 리스트 반환
|
||||
* @param list 처리할 리스트
|
||||
* @return null이면 빈 리스트, 그렇지 않으면 원래 리스트
|
||||
*/
|
||||
public static <T> List<T> emptyIfNull(List<T> list) {
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 맵이 null이면 빈 맵 반환, 그렇지 않으면 원래 맵 반환
|
||||
* @param map 처리할 맵
|
||||
* @return null이면 빈 맵, 그렇지 않으면 원래 맵
|
||||
*/
|
||||
public static <K, V> Map<K, V> emptyIfNull(Map<K, V> map) {
|
||||
return map == null ? Collections.emptyMap() : map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열을 리스트로 변환 (null 안전)
|
||||
* @param array 변환할 배열
|
||||
* @return 변환된 리스트, null이면 빈 리스트 반환
|
||||
*/
|
||||
public static <T> List<T> toList(T[] array) {
|
||||
if (array == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 리스트로 변환 (null 안전)
|
||||
* @param collection 변환할 컬렉션
|
||||
* @return 변환된 리스트, null이면 빈 리스트 반환
|
||||
*/
|
||||
public static <T> List<T> toList(Collection<T> collection) {
|
||||
if (collection == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return new ArrayList<>(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 Set으로 변환 (null 안전)
|
||||
* @param collection 변환할 컬렉션
|
||||
* @return 변환된 Set, null이면 빈 Set 반환
|
||||
*/
|
||||
public static <T> Set<T> toSet(Collection<T> collection) {
|
||||
if (collection == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return new HashSet<>(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 배열을 Set으로 변환 (null 안전)
|
||||
* @param array 변환할 배열
|
||||
* @return 변환된 Set, null이면 빈 Set 반환
|
||||
*/
|
||||
public static <T> Set<T> toSet(T[] array) {
|
||||
if (array == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<T> set = new HashSet<>();
|
||||
Collections.addAll(set, array);
|
||||
return set;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션에서 조건에 맞는 요소만 필터링
|
||||
* @param collection 필터링할 컬렉션
|
||||
* @param predicate 필터링 조건
|
||||
* @return 필터링된 리스트
|
||||
*/
|
||||
public static <T> List<T> filter(Collection<T> collection, Predicate<T> predicate) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return collection.stream()
|
||||
.filter(predicate)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션의 요소를 변환
|
||||
* @param collection 변환할 컬렉션
|
||||
* @param mapper 변환 함수
|
||||
* @return 변환된 리스트
|
||||
*/
|
||||
public static <T, R> List<R> map(Collection<T> collection, Function<T, R> mapper) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return collection.stream()
|
||||
.map(mapper)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 정렬
|
||||
* @param collection 정렬할 컬렉션
|
||||
* @param comparator 정렬 기준
|
||||
* @return 정렬된 리스트
|
||||
*/
|
||||
public static <T> List<T> sort(Collection<T> collection, Comparator<? super T> comparator) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<T> list = new ArrayList<>(collection);
|
||||
list.sort(comparator);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 자연 순서로 정렬 (Comparable 구현 필요)
|
||||
* @param collection 정렬할 컬렉션
|
||||
* @return 정렬된 리스트
|
||||
*/
|
||||
public static <T extends Comparable<? super T>> List<T> sort(Collection<T> collection) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<T> list = new ArrayList<>(collection);
|
||||
Collections.sort(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션에서 중복 제거
|
||||
* @param collection 중복 제거할 컬렉션
|
||||
* @return 중복이 제거된 리스트
|
||||
*/
|
||||
public static <T> List<T> distinct(Collection<T> collection) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return collection.stream()
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 특정 키를 기준으로 그룹화
|
||||
* @param collection 그룹화할 컬렉션
|
||||
* @param keyMapper 그룹화 키 추출 함수
|
||||
* @return 그룹화된 맵
|
||||
*/
|
||||
public static <T, K> Map<K, List<T>> groupBy(Collection<T> collection, Function<T, K> keyMapper) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return collection.stream()
|
||||
.collect(Collectors.groupingBy(keyMapper));
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 특정 키를 기준으로 맵으로 변환
|
||||
* @param collection 변환할 컬렉션
|
||||
* @param keyMapper 키 추출 함수
|
||||
* @return 변환된 맵
|
||||
*/
|
||||
public static <T, K> Map<K, T> toMap(Collection<T> collection, Function<T, K> keyMapper) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return collection.stream()
|
||||
.collect(Collectors.toMap(keyMapper, Function.identity(), (a, b) -> a));
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 특정 키와 값을 기준으로 맵으로 변환
|
||||
* @param collection 변환할 컬렉션
|
||||
* @param keyMapper 키 추출 함수
|
||||
* @param valueMapper 값 추출 함수
|
||||
* @return 변환된 맵
|
||||
*/
|
||||
public static <T, K, V> Map<K, V> toMap(Collection<T> collection, Function<T, K> keyMapper, Function<T, V> valueMapper) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return collection.stream()
|
||||
.collect(Collectors.toMap(keyMapper, valueMapper, (a, b) -> a));
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 컬렉션의 합집합 반환
|
||||
* @param collection1 첫 번째 컬렉션
|
||||
* @param collection2 두 번째 컬렉션
|
||||
* @return 합집합 리스트
|
||||
*/
|
||||
public static <T> List<T> union(Collection<T> collection1, Collection<T> collection2) {
|
||||
Set<T> set = new HashSet<>();
|
||||
if (isNotEmpty(collection1)) {
|
||||
set.addAll(collection1);
|
||||
}
|
||||
if (isNotEmpty(collection2)) {
|
||||
set.addAll(collection2);
|
||||
}
|
||||
return new ArrayList<>(set);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 컬렉션의 교집합 반환
|
||||
* @param collection1 첫 번째 컬렉션
|
||||
* @param collection2 두 번째 컬렉션
|
||||
* @return 교집합 리스트
|
||||
*/
|
||||
public static <T> List<T> intersection(Collection<T> collection1, Collection<T> collection2) {
|
||||
if (isEmpty(collection1) || isEmpty(collection2)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<>();
|
||||
Set<T> set = new HashSet<>(collection2);
|
||||
|
||||
for (T item : collection1) {
|
||||
if (set.contains(item)) {
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 컬렉션의 차집합 반환 (collection1 - collection2)
|
||||
* @param collection1 첫 번째 컬렉션
|
||||
* @param collection2 두 번째 컬렉션
|
||||
* @return 차집합 리스트
|
||||
*/
|
||||
public static <T> List<T> difference(Collection<T> collection1, Collection<T> collection2) {
|
||||
if (isEmpty(collection1)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (isEmpty(collection2)) {
|
||||
return new ArrayList<>(collection1);
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<>(collection1);
|
||||
result.removeAll(new HashSet<>(collection2));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션을 지정된 크기의 하위 리스트로 분할
|
||||
* @param collection 분할할 컬렉션
|
||||
* @param size 하위 리스트의 크기
|
||||
* @return 분할된 하위 리스트의 리스트
|
||||
*/
|
||||
public static <T> List<List<T>> partition(Collection<T> collection, int size) {
|
||||
if (isEmpty(collection)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (size <= 0) {
|
||||
throw new IllegalArgumentException("Size must be greater than 0");
|
||||
}
|
||||
|
||||
List<List<T>> result = new ArrayList<>();
|
||||
List<T> list = new ArrayList<>(collection);
|
||||
int total = list.size();
|
||||
|
||||
for (int i = 0; i < total; i += size) {
|
||||
result.add(list.subList(i, Math.min(total, i + size)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 컬렉션에서 첫 번째 요소 반환 (null 안전)
|
||||
* @param collection 처리할 컬렉션
|
||||
* @return 첫 번째 요소, 없으면 null 반환
|
||||
*/
|
||||
public static <T> T getFirst(Collection<T> collection) {
|
||||
if (isEmpty(collection)) {
|
||||
return null;
|
||||
}
|
||||
return collection.iterator().next();
|
||||
}
|
||||
|
||||
/**
|
||||
* 리스트에서 마지막 요소 반환 (null 안전)
|
||||
* @param list 처리할 리스트
|
||||
* @return 마지막 요소, 없으면 null 반환
|
||||
*/
|
||||
public static <T> T getLast(List<T> list) {
|
||||
if (isEmpty(list)) {
|
||||
return null;
|
||||
}
|
||||
return list.get(list.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 맵에서 키에 해당하는 값 반환 (null 안전)
|
||||
* @param map 처리할 맵
|
||||
* @param key 키
|
||||
* @param defaultValue 기본값
|
||||
* @return 키에 해당하는 값, 없으면 기본값 반환
|
||||
*/
|
||||
public static <K, V> V getOrDefault(Map<K, V> map, K key, V defaultValue) {
|
||||
if (isEmpty(map)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return map.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 맵을 병합
|
||||
* @param map1 첫 번째 맵
|
||||
* @param map2 두 번째 맵
|
||||
* @return 병합된 맵
|
||||
*/
|
||||
public static <K, V> Map<K, V> merge(Map<K, V> map1, Map<K, V> map2) {
|
||||
Map<K, V> result = new HashMap<>();
|
||||
|
||||
if (isNotEmpty(map1)) {
|
||||
result.putAll(map1);
|
||||
}
|
||||
|
||||
if (isNotEmpty(map2)) {
|
||||
result.putAll(map2);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,410 @@
|
||||
package egovframework.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.Period;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.TextStyle;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 날짜 관련 공통 유틸리티 클래스
|
||||
*/
|
||||
@Component
|
||||
public class DateUtil {
|
||||
|
||||
/**
|
||||
* 현재 날짜의 년월 정보를 "yyyyMM" 형식으로 반환
|
||||
* @return 년월 문자열 (예: "202405")
|
||||
*/
|
||||
public String getCurrentYearMonth() {
|
||||
LocalDate now = LocalDate.now();
|
||||
return now.format(DateTimeFormatter.ofPattern("yyyyMM"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 날짜를 지정된 형식으로 반환
|
||||
* @param pattern 날짜 형식 (예: "yyyy-MM-dd", "yyyyMMdd", "yyyy/MM/dd")
|
||||
* @return 형식화된 날짜 문자열
|
||||
*/
|
||||
public String getCurrentDate(String pattern) {
|
||||
LocalDate now = LocalDate.now();
|
||||
return now.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 날짜와 시간을 지정된 형식으로 반환
|
||||
* @param pattern 날짜 형식 (예: "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss")
|
||||
* @return 형식화된 날짜 문자열
|
||||
*/
|
||||
public String getCurrentDateTime(String pattern) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
return now.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 LocalDate 객체로 변환
|
||||
* @param dateStr 날짜 문자열
|
||||
* @param pattern 날짜 형식 (예: "yyyy-MM-dd", "yyyyMMdd")
|
||||
* @return 변환된 LocalDate 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static LocalDate parseLocalDate(String dateStr, String pattern) {
|
||||
if (dateStr == null || pattern == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 LocalDateTime 객체로 변환
|
||||
* @param dateTimeStr 날짜 시간 문자열
|
||||
* @param pattern 날짜 시간 형식 (예: "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss")
|
||||
* @return 변환된 LocalDateTime 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
|
||||
if (dateTimeStr == null || pattern == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDate 객체를 문자열로 변환
|
||||
* @param date LocalDate 객체
|
||||
* @param pattern 날짜 형식 (예: "yyyy-MM-dd", "yyyyMMdd")
|
||||
* @return 변환된 날짜 문자열, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static String formatLocalDate(LocalDate date, String pattern) {
|
||||
if (date == null || pattern == null) {
|
||||
return null;
|
||||
}
|
||||
return date.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime 객체를 문자열로 변환
|
||||
* @param dateTime LocalDateTime 객체
|
||||
* @param pattern 날짜 시간 형식 (예: "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss")
|
||||
* @return 변환된 날짜 시간 문자열, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static String formatLocalDateTime(LocalDateTime dateTime, String pattern) {
|
||||
if (dateTime == null || pattern == null) {
|
||||
return null;
|
||||
}
|
||||
return dateTime.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Date 객체를 LocalDate 객체로 변환
|
||||
* @param date Date 객체
|
||||
* @return 변환된 LocalDate 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static LocalDate toLocalDate(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Date 객체를 LocalDateTime 객체로 변환
|
||||
* @param date Date 객체
|
||||
* @return 변환된 LocalDateTime 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(Date date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDate 객체를 Date 객체로 변환
|
||||
* @param localDate LocalDate 객체
|
||||
* @return 변환된 Date 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static Date toDate(LocalDate localDate) {
|
||||
if (localDate == null) {
|
||||
return null;
|
||||
}
|
||||
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime 객체를 Date 객체로 변환
|
||||
* @param localDateTime LocalDateTime 객체
|
||||
* @return 변환된 Date 객체, 변환 실패 시 null 반환
|
||||
*/
|
||||
public static Date toDate(LocalDateTime localDateTime) {
|
||||
if (localDateTime == null) {
|
||||
return null;
|
||||
}
|
||||
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜에 일수를 더하거나 뺀 날짜 반환
|
||||
* @param date 기준 날짜
|
||||
* @param days 더하거나 뺄 일수 (양수: 더하기, 음수: 빼기)
|
||||
* @return 계산된 날짜
|
||||
*/
|
||||
public static LocalDate addDays(LocalDate date, int days) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.plusDays(days);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜에 월수를 더하거나 뺀 날짜 반환
|
||||
* @param date 기준 날짜
|
||||
* @param months 더하거나 뺄 월수 (양수: 더하기, 음수: 빼기)
|
||||
* @return 계산된 날짜
|
||||
*/
|
||||
public static LocalDate addMonths(LocalDate date, int months) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.plusMonths(months);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜에 연수를 더하거나 뺀 날짜 반환
|
||||
* @param date 기준 날짜
|
||||
* @param years 더하거나 뺄 연수 (양수: 더하기, 음수: 빼기)
|
||||
* @return 계산된 날짜
|
||||
*/
|
||||
public static LocalDate addYears(LocalDate date, int years) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.plusYears(years);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 날짜 사이의 일수 계산
|
||||
* @param startDate 시작 날짜
|
||||
* @param endDate 종료 날짜
|
||||
* @return 두 날짜 사이의 일수 (endDate - startDate)
|
||||
*/
|
||||
public static long daysBetween(LocalDate startDate, LocalDate endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return 0;
|
||||
}
|
||||
return ChronoUnit.DAYS.between(startDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 날짜 사이의 월수 계산
|
||||
* @param startDate 시작 날짜
|
||||
* @param endDate 종료 날짜
|
||||
* @return 두 날짜 사이의 월수 (endDate - startDate)
|
||||
*/
|
||||
public static long monthsBetween(LocalDate startDate, LocalDate endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return 0;
|
||||
}
|
||||
return ChronoUnit.MONTHS.between(startDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 날짜 사이의 연수 계산
|
||||
* @param startDate 시작 날짜
|
||||
* @param endDate 종료 날짜
|
||||
* @return 두 날짜 사이의 연수 (endDate - startDate)
|
||||
*/
|
||||
public static long yearsBetween(LocalDate startDate, LocalDate endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return 0;
|
||||
}
|
||||
return ChronoUnit.YEARS.between(startDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 날짜 사이의 기간 계산
|
||||
* @param startDate 시작 날짜
|
||||
* @param endDate 종료 날짜
|
||||
* @return 두 날짜 사이의 기간 (년, 월, 일)
|
||||
*/
|
||||
public static Period periodBetween(LocalDate startDate, LocalDate endDate) {
|
||||
if (startDate == null || endDate == null) {
|
||||
return Period.ZERO;
|
||||
}
|
||||
return Period.between(startDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 요일 이름 반환 (한글)
|
||||
* @param date 날짜
|
||||
* @return 요일 이름 (예: "월요일", "화요일")
|
||||
*/
|
||||
public static String getDayOfWeekName(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.KOREAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 요일 이름 반환 (영문)
|
||||
* @param date 날짜
|
||||
* @return 요일 이름 (예: "Monday", "Tuesday")
|
||||
*/
|
||||
public static String getDayOfWeekNameInEnglish(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 요일 이름 반환 (한글 약자)
|
||||
* @param date 날짜
|
||||
* @return 요일 이름 (예: "월", "화")
|
||||
*/
|
||||
public static String getDayOfWeekShortName(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.KOREAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜가 주말인지 확인
|
||||
* @param date 날짜
|
||||
* @return 주말이면 true, 평일이면 false
|
||||
*/
|
||||
public static boolean isWeekend(LocalDate date) {
|
||||
if (date == null) {
|
||||
return false;
|
||||
}
|
||||
DayOfWeek dayOfWeek = date.getDayOfWeek();
|
||||
return dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜가 평일인지 확인
|
||||
* @param date 날짜
|
||||
* @return 평일이면 true, 주말이면 false
|
||||
*/
|
||||
public static boolean isWeekday(LocalDate date) {
|
||||
return !isWeekend(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜가 오늘인지 확인
|
||||
* @param date 날짜
|
||||
* @return 오늘이면 true, 아니면 false
|
||||
*/
|
||||
public static boolean isToday(LocalDate date) {
|
||||
if (date == null) {
|
||||
return false;
|
||||
}
|
||||
return date.equals(LocalDate.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 월의 첫 날 반환
|
||||
* @param date 날짜
|
||||
* @return 월의 첫 날
|
||||
*/
|
||||
public static LocalDate getFirstDayOfMonth(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.firstDayOfMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 월의 마지막 날 반환
|
||||
* @param date 날짜
|
||||
* @return 월의 마지막 날
|
||||
*/
|
||||
public static LocalDate getLastDayOfMonth(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.lastDayOfMonth());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 연도의 첫 날 반환
|
||||
* @param date 날짜
|
||||
* @return 연도의 첫 날
|
||||
*/
|
||||
public static LocalDate getFirstDayOfYear(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.firstDayOfYear());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 연도의 마지막 날 반환
|
||||
* @param date 날짜
|
||||
* @return 연도의 마지막 날
|
||||
*/
|
||||
public static LocalDate getLastDayOfYear(LocalDate date) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.lastDayOfYear());
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 다음 특정 요일 반환
|
||||
* @param date 날짜
|
||||
* @param dayOfWeek 요일 (예: DayOfWeek.MONDAY)
|
||||
* @return 다음 특정 요일
|
||||
*/
|
||||
public static LocalDate getNextDayOfWeek(LocalDate date, DayOfWeek dayOfWeek) {
|
||||
if (date == null || dayOfWeek == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.next(dayOfWeek));
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜의 이전 특정 요일 반환
|
||||
* @param date 날짜
|
||||
* @param dayOfWeek 요일 (예: DayOfWeek.MONDAY)
|
||||
* @return 이전 특정 요일
|
||||
*/
|
||||
public static LocalDate getPreviousDayOfWeek(LocalDate date, DayOfWeek dayOfWeek) {
|
||||
if (date == null || dayOfWeek == null) {
|
||||
return null;
|
||||
}
|
||||
return date.with(TemporalAdjusters.previous(dayOfWeek));
|
||||
}
|
||||
|
||||
/**
|
||||
* 지정된 날짜에 시간을 결합하여 LocalDateTime 객체 생성
|
||||
* @param date 날짜
|
||||
* @param hour 시
|
||||
* @param minute 분
|
||||
* @param second 초
|
||||
* @return 생성된 LocalDateTime 객체
|
||||
*/
|
||||
public static LocalDateTime combineDateTime(LocalDate date, int hour, int minute, int second) {
|
||||
if (date == null) {
|
||||
return null;
|
||||
}
|
||||
return LocalDateTime.of(date, LocalTime.of(hour, minute, second));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,352 @@
|
||||
package egovframework.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 숫자 관련 공통 유틸리티 클래스
|
||||
*/
|
||||
@Component
|
||||
public class NumberUtil {
|
||||
|
||||
/**
|
||||
* 문자열을 정수(int)로 변환
|
||||
* @param str 변환할 문자열
|
||||
* @param defaultValue 변환 실패 시 반환할 기본값
|
||||
* @return 변환된 정수 또는 기본값
|
||||
*/
|
||||
public static int toInt(String str, int defaultValue) {
|
||||
if (StringUtil.isEmpty(str)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 정수(long)로 변환
|
||||
* @param str 변환할 문자열
|
||||
* @param defaultValue 변환 실패 시 반환할 기본값
|
||||
* @return 변환된 정수 또는 기본값
|
||||
*/
|
||||
public static long toLong(String str, long defaultValue) {
|
||||
if (StringUtil.isEmpty(str)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 실수(double)로 변환
|
||||
* @param str 변환할 문자열
|
||||
* @param defaultValue 변환 실패 시 반환할 기본값
|
||||
* @return 변환된 실수 또는 기본값
|
||||
*/
|
||||
public static double toDouble(String str, double defaultValue) {
|
||||
if (StringUtil.isEmpty(str)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 BigDecimal로 변환
|
||||
* @param str 변환할 문자열
|
||||
* @param defaultValue 변환 실패 시 반환할 기본값
|
||||
* @return 변환된 BigDecimal 또는 기본값
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(String str, BigDecimal defaultValue) {
|
||||
if (StringUtil.isEmpty(str)) {
|
||||
return defaultValue;
|
||||
}
|
||||
try {
|
||||
return new BigDecimal(str.trim());
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 천 단위 구분 기호가 포함된 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 천 단위 구분 기호가 포함된 문자열
|
||||
*/
|
||||
public static String formatWithComma(long number) {
|
||||
return NumberFormat.getNumberInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 천 단위 구분 기호가 포함된 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 천 단위 구분 기호가 포함된 문자열
|
||||
*/
|
||||
public static String formatWithComma(double number) {
|
||||
return NumberFormat.getNumberInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 천 단위 구분 기호가 포함된 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 천 단위 구분 기호가 포함된 문자열
|
||||
*/
|
||||
public static String formatWithComma(BigDecimal number) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
return NumberFormat.getNumberInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 원화 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 원화 형식의 문자열 (예: "₩1,000")
|
||||
*/
|
||||
public static String formatKRW(long number) {
|
||||
return NumberFormat.getCurrencyInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 원화 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 원화 형식의 문자열 (예: "₩1,000.50")
|
||||
*/
|
||||
public static String formatKRW(double number) {
|
||||
return NumberFormat.getCurrencyInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 원화 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 원화 형식의 문자열 (예: "₩1,000.50")
|
||||
*/
|
||||
public static String formatKRW(BigDecimal number) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
return NumberFormat.getCurrencyInstance(Locale.KOREA).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 달러 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 달러 형식의 문자열 (예: "$1,000")
|
||||
*/
|
||||
public static String formatUSD(long number) {
|
||||
return NumberFormat.getCurrencyInstance(Locale.US).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 달러 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 달러 형식의 문자열 (예: "$1,000.50")
|
||||
*/
|
||||
public static String formatUSD(double number) {
|
||||
return NumberFormat.getCurrencyInstance(Locale.US).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 달러 형식의 문자열로 변환
|
||||
* @param number 변환할 숫자
|
||||
* @return 달러 형식의 문자열 (예: "$1,000.50")
|
||||
*/
|
||||
public static String formatUSD(BigDecimal number) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
return NumberFormat.getCurrencyInstance(Locale.US).format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 지정된 소수점 자리수로 반올림
|
||||
* @param number 반올림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 반올림된 숫자
|
||||
*/
|
||||
public static double round(double number, int scale) {
|
||||
return BigDecimal.valueOf(number)
|
||||
.setScale(scale, RoundingMode.HALF_UP)
|
||||
.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* BigDecimal을 지정된 소수점 자리수로 반올림
|
||||
* @param number 반올림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 반올림된 숫자
|
||||
*/
|
||||
public static BigDecimal round(BigDecimal number, int scale) {
|
||||
if (number == null) {
|
||||
return null;
|
||||
}
|
||||
return number.setScale(scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 지정된 소수점 자리수로 내림
|
||||
* @param number 내림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 내림된 숫자
|
||||
*/
|
||||
public static double floor(double number, int scale) {
|
||||
return BigDecimal.valueOf(number)
|
||||
.setScale(scale, RoundingMode.FLOOR)
|
||||
.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* BigDecimal을 지정된 소수점 자리수로 내림
|
||||
* @param number 내림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 내림된 숫자
|
||||
*/
|
||||
public static BigDecimal floor(BigDecimal number, int scale) {
|
||||
if (number == null) {
|
||||
return null;
|
||||
}
|
||||
return number.setScale(scale, RoundingMode.FLOOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 지정된 소수점 자리수로 올림
|
||||
* @param number 올림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 올림된 숫자
|
||||
*/
|
||||
public static double ceil(double number, int scale) {
|
||||
return BigDecimal.valueOf(number)
|
||||
.setScale(scale, RoundingMode.CEILING)
|
||||
.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* BigDecimal을 지정된 소수점 자리수로 올림
|
||||
* @param number 올림할 숫자
|
||||
* @param scale 소수점 자리수
|
||||
* @return 올림된 숫자
|
||||
*/
|
||||
public static BigDecimal ceil(BigDecimal number, int scale) {
|
||||
if (number == null) {
|
||||
return null;
|
||||
}
|
||||
return number.setScale(scale, RoundingMode.CEILING);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 지정된 패턴으로 포맷팅
|
||||
* @param number 포맷팅할 숫자
|
||||
* @param pattern 패턴 (예: "#,###.##", "0.00")
|
||||
* @return 포맷팅된 문자열
|
||||
*/
|
||||
public static String format(double number, String pattern) {
|
||||
DecimalFormat df = new DecimalFormat(pattern);
|
||||
return df.format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자를 지정된 패턴으로 포맷팅
|
||||
* @param number 포맷팅할 숫자
|
||||
* @param pattern 패턴 (예: "#,###.##", "0.00")
|
||||
* @return 포맷팅된 문자열
|
||||
*/
|
||||
public static String format(BigDecimal number, String pattern) {
|
||||
if (number == null) {
|
||||
return "";
|
||||
}
|
||||
DecimalFormat df = new DecimalFormat(pattern);
|
||||
return df.format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 숫자 중 최소값 반환
|
||||
* @param a 첫 번째 숫자
|
||||
* @param b 두 번째 숫자
|
||||
* @return 최소값
|
||||
*/
|
||||
public static int min(int a, int b) {
|
||||
return Math.min(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 숫자 중 최대값 반환
|
||||
* @param a 첫 번째 숫자
|
||||
* @param b 두 번째 숫자
|
||||
* @return 최대값
|
||||
*/
|
||||
public static int max(int a, int b) {
|
||||
return Math.max(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 지정된 범위 내에 있는지 확인
|
||||
* @param number 확인할 숫자
|
||||
* @param min 최소값
|
||||
* @param max 최대값
|
||||
* @return 범위 내에 있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isBetween(int number, int min, int max) {
|
||||
return number >= min && number <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 지정된 범위 내에 있는지 확인
|
||||
* @param number 확인할 숫자
|
||||
* @param min 최소값
|
||||
* @param max 최대값
|
||||
* @return 범위 내에 있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isBetween(double number, double min, double max) {
|
||||
return number >= min && number <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 양수인지 확인
|
||||
* @param number 확인할 숫자
|
||||
* @return 양수이면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isPositive(int number) {
|
||||
return number > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 음수인지 확인
|
||||
* @param number 확인할 숫자
|
||||
* @return 음수이면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNegative(int number) {
|
||||
return number < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 0인지 확인
|
||||
* @param number 확인할 숫자
|
||||
* @return 0이면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isZero(int number) {
|
||||
return number == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자가 0인지 확인 (부동소수점 오차 고려)
|
||||
* @param number 확인할 숫자
|
||||
* @return 0이면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isZero(double number) {
|
||||
return Math.abs(number) < 0.000001;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,218 @@
|
||||
package egovframework.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 문자열 관련 공통 유틸리티 클래스
|
||||
*/
|
||||
@Component
|
||||
public class StringUtil {
|
||||
|
||||
/**
|
||||
* 문자열이 null이거나 빈 문자열인지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @return null이거나 빈 문자열이면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isEmpty(String str) {
|
||||
return str == null || str.length() == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이 아니고 빈 문자열이 아닌지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @return null이 아니고 빈 문자열이 아니면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNotEmpty(String str) {
|
||||
return !isEmpty(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이거나 빈 문자열이거나 공백 문자로만 이루어져 있는지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @return null이거나 빈 문자열이거나 공백 문자로만 이루어져 있으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isBlank(String str) {
|
||||
if (isEmpty(str)) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
if (!Character.isWhitespace(str.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이 아니고 빈 문자열이 아니고 공백 문자로만 이루어져 있지 않은지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @return null이 아니고 빈 문자열이 아니고 공백 문자로만 이루어져 있지 않으면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNotBlank(String str) {
|
||||
return !isBlank(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열의 앞뒤 공백을 제거
|
||||
* @param str 처리할 문자열
|
||||
* @return 앞뒤 공백이 제거된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String trim(String str) {
|
||||
return str == null ? null : str.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이면 빈 문자열 반환, 그렇지 않으면 원래 문자열 반환
|
||||
* @param str 처리할 문자열
|
||||
* @return null이면 빈 문자열, 그렇지 않으면 원래 문자열
|
||||
*/
|
||||
public static String nullToEmpty(String str) {
|
||||
return str == null ? "" : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이거나 빈 문자열이면 기본값 반환, 그렇지 않으면 원래 문자열 반환
|
||||
* @param str 처리할 문자열
|
||||
* @param defaultValue 기본값
|
||||
* @return null이거나 빈 문자열이면 기본값, 그렇지 않으면 원래 문자열
|
||||
*/
|
||||
public static String defaultIfEmpty(String str, String defaultValue) {
|
||||
return isEmpty(str) ? defaultValue : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 null이거나 빈 문자열이거나 공백 문자로만 이루어져 있으면 기본값 반환, 그렇지 않으면 원래 문자열 반환
|
||||
* @param str 처리할 문자열
|
||||
* @param defaultValue 기본값
|
||||
* @return null이거나 빈 문자열이거나 공백 문자로만 이루어져 있으면 기본값, 그렇지 않으면 원래 문자열
|
||||
*/
|
||||
public static String defaultIfBlank(String str, String defaultValue) {
|
||||
return isBlank(str) ? defaultValue : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열의 좌측에서 지정된 길이만큼 문자열 추출
|
||||
* @param str 처리할 문자열
|
||||
* @param len 추출할 길이
|
||||
* @return 추출된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String left(String str, int len) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
if (len < 0) {
|
||||
return "";
|
||||
}
|
||||
if (str.length() <= len) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열의 우측에서 지정된 길이만큼 문자열 추출
|
||||
* @param str 처리할 문자열
|
||||
* @param len 추출할 길이
|
||||
* @return 추출된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String right(String str, int len) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
if (len < 0) {
|
||||
return "";
|
||||
}
|
||||
if (str.length() <= len) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(str.length() - len);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열에서 특정 문자열을 다른 문자열로 모두 치환
|
||||
* @param str 처리할 문자열
|
||||
* @param searchStr 찾을 문자열
|
||||
* @param replaceStr 치환할 문자열
|
||||
* @return 치환된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String replace(String str, String searchStr, String replaceStr) {
|
||||
if (isEmpty(str) || isEmpty(searchStr) || replaceStr == null) {
|
||||
return str;
|
||||
}
|
||||
return str.replace(searchStr, replaceStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열 내의 HTML 특수 문자를 이스케이프 처리
|
||||
* @param str 처리할 문자열
|
||||
* @return 이스케이프 처리된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String escapeHtml(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return str.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace("\"", """)
|
||||
.replace("'", "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열 내의 줄바꿈 문자를 HTML <br> 태그로 변환
|
||||
* @param str 처리할 문자열
|
||||
* @return 변환된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String nl2br(String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
return str.replace("\r\n", "<br>")
|
||||
.replace("\n", "<br>")
|
||||
.replace("\r", "<br>");
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 지정된 접두사로 시작하는지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @param prefix 접두사
|
||||
* @return 지정된 접두사로 시작하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean startsWith(String str, String prefix) {
|
||||
return str != null && prefix != null && str.startsWith(prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열이 지정된 접미사로 끝나는지 확인
|
||||
* @param str 검사할 문자열
|
||||
* @param suffix 접미사
|
||||
* @return 지정된 접미사로 끝나면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean endsWith(String str, String suffix) {
|
||||
return str != null && suffix != null && str.endsWith(suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열을 지정된 길이로 자르고 생략 부호를 추가
|
||||
* @param str 처리할 문자열
|
||||
* @param maxLength 최대 길이
|
||||
* @param suffix 생략 부호 (예: "...")
|
||||
* @return 처리된 문자열, null이면 null 반환
|
||||
*/
|
||||
public static String abbreviate(String str, int maxLength, String suffix) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
if (str.length() <= maxLength) {
|
||||
return str;
|
||||
}
|
||||
if (suffix == null) {
|
||||
suffix = "";
|
||||
}
|
||||
int suffixLength = suffix.length();
|
||||
if (maxLength <= suffixLength) {
|
||||
return suffix;
|
||||
}
|
||||
return str.substring(0, maxLength - suffixLength) + suffix;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,340 @@
|
||||
package egovframework.util;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* 데이터 유효성 검증 관련 공통 유틸리티 클래스
|
||||
*/
|
||||
@Component
|
||||
public class ValidationUtil {
|
||||
|
||||
/** 이메일 주소 정규식 패턴 */
|
||||
private static final Pattern EMAIL_PATTERN =
|
||||
Pattern.compile("^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$");
|
||||
|
||||
/** 한국 휴대폰 번호 정규식 패턴 (010-XXXX-XXXX 또는 010XXXXXXXX 형식) */
|
||||
private static final Pattern MOBILE_PHONE_PATTERN =
|
||||
Pattern.compile("^01(?:0|1|[6-9])(?:-?\\d{3,4})?(?:-?\\d{4})$");
|
||||
|
||||
/** 한국 일반 전화번호 정규식 패턴 (지역번호-국번-번호 형식) */
|
||||
private static final Pattern PHONE_PATTERN =
|
||||
Pattern.compile("^(?:(?:\\d{2,3})|(?:\\d{2,3}-))(?:\\d{3,4}-\\d{4})$");
|
||||
|
||||
/** 한국 우편번호 정규식 패턴 (5자리) */
|
||||
private static final Pattern ZIPCODE_PATTERN =
|
||||
Pattern.compile("^\\d{5}$");
|
||||
|
||||
/** 한국 주민등록번호 정규식 패턴 (XXXXXX-XXXXXXX 형식) */
|
||||
private static final Pattern RESIDENT_REGISTRATION_NUMBER_PATTERN =
|
||||
Pattern.compile("^\\d{6}-?[1-4]\\d{6}$");
|
||||
|
||||
/** 한국 사업자등록번호 정규식 패턴 (XXX-XX-XXXXX 형식) */
|
||||
private static final Pattern BUSINESS_REGISTRATION_NUMBER_PATTERN =
|
||||
Pattern.compile("^\\d{3}-?\\d{2}-?\\d{5}$");
|
||||
|
||||
/** IP 주소 정규식 패턴 (IPv4) */
|
||||
private static final Pattern IPV4_PATTERN =
|
||||
Pattern.compile("^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
|
||||
|
||||
/** URL 정규식 패턴 */
|
||||
private static final Pattern URL_PATTERN =
|
||||
Pattern.compile("^(https?|ftp)://[^\\s/$.?#].[^\\s]*$");
|
||||
|
||||
/** 날짜 정규식 패턴 (YYYY-MM-DD 형식) */
|
||||
private static final Pattern DATE_PATTERN =
|
||||
Pattern.compile("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$");
|
||||
|
||||
/** 시간 정규식 패턴 (HH:MM:SS 형식) */
|
||||
private static final Pattern TIME_PATTERN =
|
||||
Pattern.compile("^([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?$");
|
||||
|
||||
/** 한글 정규식 패턴 */
|
||||
private static final Pattern KOREAN_PATTERN =
|
||||
Pattern.compile("^[가-힣]+$");
|
||||
|
||||
/** 영문자 정규식 패턴 */
|
||||
private static final Pattern ENGLISH_PATTERN =
|
||||
Pattern.compile("^[a-zA-Z]+$");
|
||||
|
||||
/** 영문자 및 숫자 정규식 패턴 */
|
||||
private static final Pattern ALPHANUMERIC_PATTERN =
|
||||
Pattern.compile("^[a-zA-Z0-9]+$");
|
||||
|
||||
/** 숫자 정규식 패턴 */
|
||||
private static final Pattern NUMERIC_PATTERN =
|
||||
Pattern.compile("^[0-9]+$");
|
||||
|
||||
/**
|
||||
* 이메일 주소 유효성 검증
|
||||
* @param email 검증할 이메일 주소
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidEmail(String email) {
|
||||
if (StringUtil.isEmpty(email)) {
|
||||
return false;
|
||||
}
|
||||
return EMAIL_PATTERN.matcher(email).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 휴대폰 번호 유효성 검증
|
||||
* @param mobilePhone 검증할 휴대폰 번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidMobilePhone(String mobilePhone) {
|
||||
if (StringUtil.isEmpty(mobilePhone)) {
|
||||
return false;
|
||||
}
|
||||
return MOBILE_PHONE_PATTERN.matcher(mobilePhone).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 일반 전화번호 유효성 검증
|
||||
* @param phone 검증할 전화번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidPhone(String phone) {
|
||||
if (StringUtil.isEmpty(phone)) {
|
||||
return false;
|
||||
}
|
||||
return PHONE_PATTERN.matcher(phone).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 우편번호 유효성 검증
|
||||
* @param zipcode 검증할 우편번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidZipcode(String zipcode) {
|
||||
if (StringUtil.isEmpty(zipcode)) {
|
||||
return false;
|
||||
}
|
||||
return ZIPCODE_PATTERN.matcher(zipcode).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 주민등록번호 유효성 검증 (형식만 검증, 실제 유효성은 검증하지 않음)
|
||||
* @param rrn 검증할 주민등록번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidResidentRegistrationNumber(String rrn) {
|
||||
if (StringUtil.isEmpty(rrn)) {
|
||||
return false;
|
||||
}
|
||||
return RESIDENT_REGISTRATION_NUMBER_PATTERN.matcher(rrn).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한국 사업자등록번호 유효성 검증 (형식만 검증, 실제 유효성은 검증하지 않음)
|
||||
* @param brn 검증할 사업자등록번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidBusinessRegistrationNumber(String brn) {
|
||||
if (StringUtil.isEmpty(brn)) {
|
||||
return false;
|
||||
}
|
||||
return BUSINESS_REGISTRATION_NUMBER_PATTERN.matcher(brn).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* IP 주소(IPv4) 유효성 검증
|
||||
* @param ipAddress 검증할 IP 주소
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidIpAddress(String ipAddress) {
|
||||
if (StringUtil.isEmpty(ipAddress)) {
|
||||
return false;
|
||||
}
|
||||
return IPV4_PATTERN.matcher(ipAddress).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* URL 유효성 검증
|
||||
* @param url 검증할 URL
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidUrl(String url) {
|
||||
if (StringUtil.isEmpty(url)) {
|
||||
return false;
|
||||
}
|
||||
return URL_PATTERN.matcher(url).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜 유효성 검증 (YYYY-MM-DD 형식)
|
||||
* @param date 검증할 날짜
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidDate(String date) {
|
||||
if (StringUtil.isEmpty(date)) {
|
||||
return false;
|
||||
}
|
||||
return DATE_PATTERN.matcher(date).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 시간 유효성 검증 (HH:MM:SS 또는 HH:MM 형식)
|
||||
* @param time 검증할 시간
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidTime(String time) {
|
||||
if (StringUtil.isEmpty(time)) {
|
||||
return false;
|
||||
}
|
||||
return TIME_PATTERN.matcher(time).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 한글 유효성 검증
|
||||
* @param text 검증할 문자열
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isKorean(String text) {
|
||||
if (StringUtil.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
return KOREAN_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 영문자 유효성 검증
|
||||
* @param text 검증할 문자열
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isEnglish(String text) {
|
||||
if (StringUtil.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
return ENGLISH_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 영문자 및 숫자 유효성 검증
|
||||
* @param text 검증할 문자열
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isAlphanumeric(String text) {
|
||||
if (StringUtil.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
return ALPHANUMERIC_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 숫자 유효성 검증
|
||||
* @param text 검증할 문자열
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isNumeric(String text) {
|
||||
if (StringUtil.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
return NUMERIC_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
||||
/**
|
||||
* 비밀번호 복잡성 검증 (영문 대소문자, 숫자, 특수문자 포함 8자 이상)
|
||||
* @param password 검증할 비밀번호
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidPassword(String password) {
|
||||
if (StringUtil.isEmpty(password) || password.length() < 8) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasUpperCase = false;
|
||||
boolean hasLowerCase = false;
|
||||
boolean hasDigit = false;
|
||||
boolean hasSpecialChar = false;
|
||||
|
||||
for (char c : password.toCharArray()) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
hasUpperCase = true;
|
||||
} else if (Character.isLowerCase(c)) {
|
||||
hasLowerCase = true;
|
||||
} else if (Character.isDigit(c)) {
|
||||
hasDigit = true;
|
||||
} else if (!Character.isLetterOrDigit(c)) {
|
||||
hasSpecialChar = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasUpperCase && hasLowerCase && hasDigit && hasSpecialChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 문자열 길이 검증
|
||||
* @param text 검증할 문자열
|
||||
* @param minLength 최소 길이
|
||||
* @param maxLength 최대 길이
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidLength(String text, int minLength, int maxLength) {
|
||||
if (text == null) {
|
||||
return minLength <= 0;
|
||||
}
|
||||
int length = text.length();
|
||||
return length >= minLength && length <= maxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* 주민등록번호 유효성 검증 (체크섬 포함)
|
||||
* @param rrn 검증할 주민등록번호 (XXXXXX-XXXXXXX 형식)
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidResidentRegistrationNumberWithChecksum(String rrn) {
|
||||
if (!isValidResidentRegistrationNumber(rrn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 하이픈 제거
|
||||
rrn = rrn.replace("-", "");
|
||||
|
||||
// 가중치 배열
|
||||
int[] weights = {2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5};
|
||||
|
||||
// 합계 계산
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 12; i++) {
|
||||
sum += (rrn.charAt(i) - '0') * weights[i];
|
||||
}
|
||||
|
||||
// 체크섬 계산
|
||||
int checksum = (11 - (sum % 11)) % 10;
|
||||
|
||||
// 마지막 자리와 체크섬 비교
|
||||
return checksum == (rrn.charAt(12) - '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* 사업자등록번호 유효성 검증 (체크섬 포함)
|
||||
* @param brn 검증할 사업자등록번호 (XXX-XX-XXXXX 형식)
|
||||
* @return 유효하면 true, 그렇지 않으면 false
|
||||
*/
|
||||
public static boolean isValidBusinessRegistrationNumberWithChecksum(String brn) {
|
||||
if (!isValidBusinessRegistrationNumber(brn)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 하이픈 제거
|
||||
brn = brn.replace("-", "");
|
||||
|
||||
// 가중치 배열
|
||||
int[] weights = {1, 3, 7, 1, 3, 7, 1, 3, 5};
|
||||
|
||||
// 합계 계산
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
sum += (brn.charAt(i) - '0') * weights[i];
|
||||
}
|
||||
|
||||
// 체크섬 계산
|
||||
sum += ((brn.charAt(8) - '0') * 5) / 10;
|
||||
int checksum = (10 - (sum % 10)) % 10;
|
||||
|
||||
// 마지막 자리와 체크섬 비교
|
||||
return checksum == (brn.charAt(9) - '0');
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue