문제 설명

접속자가 많을 때는 서버를 많이, 접속자가 적을 때에는 서버를 적게 띄워야 합니다. 배달의 민족에서는 각 시간대에 발생한 로그 수를 파악해 미래에 서버를 몇 대 띄울지 계산하려 합니다. 로그는 YYYY/MM/DD hh:mm:ss 형식으로 표시되며, 한국은 UTC+09:00 시간대이므로 로그에 표시된 시각에서 9시를 더해야 올바른 한국 시각이 나옵니다.

예를 들어 2019/10/01 09:33:19 로그는 한국 기준, 2019년 10월 1일 18시 33분 19초에 발생한 로그입니다.
로그 발생 시각을 담은 문자열 logs가 매개변수로 주어졌을 때 0시부터 23시까지, 한국 시간 기준 각 시간대별로 로그가 몇 회씩 발생했는지 return 하도록 메서드를 완성해주세요.

제한 사항

  • 발생 시각은 개행(\n) 문자로 구분되어있습니다.
  • 발생 시각은 10개 이상 100개 이하로 주어집니다.
  • 발생 시각은 YYYY/MM/DD hh:mm:ss 형식이며 24시 표시법을 따릅니다.
  • 연도는 2011 이상 2019 이하 값으로만 주어집니다.
  • 잘못된 시각이 주어지는 경우(-1년 13월 55일 25시 82분 400초 등)는 없습니다.

스크린샷 2019-11-10 오후 3 31 37

 

스크린샷 2019-11-10 오후 3 31 55

풀이

package beautifultask;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;

public class PrintLogNumber {

    public static int[] solution(String[] input) {

        int[] hours = new int[24];
        Arrays.fill(hours, 0);

        DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");

        for (int i = 0; i < input.length; i++) {

            final LocalDateTime parser = LocalDateTime.parse(input[i], pattern);

            // 시간 정보만 가져옵니다.
            int hour = parser.getHour() + 9;
            hours[hour] += 1;
        }

        return hours;
    }


    public static void main(String[] args) {

        String log = "2019/05/01 00:59:19\n" +
                "2019/06/01 01:35:20\n" +
                "2019/08/01 02:01:22\n" +
                "2019/08/01 02:01:23\n" +
                "2019/08/02 03:02:35\n" +
                "2019/10/03 04:05:40\n" +
                "2019/10/04 06:23:10\n" +
                "2019/10/10 08:23:20\n" +
                "2019/10/12 08:42:24\n" +
                "2019/10/23 08:43:26\n" +
                "2019/11/14 08:43:29\n" +
                "2019/11/01 10:19:02\n" +
                "2019/12/01 11:23:10\n";

        String[] input = log.split("\n");

        int[] result = solution(input);

        for (int value : result) {
            System.out.println(value);
        }

    }
}

어제 우아한테스크코스 온라인 코딩 테스트에서 나온 2번 문제입니다. 한국 시간 기준 각 시간대별로 로그가 몇 회씩 발생했는지 배열 타입으로 return 하는 것이 핀트입니다.

이 문제를 분석하면서 출제자의 의도를 분석을 해보면서 해당 날짜 관련 데이터에서 얼마나 잘 핸들링 할 수 있는지 파악하는것이 목적이 아닐까.. 조심스럽게 생각해봤습니다.
평상시에 날짜, 시간과 관련된 객체를 다루어 본 경험이 있으시다면 그렇게 어렵지 않는 문제였습니다.

먼저, 문자열 변수에 들어있는 날짜 데이터들을 \n을 구분자로 문자열 타입 배열로 변환해주고 처리하는게 가장 처리하기 쉬운거 같습니다.

두번째로는 아래와 같이 java.time.format 패키지에서 제공해주는 DateTimeFormatter 클래스를 사용하여 ofPattern 메서드로 출력형식으로 원하는 날짜 포맷을 지정해줍니다.

DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); 

주의사항: yyyy/MM 은 대소문자 구분 없이 연,월을 표현하지만, dd,HH,ss는 대소문자에 따라 출력형식이 달라집니다.
DD는 년의 몇 번째 일(1 ~366), dd는 월의 몇 번째 일(1~31), HH는 시간(0~23), hh 시간(1~12), SS(1/1000초) ss는 초(0~59)를 의미합니다.

마지막으로 자바 1.8부터 제공해주는 날짜와 관련된 클래스인 LocalDateTime 객체의 parse() 메서드를 사용하여 날짜 데이터가 들어있는 문자열 타입의 배열을 꺼내와서 이전에 DateTimeFormatter으로 지정한 출력형식으로 파싱을 하여 LocalDateTime 객체를 얻어옵니다.

LocalDateTime parser = LocalDateTime.parse(input[i], pattern);

이제 날짜, 시간 등 원하는 대로 처리 할 수 있습니다.

아래는 자바 1.8 버전부터 제공해주는 날짜 관련 객체와 메소드에 대한 정보가 나와있는 참조 사이트입니다. 아래 개발자분들이 올려주신 정보는 저에게 정말 많은 도움이 되었습니다.

참조: https://lovefields.github.io/java/2017/06/15/post76.html, https://jekalmin.tistory.com/entry/%EC%9E%90%EB%B0%94-18-%EB%82%A0%EC%A7%9C-%EC%A0%95%EB%A6%AC

+ Recent posts