서버의 시간(feat. 타임스탬프)

squareBird·2022년 6월 23일
0

타임스탬프(TimeStamp)

IT와 관련된 공부를 진행하다 보면 타임 스탬프라는 단어를 접할 수 있다.
그대로 직역하면 시간 도장 이라는 의미인데 말 그대로 특정한 시점에 도장을 찍는다고 보면 될 것 같다.

IT 에서는 일이 발생해서 컴퓨터에 기록된 시간을 의미하는데, 주로 어떤 일이 발생한 시간을 비교하거나 두 작업 사이에 어느정도의 시간이 경과되었는지를 알아내기 위해 사용한다.


GMT와 UTC

타임스탬프를 알기 위해서는 GMTUTC라는 용어를 알 필요가 있다.

1. GMT(Greenwich Mean Time)

GMT란 그리니치 천문대에서 측정한 평균태양시를 의미한다.

과거에 태양의 움직임 즉 지구의 자전과 공전을 기준으로 시간을 결정한 것이다.
지구의 운동에서 하루의 평균 길이를 결정하고 여기서 1/24를 1시간으로, 1시간의 1/60을 1분으로, 1분의 1/60을 1초라고 정의한 것이다.

그런데, 과학이 발전하면서 골치아픈 문제가 발생했다.
지구의 자전속도가 일치하지 않는다는 것을 발견한 것이다.

이로인해 지구의 움직임 외에 다른 무언가를 기준으로 시간을 측정할 필요가 생겼다.

2. UTC(Coordinated Universal Time)

지구의 움직임을 통해 시간을 측정하는 방식에 문제가 생기자 대안으로 나타난 것이 원자의 움직임을 통해 시간을 측정하는 방식이다.

원자는 바닥상태와 들뜬 상태를 반복하며 에너지를 방출할 때 그 주기가 일정한데, 이 특성을 이용하여 시간을 측정하는 기준으로 활용한 것이다.

이렇게 태양의 움직임 대신에 원자 시계를 기준으로 세운 시간 체계를 원자시라고 하며, 전세계에 400여개의 원자시계를 설치하여 시간의 오차를 보정하고 있는데, 이렇게 세계 각지에 흩어진 원자 시계를 통해 보정되는 시간 체계를 국제원자시라고 한다.

원자를 기준으로 시간을 측정하면 1초보다 훨씬 적은 단위로 측정이 가능하다.

하지만, 일상 생활에서는 1초 미만의 단위를 다루는 것은 쉽지 않기 때문에 국제 원자시를 바탕으로 1초단위의 시간까지만 맞춰 놓은 것을 UTC라고 한다.


Java에서의 타임스탬프

Java의 패키지에는 Timestamp라는 클래스가 존재한다.

위의 그림은 Timestamp 클래스의 일부이다.

java.util.Date를 상속해 만든것을 알 수 있고, @Deprecated 어노테이션이 붙어있는 생성자를 보면 과거에는 int 타입의 년도, 월, 일, 시간, 분 등의 파라미터를 입력해서 인스턴스를 생성했지만 이제 곧 해당 생성자를 지원하지 않는다는 것을 알 수 있다.

@Deprecated 어노테이션이 붙어있는 생성자 아래에는 long 타입 변수를 파라미터로 받는 생성자를 확인할 수 있다.

해당 생성자는 super메소드를 이용해 Date 클래스에 있는 fastTime이라는 변수값을 수정한다.

이 때 생성자에 전달하는 파라미터는 위의 시간값이라는 것을 알 수 있다.

아래에는 친절하게 System.currentTimeMills 메소드를 예시로 들어주까지 했다.

이제 실제로 해당 클래스를 사용해 타임스탬프 값을 확인해보자.

Timestamp의 생성자에 들어갈 변수 값은 위에서 제시한 System.currentTimeMills 메소드를 통해 구해준다.

해당 메소드는 현재 시간과 1970년 1월 1일 자정과의 차이를 밀리세컨드(1/1000초) 값으로 반환한다.

import java.sql.Timestamp;

public class TimestampSample {

    public static void main(String[] args) {

		Long datetime = System.currentTimeMillis();
        Timestamp timestamp = new Timestamp(datetime);
        
        System.out.println("Datetime = " + datetime);
        System.out.println("Timestamp: "+timestamp);
        
    }
}

System.currentTimeMills 메소드를 통해 구한 시간 값과 Timestamp 클래스를 통해 구한 시간값을 출력해보겠다.

두 값이 서로 다르다는 것을 알 수 있다.

먼저 Datetime은 현재 시간과 1970년 1월 1일 자정과의 차이를 밀리세컨드(1/1000초) 값으로 반환한 것이다.

다음으로 Timestamp의 값은 위의 시간을 이용해 우리가 아는 시간의 포맷으로 변경한 것이다.


타임스탬프 값은 어떻게 구할까?

그렇다면 해당 Timestamp 값을 구하는 과정을 살펴보자.

import java.sql.Timestamp;

public class TimestampSample {

    public static void main(String[] args) {

		Long datetime = System.currentTimeMillis();
        Timestamp timestamp = new Timestamp(datetime);
        
        System.out.println("Datetime = " + datetime);
        System.out.println("Timestamp: "+timestamp);
        
    }
}

다시 예제 코드를 보면 Timestamp 값을 출력하는 부분이 객체명을 통해 그대로 출력되는 것을 볼 수 있다.
이를 통해 Timestamp 클래스에는 toString메소드가 오버라이딩 되어 있다는 것을 알 수 있다.

해당 메소드의 일부분이다.

super를 통해 상속받은 클래스로부터 년도, 월, 시간 등을 받아오는 것을 볼 수 있다.

대표적으로 year 값을 받아오는 부분을 보면 Date 클래스의 getYear 메소드에서 1900을 빼주고 Timestamp 클래스의 toString 메소드에서 1900을 더해주므로 year 값을 구하고 있다.

나머지 month, day, hour 등의 변수들도 Date 클래스에 있는 밀리세컨드로 표현한 현재 시간값에 일정한 보정을 하여 년, 월, 일, 시간 등의 값을 가져오는 것을 알 수 있다.


1970년 1월 1일 자정

위의 Date 클래스의 생성자를 보면 파라미터로 1970년 1월 1일의 자정을 기준으로 하는 값을 받는 것을 알 수 있다.

그런데 1970년 1월 1일의 자정에는 무슨 의미가 있을까?


UNIX 시간

결론부터 말하면 UTC시간을 기준으로 1970년 1월 1일 자정UNIX 시간의 기준이 되는 시간이다.

UNIX 시간이란 유닉스 계열의 운영체제를 사용하는 컴퓨터에서 시간을 표시하는데 사용되는 방식인데 1970년 1월 1일 자정부터 현재까지 얼마나 시간이 흘렀는지를 정수로 나타낸다.

말 그대로 UNIX에서 기준이 되는 시간이기 때문에 알게모르게 꽤나 자주 보는 시간이기도 하다.

2038년 문제

2038년 문제UNIX 시간32bit 정수형을 사용하는 서버들에서 나타나게 될 크리티컬한 문제이다.

32bit의 정수형은 양수로 0~2^31-1 범위의 값을 나타낼 수 있다.

그런데 2^31-1에서 1초가 더 지나면 바이너리 값이 01111111 11111111 11111111 11111111에서 10000000 00000000 00000000 00000000으로 변경되면서 음수값이 된다.


profile
DevOps...

0개의 댓글