Date는 날짜와 시간을 다룰 목적으로 JDK1.0부터 제공되어온 클래스입니다.
그러나 Date클래스는 기능이 부족했기 때문에 Calendar라는 새로운 클래스를 JDK1.1부터 제공하기 시작했습니다.
다만 Calendar 클래스도 단점이 존재하기 때문에,
JDK 1.8부터 'java.time'패키지라는 기존의 단점들을 개선한 새로운 패키지가 추가되었습니다.
Calendar
Calendar는 추상클래스로 직접 객체를 생성할 수 없고, 메서드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어야 합니다.
Calendar cal = Calendar.getInstance();
다음은 Calendar의 get메서드로 받아올 수 있는 값들에 대한 예제입니다.
package ch10;
import java.util.Calendar;
public class CalendarEx1 {
public static void main(String[] args) {
Calendar today = Calendar.getInstance();
System.out.println("이 해의 년도: " + today.get(Calendar.YEAR));
System.out.println("월(0~11, 0:1월):" + today.get(Calendar.MONTH));
System.out.println("이 해의 몇 째주 : " + today.get(Calendar.WEEK_OF_YEAR));
System.out.println("이 달의 몇 째주: "+ today.get(Calendar.WEEK_OF_MONTH));
//Day와 DAY_OF_MONTH는 같다.
System.out.println("이 달의 몇 일 :" + today.get(Calendar.DATE));
System.out.println("이 달의 몇 일:" + today.get(Calendar.DAY_OF_MONTH));
System.out.println("이 해의 몇 일:" + today.get(Calendar.DAY_OF_YEAR));
System.out.println("요일(1~7, 1: 일요일) : " + today.get(Calendar.DAY_OF_WEEK));
System.out.println("이 달의 몇째 요일 :" + today.get(Calendar.DAY_OF_WEEK_IN_MONTH));
System.out.println("오전_오후(0:오전, 1:오후): " + today.get(Calendar.AM_PM));
System.out.println("시간(0~11) : " + today.get(Calendar.HOUR));
System.out.println("시간(0~23) : " + today.get(Calendar.HOUR_OF_DAY));
System.out.println("분(0~59) : " + today.get(Calendar.MINUTE));
System.out.println("초(0~59) : " + today.get(Calendar.SECOND));
System.out.println("1000분의 1초(0~999) : " + today.get(Calendar.MILLISECOND));
System.out.println("TimeZone(-12~+12): " + today.get(Calendar.ZONE_OFFSET)/(60*60*1000));
System.out.println("이 달의 마지막 날: " + today.getActualMaximum(Calendar.DATE));//이 달의 마지막일
}
}
getInstance()를 통해서 얻은 인스턴스는 기본적으로 현재 시스템의 날짜와 시간에 대한 정보를 담고 있습니다.
또한 get(Calendar.Month)로 얻어오는 값의 범위는 1~12가 아닌 0~11인 점을 주의해야 합니다.
import java.util.Calendar;
public class CalendarEx2 {
public static void main(String[] args) {
final String[] DAY_OF_WEEK = {"","일","월","화","수","목","금","토"};
Calendar date1 = Calendar.getInstance();
Calendar date2 = Calendar.getInstance();
date1.set(2015,7,15); // 2021년 8월 15일로 날짜를 설정한다.
System.out.println("date1은 " + toString(date1) + DAY_OF_WEEK[date1.get(Calendar.DAY_OF_WEEK)] + "요일이고," );
System.out.println("오늘(date2)은 " + toString(date2) + DAY_OF_WEEK[date2.get(Calendar.DAY_OF_WEEK)] +"요일입니다.");
// 두 날짜간의 차이를 얻으려면, getTimeInMillis() 천분의 일초 단위로 변환해야함
long diffrence = (date2.getTimeInMillis() - date1.getTimeInMillis()) / 1000;
System.out.println("그 날(date1)부터 지금(date2)까지 " + diffrence + "가 지났습니다.");
System.out.println("일(day)로 계산하면 " + diffrence/(24*60*60) +"일입니다.");
}
public static String toString(Calendar date){
return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1) +"월 " + date.get(Calendar.DATE) + "일 ";
}
}
package ch10;
import java.util.Calendar;
public class CalendarEx3 {
public static void main(String[] args) {
final int[] TIME_UNIT = {3600, 60, 1}; //큰 단위를 앞에 놓음
final String[] TIME_UNIT_NAME = {"시간","분","초"};
Calendar time1 = Calendar.getInstance();
Calendar time2 = Calendar.getInstance();
time1.set(Calendar.HOUR_OF_DAY,10); // time1을 10시 20분 30초로 설정
time1.set(Calendar.MINUTE,20);
time1.set(Calendar.SECOND,30);
time2.set(Calendar.HOUR_OF_DAY,20);
time2.set(Calendar.MINUTE,20);
time2.set(Calendar.SECOND,30);
System.out.println("time1 :" + time1.get(Calendar.HOUR_OF_DAY) +"시 " + time1.get(Calendar.MINUTE) +"분 " + time1.get(Calendar.SECOND) + "초");
System.out.println("time2 :" + time2.get(Calendar.HOUR_OF_DAY) +"시 " + time2.get(Calendar.MINUTE) +"분 " + time2.get(Calendar.SECOND) + "초");
long difference = Math.abs(time2.getTimeInMillis() - time1.getTimeInMillis())/1000;
System.out.println("time1과 time2의 차이는 " + difference + "초 입니다.");
String tmp ="";
for(int i=0; i<TIME_UNIT.length;i++){
tmp += difference/TIME_UNIT[i] + TIME_UNIT_NAME[i];
difference %= TIME_UNIT[i];
}
System.out.println("시분초로 변환하면" + tmp + "입니다.");
}
}
package ch10;
import java.util.Calendar;
public class CalendarEx4 {
public static void main(String[] args) {
Calendar date = Calendar.getInstance();
date.set(2015,7,31);
System.out.println(toString(date));
System.out.println("= 1일 후 = ");
date.add(Calendar.DATE,1);
System.out.println(toString(date));
System.out.println("=6달전=");
date.add(Calendar.MONTH, -6);
System.out.println(toString(date));
System.out.println("= 31일후(roll) = ");
date.roll(Calendar.DATE,31);
System.out.println(toString(date));
System.out.println("= 31일후(add) =");
date.add(Calendar.DATE, 31);
System.out.println(toString(date));
}
public static String toString(Calendar date){
return date.get(Calendar.YEAR) + "년 " + (date.get(Calendar.MONTH) + 1)
+"월 " + date.get(Calendar.DATE) + "일";
}
}
- add(int field, int amount)를 사용하면 지정한 필드의 값을 원하는 만큼 증가 또는 감소시킬 수 있습니다.
- roll(int field, int amount)은 add와 달리 다른 필드에 영향을 미치지 않습니다. 가령 31일을 추가한다고 해도 월 필드의 값은 바뀌지 않습니다.
단, 일 필드가 말일일때 roll 메서드를 이용해 월 필드를 변경하면 일 필드에도 영향이 간다.
package ch10;
import java.util.Calendar;
public class CalendarEx5 {
public static void main(String[] args) {
Calendar date = Calendar.getInstance();
date.set(2015,0,31);
System.out.println(toString(date));
date.roll(Calendar.MONTH,1);
System.out.println(toString(date));
}
public static String toString(Calendar date){
return date.get(Calendar.YEAR) + "년" +(date.get(Calendar.MONTH) + 1) + "월 " + date.get(Calendar.DATE) + "일";
}
}
형식화 클래스
형식화 클래스는 형식화에 사용할 패턴을 정의하며, java.text패키지에 포함되어 있습니다. 숫자, 날짜, 텍스트 데이터를 일정한 형식에 맞게 표현할 수 있는 방법을 객체지향적으로 설계하여 표준화하였습니다.
DecimalFormat
형식화 클래스 중에서 숫자를 형식화하는데 사용하는 것은 DecimalFormat입니다. DecimalFormat을 사용하면 숫자 데이터를 정수, 부동소숫점, 금액등의 다양한 형식으로 표현할 수 있습니다.
0 | 10진수(값이 없을때는 0) |
# | 10진수 |
. | 소수점 |
- | 음수부호 |
. | 단위 구분자 |
E | 지수기호 |
; | 패턴 구분자 |
% | 퍼센트 |
\u2030 | 퍼밀 |
\u00A4 | 통화 |
' | escape문자 |
DecimalFormat을 사용하기 위해서는 먼저 원하는 출력 형식의 패턴을 작성해서 인스턴스를 생성한 다음, 출력하고자 하는 문자열로 format메서드를 호출하면 됩니다.
double number = 1234567.89;
DecimalFormat df = new DecimalFormat("#.#E0");
String result = df.format(number);
SimpleDateFormat
Date와 Calendar만으로 날짜 데이터를 원하는 형태로 다양하게 출력하는 것은 불편합니다. 하지만 SimpleDateFormat을 사용하면 이러한 문제들이 간단히 해결됩니다.
y | 년도 |
M | 월 |
w | 년의 몇번째 주 |
W | 월의 몇번째 주 |
D | 년의 몇번째 일 |
d | 월의 몇번째 일 |
F | 월의 몇번째 요일 |
E | 요일 |
H | 시간(0~23) |
m | 분(0~59) |
s | 초(0~59) |
SimpleDateFormat를 사용하기 위해서는 아래와 같이 사용합니다.
Date today = new Date();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 오늘 날짜를 yyyy-MM-dd형태로 변환하여 반환합니다.
String result = df.format(today);
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatEx1 {
public static void main(String[] args) {
Date today = new Date();
SimpleDateFormat sdf1, sdf2, sdf3, sdf4;
SimpleDateFormat 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요일입니다.");
System.out.println(sdf1.format(today));
System.out.println(sdf2.format(today));
System.out.println(sdf3.format(today));
System.out.println(sdf4.format(today));
System.out.println();
System.out.println(sdf5.format(today));
System.out.println(sdf6.format(today));
System.out.println(sdf7.format(today));
System.out.println(sdf8.format(today));
System.out.println(sdf9.format(today));
}
}
-parse(String source)를 사용하여 날짜 데이터의 출력형식 또한 변환할 수 있다. 문자열source을 날짜 Date인스턴스로 변환해준다.
package ch10;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatEx3 {
public static void main(String[] args) {
DateFormat df = new SimpleDateFormat("yyyy년 MM월 dd일");
DateFormat df2 = new SimpleDateFormat("yyyy/MM/dd");
try{
Date d = df.parse("2015년 11월 23일");
System.out.println(df2.format(d));
}catch (Exception e){
e.printStackTrace();
}
}
}
ChoiceFormat
choiceFormat은 특정 범위에 속하는 값을 문자열로 변환해줍니다.
파라미터로 두개의 배열을 사용하며, 경계값은 double형으로 반드시 모두 오름차순으로 정렬되어있어야 하며, 치환될 문자열의 개수는 경계값 배열에 정의된 범위의 개수와 일치해야 합니다.
import java.text.ChoiceFormat;
public class ChoiceFormatEx1 {
public static void main(String[] args) {
double[] limits = {60, 70, 80, 90};
String[] grades = {"D","C","B","A"};
int[] scores = {100, 95, 88, 70, 52,60,70};
ChoiceFormat form = new ChoiceFormat(limits,grades);
for(int i=0; i<scores.length;i++){
System.out.println(scores[i] + " :" + form.format(scores[i]));
}
}
}
MessageFormat
데이터를 정해진 양식에 맞게 출력할 수 있도록 도와줍니다.
package ch10;
import java.text.*;
public class MessageFormatEx1 {
// 데이터를 정해진 양식에 맞게 출력할 수 있도록 도와줍니다.
public static void main(String[] args) {
String msg = "Name : {0} \nTel: {1} \nAge{2} \nBirthday:{3}\n";
Object[] arguments = {
"이자바","02-123-1234","27","07-09"
};
String result = MessageFormat.format(msg,arguments);
System.out.println(result);
}
}
java.time 패키지
JDK 1.8부터 'java.time'패키지가 추가되었습니다.
이 패키지는 4개의 하위 패키지를 지닙니다.
java.time | 날짜와 시간을 다루는데 필요한 핵심 클래스 제공 |
java.time.chrono | 표준이 아닌 달력 시스템을 위한 클래스들을 제공 |
java.time.format | 날짜와 시간을 파싱하고, 형식화하기위한 클래스 제공 |
java.time.temporal | 날짜와 시간의 필드와 단위를 위한 클래스들을 제공 |
java.time.zone | 시간대와 관련된 클래스들을 제공 |
위 패키지들의 특징은 immutable(불변)하여, 기존의 객체를 변경하는 대신 항상 변경된 새로운 객체를 반환합니다.
날짜와 시간을 하나로 표현하는 Calendar클래스와 달리, java.time패키지에서는 날짜와 시간을 별도의 클래스로 분리해 놓았습니다.
<Temporal, TemporalAccessor, TemporalAdjuster 인터페이스를 구현한 클래스>
- LocalDate : 날짜
- LocalTime : 시간
- LocalDateTime : 날짜 + 시간
<TemporalAmount를 구현한 클래스>
- Period : 두 날짜간의 차이
- Duration : 두 시간간의 차이
java.time패키지에 속한 클래스의 객체를 생성하는 방법은 now()와 of()를 사용하는 것입니다.
now()는 현재 날짜와 시간을 저장하는 객체를 생성합니다.
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
ZonedDateTime dateTimeInKr = ZonedDateTime.now();
of()는 단순히 해당 필드의 값을 순서대로 지정해주면 됩니다.
LocalDate date = LocalDate.of(2015,11,23); // 2015년 11월 23일
LocalTime time = LocalTime.of(23,59,59); // 23시 59분 59초
LocalDateTime dateTime = LocalDateTime.of(date,time);
ZonedDateTime zDateTime = ZonedDateTime.of(dateTime,ZoneId.of("Asia/Seoul");
LocalDate와 LocalTime
LocalDate와 LocalTime은 java.time패키지의 가장 기본이 되는 클래스입니다.
위의 of()와 now()가 기본적인 메서드로 적용되며, parse()를 이용하면 문자열을 날자와 시간으로 변환할 수 있습니다.
LocalDate | int getYear() | 년도 |
int getMonthValue() | 월(12) | |
Month getMonth() | 월(December) | |
int getDayOfMonth() | 일(31) | |
int getDayOfYear() | 같은 해 1월 1일부터 몇번째 일 | |
DayOfWeek getDayOfWeek() | 요일 | |
int lengthOfMonth() | 같은 달의 총 일수 | |
int lengthOfYear() | 같은 해의 총 일수 | |
boolean isLeapYear() | 윤년여부 확인 | |
LocalTime | int getHour() | 시(23) |
int getMinute() | 분(59) | |
int getSecond() | 초(59) | |
int getNano() | 나노초(0) |
LocalDate와 LocalTime도 compareTo()가 오버라이딩 되어있어서 아래와 같이 compareTo()로 비교할 수 있습니다.
// 같으면 0, date1이 이전이면 -1, 이후면 1
int result = date1.compareTo(date2);
다음은 LocalDate와 LocalTime의 예제입니다.
package ch10;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
public class NewTimeEx1 {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalTime now = LocalTime.now();
LocalDate birthDate = LocalDate.of(1999,12,31);
LocalTime birthTime = LocalTime.of(23,59,59);
System.out.println("today=" + today);
System.out.println("now = " + now);
System.out.println("birthDate = " + birthDate);
System.out.println("birthTime = " + birthTime);
System.out.println(birthDate.withYear(2000));
System.out.println(birthDate.plusDays(1));
System.out.println(birthDate.plus(1, ChronoUnit.DAYS));
System.out.println(birthTime.truncatedTo(ChronoUnit.HOURS));
System.out.println(ChronoField.CLOCK_HOUR_OF_DAY.range());
System.out.println(ChronoField.HOUR_OF_DAY.range());
}
}
TemporalAdjusters
다음 해의 첫날, 이번 달의 마지막 날을 구하는 등 자주 쓰일만할 날짜 계산들을 대신 해주는 클래스입니다.
LocalDate today = LocalDate.now();
LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
firstDayOfNextYear() | 다음 해의 첫 날 |
firstDayOfNextMonth() | 다음 달의 첫 날 |
firstDayOfYear() | 올 해의 첫 날 |
firstDayOfMonth() | 이번 달의 첫 날 |
lastDayOfYear() | 올 해의 마지막 날 |
lastDayOfMonth() | 이번 달의 마지막 날 |
firstInMonth(DayOfWeek dayOfWeek) | 이번 달의 첫번째 ?요일 |
lastInMonth(DayOfWeek dayOfWeek) | 이번 달의 마지막 ?요일 |
previous(DayOfWeek dayOfWeek) | 지난 ?요일(당일 미 포함) |
previousOrSame(DayOfWeek dayOfWeek) | 지난 ?요일(당일 포함) |
next(DayOfWeek dayOfWeek) | 다음 ?요일(당일 미포함) |
nextOrSame(DayOfWeek dayOfWeek) | 다음 ?요일(당일 포함) |
dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek) | 이번 달의 n번째 ?요일 |
출처 : 자바의 정석 3판
'Language > Java' 카테고리의 다른 글
Generics (0) | 2022.01.10 |
---|---|
Collection Framework (0) | 2022.01.02 |
java.lang패키지와 유용한 클래스 (0) | 2021.12.19 |
예외처리 (2) | 2021.12.12 |
객체지향 프로그래밍2 (0) | 2021.12.05 |