📚 Study/JAVA
[JAVA] 날짜와 시간 & 형식화
0_ch4n
2022. 5. 5. 21:53
반응형
✔️ 날짜와 시간
📌 java.util.Date 클래스
- Date 클래스는 대부분의 메서드가 'deprecated'이므로 Calendar로 변환해가며 사용한다
//Calendar -> Date
Calendar cal = Calendar.getInstance();
Date d = new Date(cal.getTimeInMillis());
//Date -> Calendar
Date d = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(d);
📌 java.util.Calendar 클래스
- 추상 클래스이므로 getInstance()를 통해 날짜와 시간에 대한 정보를 갖게끔 구현해야 한다
- getInstance()는 태국은 BuddhistCalendar, 나머지는 GregorianCalendar를 반환한다
//Calendar 클래스 구현
Calendar cal = Calendar.getInstance(); //getInstance()를 통해 클래스 구현
Calendar cal2 = new GregorianCalendar(); //GregorianCalendar를 통해 클래스 구현
Date d = new Date();
cal.setTime(d); //getInstance()로 Date 클래스를 구현
//get 메서드
System.out.println(cal.get(Calendar.YEAR)); //1, 년도
System.out.println(cal.get(Calendar.MONTH)); //2, 월(0~11월)
System.out.println(cal.get(Calendar.WEEK_OF_YEAR)); //3, 이 해의 몇 째 주
System.out.println(cal.get(Calendar.WEEK_OF_MONTH)); //4, 이 달의 몇 째 주
System.out.println(cal.get(Calendar.DATE)); //5, 일
System.out.println(cal.get(Calendar.DAY_OF_MONTH)); //5, 일
System.out.println(cal.get(Calendar.DAY_OF_YEAR)); //6, 이 해의 몇 일
System.out.println(cal.get(Calendar.DAY_OF_WEEK)); //7, 요일(1:일요일)
System.out.println(cal.get(Calendar.DAY_OF_WEEK_IN_MONTH)); //8, 이 달의 몇 쨰 요일
System.out.println(cal.get(Calendar.AM_PM)); //9, 오전오후(0:오전)
System.out.println(cal.get(Calendar.HOUR)); //10, 시간(0~11시간)
System.out.println(cal.get(Calendar.HOUR_OF_DAY)); //11, 시간(0~23시간)
System.out.println(cal.get(Calendar.MINUTE)); //12, 분(0~59분)
System.out.println(cal.get(Calendar.SECOND)); //13, 초(0~59초)
System.out.println(cal.get(Calendar.MILLISECOND)); //14, 1000분의 1초(0~999)
System.out.println(cal.get(Calendar.ZONE_OFFSET)); //15, 타임존(-12~+12)
System.out.println(cal.getActualMaximum(Calendar.DATE)); //이 달의 마지막 일
//set 메서드
cal.set(Calendar.HOUR, 5); 5시로 설정
cal.set(2030, 5, 30); //2030년 5월 30일로 설정
cal.set(2030, 5, 30, 5, 30); //2030년 5월 30일 5시 30분으로 설정
cal.set(2030, 5, 30, 5, 30 ,10); //2030년 5월 30일 5시 30분 10초로 설정
//1000분의 1초로 시간 구하기
cal.getTimeInMillis();
//증가, 감소
cal.add(Calendar.MONTH, -6) //달을 6만큼 감소 (다른 필드에 영향 O)
cal.roll(Calendar.MONTH, -6) //달을 6만큼 감소 (다른 필드에 영향 X, 말일은 영향 O)
✔️ 형식화
- java.text 패키지에 포함되어 있으며 숫자, 날짜, 텍스트 데이터를 일정한 형식에 맞게 표현하거나 역으로 데이터를 얻어낼 수 있다
📌 DecimalFormat 클래스
- 숫자를 형식화하거나 텍스트 데이터를 숫자로 변환하는데 사용한다
double number = 1234567.89;
String[] pattern = {
"0", //1234568
"#", //1234568
"0.0", //1234567.9
"#.#", //1234567.9
"0000000000.0000", //0001234567.8900
"##########.####", //1234567.89
"#.#-", //1234567.9-
"-#.#", //-1234567.9
"#,###.##", //1,234,567.89
"#,####.##", //123,4567.89
"#E0", //.1E7
"0E0", //1E6
"##E0", //1.2E6
"####E0", //123.5E4
"0000E0", //1235E3
"#.#E0", //1.2E6
"0.0E0", //1.2E6
"0.000000000E0", //1.234567890E6
"00.00000000E0", //12.34567890E5
"000.0000000E0", //123.4567890E4
"#.#########E0", //1.23456789E6
"##.########E0", //1.23456789E6
"###.#######E0", //1.23456789E6
"#,###.##+;#,###.##-", //1,234,567.89+
"#.#%", //123456789%
"#.#\u2030", //1234567890%
"\u00A4 #,###", //₩ 1,234,568
"'#'#,###", //#1,234,568
"''#,###", //'1,234,568
};
for(int i = 0; i <pattern.length; i++) {
DecimalFormat df = new DecimalFormat(pattern[i]);
System.out.printf("%s : %s\n", pattern[i], df.format(number));
}
DecimalFormat df = new DecimalFormat("#,###.##");
DecimalFormat df2 = new DecimalFormat("#.###E0");
Number num = df.parse("1,234,567.89");
double d = num.doubleValue(); //Number 클래스를 통한 문자열 -> 숫자로의 변환
System.out.println(d);
System.out.println(df2.format(num)); //format 메서드를 통한 숫자 -> 문자열로의 변환
📌 SimpleDateFormat 클래스
- Date나 Calendar를 통해 만든 인스턴스를 원하는 형태로 출력하기 위해 사용한다
- Date 인스턴스만 format 메서드에 사용될 수 있기 때문에 Calendar는 Date로 변환하여 사용한다
//Calendar를 Date로 변환
Calendar cal = Calendar.getInstance();
cal.set(2005, 9, 3);
Date d = cal.getTime();
//Date 생성
Date d2 = new Date();
//parse()를 통한 Date 생성
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일");
try {
Date d3 = sdf.parse("2015년 11월 23일");
} catch (Exception e) {}
//SimpleFormat 생성
SimpleDateFormat sdf1, sdf2, sdf3, sdf4, sdf5, sdf6, sdf7, sdf8, sdf9;
sdf1 = new SimpleDateFormat("yyyy-MM-dd");
sdf2 = new SimpleDateFormat("''yy년 MMM dd일 E요일");
sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf4 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a");
sdf5 = new SimpleDateFormat("오늘은 올 해의 D번째 날입니다.");
sdf6 = new SimpleDateFormat("오늘은 이 달의 d번째 날입니다.");
sdf7 = new SimpleDateFormat("오늘은 올 해의 w번째 주입니다.");
sdf8 = new SimpleDateFormat("오늘은 이 달의 W번째 주입니다.");
sdf9 = new SimpleDateFormat("오늘은 이 달의 F번째 E요일입니다.");
📌 ChoiceFormat 클래스
- 특정 범위에 속하는 값을 문자열로 변환할 때 사용한다
//경계값과 치환할 문자열의 개수는 같아야 한다
double[] limits = {60,70,80,90}; //범위의 경계값 (꼭 double형이고 오름차순이어야 함)
String[] value = {"D","C","B","A"}; //치환할 문자열
ChoiceFormat cf = new ChoiceFormat(limits, value);
//패턴을 이용한 치환
String pattern = "60#D|70#C|80<B|90#A"; //#은 범위에 포함, <은 범위에 미포함
ChoiceFormat cf2 = new ChoiceFormat(pattern);
//변환 대상
int[] score = {100,95,88,70,52,60,70};
//출력
for(int i = 0; i < score.length; i++) {
System.out.println(cf.format(score[i]));
}
📌 MessageFormat 클래스
- 데이터를 정해진 양식에 맞게 출력할 때 사용한다
//양식 생성 ({}부분에 데이터가 들어간다)
String pattern = "Name: {0} \nTel: {1} \nAge: {2} \nBirthday: {3}";
//양식에 들어갈 데이터
Object[] data = {"이자바", "02-123-1234", "27", "07-09"};
//format 생성과 출력
String result = MessageFormat.format(pattern, data);
System.out.println(result);
📌 DateTimeFormatter
- 형식화 클래스 중 날짜와 시간에 특화된 형식화 클래스이다
- static 메서드 ofLocalizedDate(), ofLocalizedTime(), ofLocalizedDateTime()의 FormatStyle
- ofPattern()로 기호를 이용해 출력형식을 직접 정의할 수도 있다
- parse()로 문자열을 날짜 또는 시간으로 변환할 수 있다
✔️ java.time 패키지
- jdk 8부터 Date와 Calendar의 단점을 보완하고 불변이므로 항상 새로운 객체를 반환하며 멀티스레드에 안전하다.
📌 java.time 패키지의 클래스들
- TemporalUnit(날짜와 시간의 단위를 정의)과 ChronoUnit(열거형)이 있다
- Temporal, TemporalAccessor, TemporalAdjuster -> LocalDate, LocalTime, LocalDateTime, ZonedDateTime
- TemporalAmount -> Period, Duration
LocalDate와 LocalTime 클래스
//now()를 통한 객체 생성
LocalDate date = LocalDate.now(); //날짜
LocalTime time = LocalTime.now(); //시간
//of()를 통한 객체 생성
LocalDate date2 = LocalDate.of(2015, 11, 23);
LocalTime time2 = LocalTime.of(23,59,59);
//parse를 통한 문자열 -> 날짜와 시간
LocalDate date3 = LocalDate.parse("1999-12-31");
LocalTime time3 = LocalTime.parse("23:59:59");
//get(), getXXX()을 통해 값 가져오기
date.getYear();
time.getHour();
//필드 값 변경
date.withYear(2022); //with()는 직접 지정
date.plusYears(2); //plus()는 더하기
date.minusYears(2); //minus()는 빼기
//날짜와 시간의 비교
date.isAfter(date2);
date.isBefore(date2);
date.isEqual(date2);
Instant 클래스
- 에포크 타임(1970-01-01 00:00:00 UTC)부터 경과된 시간을 나노초 단위로 표현한다
- 세계협정시 UTC(+00:00)는 한국 시간대(+09:00)와 9시간 차이난다
//Instant 생성
Instant now = Instant.now();
Instant now2 = Instant.ofEpochSecond(now.getEpochSecond());
//필드 값 가져오기
now.getEpochSecond(); //초 단위
now.getNano(); //나노초 단위
now.toEpochMilli(); //밀리초 단위
//Instant와 Date 변환
Instant.from(now); //Instant -> Date
Date d = new Date();
d.toInstant(); //Date -> Instant
LocalDateTime과 ZonedDateTime 클래스
- LocalDateTime = LocalDate + LocalTime
- ZonedDateTime = LocalDateTime + 시간대
//LocalDateTime 생성
LocalDateTime dt = LocalDateTime.now();
LocalDateTime dt1 = LocalDateTime.of(2015,12,31,12,34,56);
LocalDateTime dt2 = LocalDateTime.of(date,time);
LocalDateTime dt3 = date.atTime(time);
LocalDateTime dt4 = time.atDate(date);
LocalDateTime dt5 = date.atStartOfDay(); //0시 0분 0초
//ZonedDateTime 생성
ZonedDateTime zdt = ZonedDateTime.now();
ZonedDateTime zdt1 = ZonedDateTime.of(dt, ZoneId.of("Asia/Seoul"));
ZonedDateTime zdt2 = dt.atZone(ZoneId.of("Asia/Seoul"));
ZonedDateTime zdt3 = ZonedDateTime.now().withZoneSameInstant(ZoneId.of("America/NewYork"));
//LocalDateTime -> LocalDate or LocalTime or ZonedDateTime 변환
LocalDate date = dt.toLocalDate();
LocalTime time = dt.toLocalTime();
ZonedDateTime zdt = dt.atZone(ZoneId.of("Asia/Seoul"));
//UTC로부터 얼만큼 떨어져있는지 확인
ZoneOffset zo = ZonedDateTime.now().getOffset();
int offset = zo.get(ChronoField.OFFSET_SECONDS);
//ZonedDateTime -> OffsetDateTime
OffsetDateTime odt = zdt.toOffsetDateTime();
OffsetDateTime odt1 = OffsetDateTime.of(date, time, zo);
//ZonedDateTime과 GregorianCalendar 변환
GregorianCalendar gc = GregorianCalendar.from(zdt); //ZonedDateTime -> GregorianCalendar
gc.toZonedDateTime(); //GregorianCalendar -> ZonedDateTime
TemporalAdjusters 클래스
- 자주 쓰이는 날짜 계산을 메서드로 정의해놓은 것이다
LocalDate date = LocalDate.now();
TemporalAdjusters.firstDayOfNextMonth(); //다음 해의 첫 날
TemporalAdjusters.firstDayOfNextYear(); //다음 달의 첫 날
TemporalAdjusters.firstDayOfYear(); //올 해의 첫 날
TemporalAdjusters.firstDayOfMonth(); //이번 달의 첫 날
TemporalAdjusters.lastDayOfYear(); //올 해의 마지막 날
TemporalAdjusters.lastDayOfMonth(); //이번 달의 마지막 날
TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY); //이번 달의 첫 번째 ?요일
TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY); //이번 달의 마지막 ?요일
TemporalAdjusters.previous(DayOfWeek.MONDAY); //지난 ?요일(당일 미포함)
TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY); //지난 ?요일(당일 포함)
TemporalAdjusters.next(DayOfWeek.MONDAY); //다음 ?요일(당일 미포함)
TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY); //다음 ?요일(당일 포함)
TemporalAdjusters.dayOfWeekInMonth(1, DayOfWeek.MONDAY); //이번 달의 n번째 ?요일
//with()를 통한 활용
date.with(TemporalAdjusters.firstDayOfNextMonth());
Period와 Duration 클래스
- Period는 날짜 간의 차이, Duration은 시간 간의 차이를 계산한다
//Period를 통해 날짜 간의 간격 구하기
Period period = Period.between(date, date2);
//Duration을 통해 시간 간의 간격 구하기
Duration duration = Duration.between(time, time2);
//get()을 통해 필드 값 구하기
period.get(ChronoUnit.YEARS); //int getYears()
period.get(ChronoUnit.MONTHS); //int getMonths()
period.get(ChronoUnit.DAYS); //int getDays()
duration.get(ChronoUnit.SECONDS); //long getSeconds()
duration.get(ChronoUnit.NANOS); //int getNano();
//between()과 until()
Period period1 = Period.between(date, date2); //static 메서드
Period period2 = date.until(date2); //instance 메서드
//기타 연산
period = period.minusYears(1).multipliedBy(2); //1년 빼고 2 곱함
duration = duration.plusHours(1).dividedBy(60); //1시간 더하고 60으로 나눔
boolean sameDate = Period.between(date, date2).isZero(); //0인지 확인
boolean isBefore = Duration.between(time, time2).isNegative(); //음수인지 확인
duration = duration.negated(); //부호를 반대로 변경
period = Period.of(1,13,32).normalized(); //1년 13개월 32일 -> 2년 1개월 32일
//toXXX()로 다른 단위로 변환하기
period.toTotalMonths(); //년월일을 월단위로 변환
duration.toDays(); //일단위로 변환
duration.toHours(); //시간단위로 변환
duration.toMinutes(); //분단위로 변환
duration.toMillis(); //천분의 일초 단위로 변환
duration.toNanos(); //나노초 단위로 변환
📄 참고
자바의 정석 3rd Edition
반응형