c# DateTime과 TimeSpan으로 날짜와 시간 제어하기

DateTime

.네트의 날짜와 시간은 델파이의 그것들에 비하면 좀 특이하다. 델파이의 날짜와 시간은 모두 double인데 .네트의 DataTime은 구조체이며 이거로는 제어를 충분히 할 수 없어서 TimeSpan이라는 구조체도 같이 써야 한다. DateTime은 시점이고 TimeSpan은 길이다. double에 비해 구조체의 용량이 더 크고 작동에도 부하가 크겠지만 그 차이가 얼마나 될지는 모르겠다. .네트의 구조체는 인스턴스가 만들어진 때 그 크기가 특정되지 않으므로 크기도 단순하게 비교하기 어렵다.

TimeSpan

델파이의 경우 날짜와 시간은 double이므로 예를 들어 09:00:00에 1분을 더하려면 각각의 값을 double로 환산하여 더하면 된다. .네트로는 DateTime.AddMinutes 메떠드를 이용할 수 있고 TimeSpan 객체를 new로 만들어서 DateTime에 더하거나 TimeSpan.FromMinutes로 값을 만들어서 더할 수도 있다. TimeSpan을 만들어서 이용하는 거는 한 단계를 더 거치므로 아무래도 DateTime의 메떠드를 이용하는 거보다는 느리며 그 정도도 꽤 크다. 예를 들어 분을 뺄 때에는 빼는 메떠드가 따로 있지는 않으므로 AddMinutes에 음수를 입력해야 한다.

문자열 변환

예를 들어 이베스트투자증권의 api로 데이터를 받으면 시간은 090000, 날짜는 20230101의 형태로 되어 있다. 문자열을 날짜나 시간으로 바꾸는 메떠드인 Convert.ToDateTime은 09:00:00처럼 되어 있어야 작동하며 그렇지 않은 090000 같은 문자열은 처리하지 못한다. 아래와 같이 DateTime.ParseExact를 써야 한다. 날짜의 달은 대문자 M으로 하지 않으면 처리되지 않는다.

DateTime time = DateTime.ParseExact("090000", "hhmmss", null);

초 미만의 단위로는 millisecond, nanosecond, tick이 있다. 초 미만의 값을 갖지 않는 시간을 ToString()으로 출력하면 초까지만 출력되지만 초 미만의 값을 갖는 시간을 출력하면 hh:mm:ss.fffffff로 천만 단위까지 출력된다. f는 fraction을 의미하며 ‘부분’, ‘분수’라는 뜻이다. 초 미만 단위를 출력하지 않기 위해 그냥 ToString(“hh:mm:ss”)로만 하면 오류로 처리된다. 초 미만 단위를 출력하지 않으려면 custom TimeSpan format strings를 써야 한다. 각 단위를 구분하는 문자 앞에 \를 쓰면 원하는 포맷으로 만들 수 있다. ToString(@”hh\.mm\:ss”)라고 하면 hh.mm:ss의 형태로 출력이 된다. “hh\\:mm\\:ss”라고 하면 hh:mm:ss라고 나온다. @나 \를 이용하는 건 특수 문자가 포함된 문자열을 제어할 때 날짜나 시간의 경우 아니라도 일반적으로 이용되는 방법인데 자세한 내용은 아래와 같다.

버버팀과 이스케이프 씨퀀스

@를 verbatim 문자라 한다. verbatim은 ‘문자 그대로’라는 뜻으로 literal과 같은 의미다. 예를 들어 \를 출력하기 위해 Text = “\”라고 하면 오류로 처리된다. 여기에서 \는 이스케이프 씨퀀스를 만드는 특별한 의미를 갖는 문자이기 때문이다. 이럴 때 그 앞에 \를 하나 더 붙이거나 문자열 앞에 @를 붙이면 문자 그대로 처리하라는 의미가 된다. “\\” 또는 @”\” 이렇게 말이다. 보통은 버버팀을 이용한 후자의 방법이 원래의 문자 또는 문자열을 간섭하지 않아서 읽기 편하다.

위와 같이 \를 다른 문자 앞에 붙여서 쓰는 거는 escape sequence라고 한다. sequence는 ‘연속된다’는 뜻이고 여기에서는 탈출 문자열이라는 의미다. 일반적인 문자열 처리에서 벗어난 제어를 할 때 쓰기 때문에 그런 이름을 갖는다. 그 뒤에 오는 문자에 따라 다양한 기능들을 한다.