Calendar 를 조금 더 쉽게 써보자, TimeUtil & TimeBuilder
해당 포스팅에서 언급된 내용은 Ndroid 에서 제공합니다.
Java 에서 시간 관련 클래스 (Calendar, Date) 들은 꽤 많이 사용됩니다.
하지만 언제나 사용할 때마다 헷갈리는 부분이 존재하며, 간단한 기능도 직관적이지 않은 패턴을 사용해야합니다. (예를들면, Calendar 에서 달을 출력하려면? 현재 년도에 특정 값을 더하고 싶다면?)
1 2 3 4 5 | Calendar calendar = Calendar.getInstance(); calendar.get(Calendar.MONTH); // 출력되는 달은 0-11 입니다. (1-12 가 안나온다는 것을 기억해야하죠. calendar.add(Calendar.YEAR, 2); // 년도를 더하고 싶습니다. 덧셈을 하고 싶다면, Calendar 의 상수를 이용해야하죠. | cs |
제 생각에 직관적이지 못하다고 생각하는 이유는 메소드명을 보고 행위를 하는 것이 아닌, 상수를 넣고 처리를 해야하기 때문입니다. 물론 Calendar 클래스에 익숙하다면 능숙하게 사용하겠지만, 날짜 연산에 대해 조금만 복잡하게 계산을 한다고 하면 저 상수를 이용한 연산을 줄줄이 입력해야할 수도 있습니다.
Ndroid 프로젝트에서는 조금 더 이를 편하게 사용하고 싶었습니다.
Calendar 의 사용목적이 결국 날짜 데이터를 핸들링하는 것이고, 일련의 연산과정 중 최종으로 핸들링된 날짜만 알고 싶습니다. 이를 마치 질의를 하는 것과 같은 선언형식으로 할 수 있다면 매우 코드가 아름다워지지 않을까라는 기대가 있었습니다.
Ndroid 의 TimeBuilder 모듈은 위와 같은 요구사항을 담도록 하였습니다.
예를 들어 이러한 요구사항이 있다고 합시다.
- String 으로 된 시간을 파싱할 것.
- 파싱한 날짜에 년도를 1 덧셈
- 파싱한 날짜에 달을 5 덧셈.
- 파싱한 날짜에 일을 1 뺄셈
- 시,분,초는 생략할 것.
- 날짜는 영어권으로 보여줄 것.
기존 자바 코드로 작성을 한다면, 이 정도 되겠네요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // simple java code. String dateString = "2017-3-26 16:40"; try { // parse. Date formatData = new SimpleDateFormat("yyyy-MM-dd hh:mm").parse(dateString); // calculating Calendar calendar = Calendar.getInstance(); calendar.setTime(formatData); calendar.add(Calendar.YEAR, 1); calendar.add(Calendar.MONTH, 5); calendar.add(Calendar.DAY_OF_MONTH, -1); // to yyMMdd calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); System.out.println(new SimpleDateFormat("yyyy.MM.dd (hh,mm,ss a)", Locale.ENGLISH).format(calendar.getTime())); } catch (ParseException e) { e.printStackTrace(); } | cs |
간단하지는 않네요. 사용하려면 상수의 기능부터 알아야하고 (DAY_OF_MONTH, HOUR_OF_DAY 등은 한 번 찾아봐야겠죠 .ㅡㅡ^), SimpleDateFormat 클래스의 기능도 알아야합니다.
위의 기능을 TimeBuilder 를 통해 작업해보도록 하겠습니다.
1 2 3 4 5 6 7 8 | TimeBuilder.Create(dateString, "yyyy-MM-dd hh:mm"). addYear(1). addMonth(5). addDay(-1). setLocale(Locale.ENGLISH). to_yyMMdd(). getStringFormat("yyyy.MM.dd (hh,mm,ss a)"). subscribe(System.out::println); | cs |
Builder 클래스에서 제공하는 메소드를 사용함으로써, 상수들을 알 필요가 없어졌으며 파싱 및 포맷을 위해서 사용할 SimpleDateFormat 역시 몰라도 됩니다.
파이프라인 메소드 중 getStringFormat 의 출력 타입은 RxJava 의 Maybe 입니다.
포맷의 형식이 잘못되어 포맷에 실패할 수도 있으며, 이런 결과를 이전 MaybeUtil 에서 제공하던 기능들과 같이 값이 있거나 없거나의 문제로 보았습니다.
MaybeUtil 의 기능은 아래에서 참고
TimeBuilder 의 인스턴스를 만드는 방법은 아래와 같이 다양합니다.
1 2 3 4 5 6 7 8 9 10 11 | // non-param : current time. TimeBuilder currentTimeBuilder = TimeBuilder.Create(); // param : Calendar. TimeBuilder calendarBuilder = TimeBuilder.Create(TimeUtil.GetCalendar()); // param : date TimeBuilder dateBuilder = TimeBuilder.Create(new Date()); // param : string, format TimeBuilder stringBuilder = TimeBuilder.Create("2017-3-26", "yyyy-MM-dd"); | cs |
보다 자세한 내용은 아래 url 에서 확인하실 수 있습니다.
이 기능을 제작하게 된 첫 번째 배경은 JAVA8 에서 Date 관련 API 의 개편이 있던 것으로 알았고 (아직 공부해보지는 않았습니다. 아마 다음 올릴 포스팅이 해당 부분일 것입니다.), 안드로이드 진영에서는 아직 JAVA8 을 온전히 지원하지 않기 때문에 추가하고자 하는 배경이 되었습니다.
JAVA8 의 기능을 보고 TimeBuilder 의 기능이 더 추가될 여지가 있길 바랍니다. :-)
'개발이야기 > 오픈소스 N series ' 카테고리의 다른 글
구간을 표현하자! [Between 기능 소개] (4) | 2017.07.06 |
---|---|
예외처리를 간소화하여, 코드를 이쁘게 해보자! (9) | 2017.05.10 |
RxJava2 의 Maybe를 조금 더 적극적으로 써보자! MaybeUtil! (2) | 2017.03.16 |
안드로이드 람다 조합 (RxJava2 호환) (0) | 2017.03.08 |
조금 더 구체적인 안드로이드 개발 패턴화 (2) | 2017.01.30 |