DateTime & DateTimeOffset (System.DateTime & System.DateTimeOffset)
// DateTime and DateTimeOffset (.NET 3.5)
// 날짜와 시간을 나타내는 불변이 구조체
// 해상도: 100ns
// 범위: 0001년 ~ 9999년
// DateTime 객체 생성
// 내부 저장 데이터
// 1. 0001-01-01에서부터 흐른 틱 수를 뜻하는 62비트 수치
// 2. DateTimeKind를 나타내는 2비트 열거형 값
DateTime[] dt =
{
// 기본값
// 시간: 00:00:00:000
// DateTimeKind: Unspecified
// 캘린더: GregorianCalendar
// 틱 (100ns)
new DateTime(625000000000000000),
// 년, 월, 일
new DateTime(2017, 6, 26),
// 년, 월, 일, 시, 분, 초, 밀리초
new DateTime(2017, 6, 26, 13, 26, 30, 100),
// 년, 월, 일, 시, 분, 초, 밀리초, UTC 시간대
new DateTime(2017, 6, 26, 13, 26, 30, 100, DateTimeKind.Utc),
// 히브리력 5767년 1월 1일
new DateTime(5767, 1, 1, new System.Globalization.HebrewCalendar()),
// 단기 4350년 2월 2일 13시 26분 30초 100밀리초, UTC
// 밀리초까지 기입하면 Calendar와 DateTimeKind를 동시에 입력 가능
// 나머지 생성자는 Calendar를 넣거나 DateTimeK
new DateTime(4350, 2, 2, 13, 26, 30, 100, new System.Globalization.KoreanCalendar(), DateTimeKind.Utc),
};
// 내용 출력
foreach (var item in dt)
{
Console.WriteLine(item);
}
Console.WriteLine();
// DateTime이 가진 DateTimeKind 값
Console.WriteLine(dt[0].Kind);
Console.WriteLine();
// DateTime <-> Windows 파일 시간(long)
long ft = dt[2].ToFileTime();
long ftUtc = dt[2].ToFileTimeUtc();
DateTime cdt = DateTime.FromFileTime(ft);
DateTime cdtUtc = DateTime.FromFileTimeUtc(ftUtc);
Console.WriteLine(ft);
Console.WriteLine(ftUtc);
Console.WriteLine(cdt);
Console.WriteLine(cdtUtc);
Console.WriteLine();
// DateTime <-> OLE 자동화/시간(double)
double olet = dt[2].ToOADate();
DateTime cdt2 = DateTime.FromOADate(olet);
Console.WriteLine(olet);
Console.WriteLine(cdt2);
Console.WriteLine();
// DateTime <-> String
string dtString = dt[2].ToString();
DateTime cdt3 = DateTime.Parse(dtString);
Console.WriteLine(dtString);
Console.WriteLine(cdt3);
Console.WriteLine();
// DateTimeOffset 객체 생성
// 내부 저장 데이터
// 1. DateTime (UTC)
// 2. 16비트 정수: 분 단위 UTC Offset
DateTimeOffset[] dto =
{
// 년, 월, 일, 시간을 생략하는 생성자는 없음
// TimeSpan은 최소 분 단위로 입력해줘야 함
// 틱 (100ns)
new DateTimeOffset(625000000000000000, TimeSpan.FromHours(0)),
// 년, 월, 일, 시, 분, 초, 오프셋
new DateTimeOffset(2017, 6, 26, 13, 26, 30, TimeSpan.FromHours(5)),
// 년, 월, 일, 시, 분, 초, 밀리초, 오프셋
new DateTimeOffset(2017, 6, 26, 13, 26, 30, 100, TimeSpan.FromHours(0)),
// 년, 월, 일, 시, 분, 초, 밀리초, 캘린더, 오프셋
new DateTimeOffset(4350, 6, 26, 13, 26, 30, 100, new System.Globalization.KoreanCalendar(), TimeSpan.FromHours(5)),
// DateTime에서 복사해오기
// offset은 생략 가능. 기본 값은 -
// 1. DateTimeKind가 Utc면 offset은 0
// 2. DateTimeKind가 Local이나 Unspecified면 현재 지역 시간대의 오프셋
// 오프셋을 생략
new DateTimeOffset(dt[2]),
// 오프셋을 지정
new DateTimeOffset(dt[2], TimeSpan.FromHours(5))
};
// DateTime에서 이렇게 복사해올 수도 있다
// DateTimeOffset.Implicit Operator
DateTimeOffset dto2 = dt[2];
// 내용 출력
foreach (var item in dto)
{
Console.WriteLine(item);
}
Console.WriteLine();
// Parse, ParseExact, FromFileTime 있음
DateTimeOffset dtoParse = DateTimeOffset.Parse("2017-06-26 13:26:30 +01:00");
//DateTimeOffset dtoParsed2 = DateTimeOffset.ParseExact();
DateTimeOffset dtoFromFileTime = DateTimeOffset.FromFileTime(ft);
Console.WriteLine(dtoParse);
Console.WriteLine(dtoFromFileTime);
Console.WriteLine();
// 현재 DateTime/DateTimeOffset
// 정밀도: OS에 따라 다름. 대체로 10~20ms
// Now - 현재 날짜 및 시간
Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTimeOffset.Now);
Console.WriteLine();
// Today - 현재 날짜만, DateTime에만 있음
Console.WriteLine(DateTime.Today);
Console.WriteLine();
// UtcNow - UTC 기준 현재 날짜 및 시간
Console.WriteLine(DateTime.UtcNow);
Console.WriteLine(DateTimeOffset.UtcNow);
Console.WriteLine();
// 날짜와 시간 다루기
// 값 받아오기
Console.WriteLine(DateTime.Now.Year); // 년
Console.WriteLine(DateTime.Now.Month); // 월
Console.WriteLine(DateTime.Now.Day); // 일
Console.WriteLine(DateTime.Now.DayOfWeek); // 요일
Console.WriteLine(DateTime.Now.DayOfYear); // 주차(년에서)
Console.WriteLine(DateTime.Now.Hour); // 시간
Console.WriteLine(DateTime.Now.Minute); // 분
Console.WriteLine(DateTime.Now.Second); // 초
Console.WriteLine(DateTime.Now.Millisecond); // 밀리초
Console.WriteLine(DateTime.Now.Ticks); // 틱
Console.WriteLine(DateTime.Now.TimeOfDay); // TimeSpan (자정으로부터 지난 시간)
Console.WriteLine(DateTimeOffset.Now.Offset); // TimeSpan, 오프셋 (DateTimeOffset Only)
Console.WriteLine();
// 값 더하기(음수를 더한다면 빼기)
Console.WriteLine(dt[2]);
dt[2] = dt[2].AddYears(1); // 년
dt[2] = dt[2].AddMonths(-2); // 월
dt[2] = dt[2].AddDays(3); // 일
dt[2] = dt[2].AddHours(-4); // 시간
dt[2] = dt[2].AddMinutes(5); // 분
dt[2] = dt[2].AddSeconds(-6); // 초
dt[2] = dt[2].AddMilliseconds(7); // 밀리초
dt[2] = dt[2].AddTicks(-8); // 틱
Console.WriteLine(dt[2]);
TimeSpan ts = TimeSpan.FromMinutes(90);
dt[2] = dt[2].Add(ts); // Timespan
dt[2] = dt[2] + ts; // Timespan (위와 동일)
Console.WriteLine(dt[2]);
Console.WriteLine();
// 더하기는 안 되고 마이너스는 됨
// 두 DateTime(DateTimeOffset)의 차는 TimeSpan
ts = dt[2] - dt[3];
Console.WriteLine(ts);
Console.WriteLine();
// 파싱과 서식화
// ToString
Console.WriteLine(dt[2]);
Console.WriteLine(dto[2]);
Console.WriteLine();
// 서식화가 다른 ToString들 (DateTime Only)
Console.WriteLine(dt[2].ToShortDateString());
Console.WriteLine(dt[2].ToLongDateString());
Console.WriteLine();
// Parse, TryParse, ParseExact, TryParseExact
// ToString의 반대, String -> DateTime(Offset)
// 널 값을 가진 DateTime과 DateTimeOffset
DateTime? dtn = null;
DateTimeOffset? dton = null;
if (dtn == null)
{
Console.WriteLine("dtn is null");
}
if (dton == null)
{
Console.WriteLine("dton is null");
}
Console.WriteLine();
// DateTime과 시간대
// 두 DateTime을 비교할 때는 틱 수만 비교하고, DateTimeKind는 무시한다.
// 따라서 아래 두 시간대를 비교하면 True로 표시된다.
DateTime dtLocal = new DateTime(2015, 1, 1, 10, 20, 30, DateTimeKind.Local);
DateTime dtUtc = new DateTime(2015, 1, 1, 10, 20, 30, DateTimeKind.Utc);
DateTime dtUnspecified = new DateTime(2015, 1, 1, 10, 20, 30);
Console.WriteLine(dtLocal);
Console.WriteLine(dtUtc);
Console.WriteLine(dtLocal == dtUtc);
Console.WriteLine();
// Local과 Unspecified에 대해 ToUniversalTime (Local -> UTC),
// UTC에 Unspecified에 대해 ToLocalTime (UTC -> Local),
// 위 행위는 값을 변화시킨다.
Console.WriteLine(dtLocal.ToUniversalTime());
Console.WriteLine(dtUnspecified.ToUniversalTime());
Console.WriteLine(dtUtc.ToLocalTime());
Console.WriteLine(dtUnspecified.ToLocalTime());
Console.WriteLine();
// SpecifyKind를 사용하면 주어진 DateTime은 그대로 두고
// Kind만 다른 새 DateTime을 생성 가능
Console.WriteLine(DateTime.SpecifyKind(dtLocal, DateTimeKind.Utc));
Console.WriteLine();
// DateTimeOffset과 시간대
// 두 DateTimeOffset을 비교할 때는 DateTime(UTC)만 비교하고, Offset은 무시한다.
// DateTimeOffset은 생성 당시에 Offset에 의해 UTC를 기준으로 변동되기 때문에
// 아래 두 시간대를 비교하면 False로 표시된다.
DateTimeOffset dtoLocal = new DateTimeOffset(2015, 1, 1, 10, 20, 30, TimeSpan.FromHours(9));
DateTimeOffset dtoUtc = new DateTimeOffset(2015, 1, 1, 10, 20, 30, TimeSpan.FromHours(0));
Console.WriteLine(dtoLocal);
Console.WriteLine(dtoUtc);
Console.WriteLine(dtoLocal == dtoUtc);
Console.WriteLine();
// ToUniversalTime, ToLocalTime은 DateTime과는 달리
// offset을 변화시키지만 DateTime(UTC)에는 영향을 끼치지 않는다.
// 아래 두 시간대를 비교하면 True로 표시된다.
DateTimeOffset dtoLocalNow = DateTimeOffset.Now;
DateTimeOffset dtoUtcNow = dtoLocalNow.ToUniversalTime();
Console.WriteLine(dtoLocalNow);
Console.WriteLine(dtoUtcNow);
Console.WriteLine(dtoLocalNow == dtoUtcNow);
Console.WriteLine();
// EqualsExact - 오프셋까지 고려한 비교
Console.WriteLine(dtoLocalNow.EqualsExact(dtoUtcNow));
Console.WriteLine();
// 일광절약시간제와 DateTime
Console.WriteLine(DateTime.Now.IsDaylightSavingTime());
Console.WriteLine(DateTime.UtcNow.IsDaylightSavingTime());
Console.WriteLine(DateTimeOffset.Now.LocalDateTime.IsDaylightSavingTime());
'C#' 카테고리의 다른 글
[C#] 표준 서식 문자열과 파싱 플래그 (1) | 2023.08.13 |
---|---|
[C#] TimeZoneInfo.AdjustmentRule & TimeZoneInfo.TransitionTime (1) | 2023.08.12 |
[C#] TimeZoneInfo (1) | 2023.08.11 |
[C#] TimeZone (1) | 2023.08.10 |
[C#] TimeZoneInfo (2) | 2023.07.05 |
[C#] TimeZone (1) | 2023.07.04 |
[C#] TimeSpan (1) | 2023.07.01 |
[C#] Encoding (1) | 2023.06.30 |