System.DateTime 구조체

이 문서에서는 이 API에 대한 참조 설명서에 대한 추가 설명서를 제공합니다.

Important

일본어 달력의 시대는 천황 통치 기간을 기준으로 하므로 변경되어야 합니다. 예를 들어 2019년 5월 1일은 JapaneseCalendarJapaneseLunisolarCalendar에서 레이와 시대의 시작을 나타냅니다. 이러한 시대 변경 내용은 해당 달력을 사용하는 모든 애플리케이션에 영향을 줍니다. 자세한 내용과 애플리케이션이 영향을 받는지 여부를 확인하려면 .NET의 일본 달력에서 새 시대 처리를 참조하세요. Windows 시스템에서 애플리케이션을 테스트하여 시대 변화에 대한 준비 상태를 확인하는 방법에 대한 자세한 내용은 일본 시대 변경을 위한 애플리케이션 준비를 참조하세요. 여러 연대가 있는 달력을 지원하는 .NET의 기능과 여러 연대를 지원하는 달력으로 작업할 때 모범 사례는 연대 작업(Working with era)을 참조 하세요.

개요

값 형식은 DateTime 9999년 12월 31일 오후 11시 59분 59분(C.E.)까지의 값이 00:00:00(자정), 0001년 1월 1일 안노 도미니(일반 시대)부터 9999년 12월 31일(C.E.) 사이의 값을 가진 날짜 및 시간을 나타냅니다.

시간 값은 틱이라고 하는 100나노초 단위로 측정됩니다. 특정 날짜는 달력의 0001년 1월 1일 자정 12:00(C.E.) GregorianCalendar 이후의 틱 수입니다. 이 숫자는 윤초에 추가될 틱을 제외합니다. 예를 들어 틱 값 3124137600000000000L은 0100년 1월 1일 금요일 12:00:00 자정 날짜를 나타냅니다. DateTime 값은 항상 명시적 또는 기본 달력의 컨텍스트에서 표현됩니다.

참고 항목

분 또는 초와 같은 다른 시간 간격으로 변환하려는 틱 값을 사용하는 경우 변환을 수행하려면 , TimeSpan.TicksPerHour, TimeSpan.TicksPerSecondTimeSpan.TicksPerMinute또는 TimeSpan.TicksPerMillisecond 상수로 사용해야 TimeSpan.TicksPerDay합니다. 예를 들어 지정된 틱 Second 수로 표시되는 시간(초)을 값의 DateTime 구성 요소에 추가하려면 식을 dateValue.Second + nTicks/Timespan.TicksPerSecond사용할 수 있습니다.

Visual Basic, F# 또는 C#에서 이 문서의 전체 예제 집합에 대한 원본을 볼 수 있습니다.

참고 항목

특정 표준 시간대의 DateTime 날짜 및 시간 값을 사용하기 위한 구조체의 대안은 구조체 DateTimeOffset 입니다. 구조체는 DateTimeOffset 날짜 및 시간 정보를 개인 DateTime 필드에 저장하고 해당 날짜와 시간이 개인 Int16 필드의 UTC와 다른 시간(분)을 저장합니다. 이렇게 하면 DateTimeOffset 값이 특정 표준 시간대의 시간을 반영할 수 있는 반면 DateTime 값은 UTC 및 현지 표준 시간대의 시간만 명확하게 반영할 수 있습니다. 날짜 및 시간 값을 사용할 때 구조 또는 구조를 사용하는 DateTime 시기에 대한 자세한 내용은 DateTime, DateTimeOffset, TimeSpan 및 TimeZoneInfo 중에서 선택 항목을 참조 DateTimeOffset 하세요.

참고 항목

이 문서의 일부 C# 예제는 Try.NET 인라인 코드 실행기 및 플레이그라운드에서 실행됩니다. 대화형 창에서 예제를 실행하려면 실행 버튼을 선택합니다. 코드를 실행하면 실행을 다시 선택하여 코드를 수정하고 수정된 코드를 실행할 수 있습니다. 수정된 코드는 대화형 창에서 실행되거나, 컴파일이 실패하면 대화형 창에 모든 C# 컴파일러 오류 메시지가 표시됩니다.

Try.NET 인라인 코드 러너와 플레이그라운드의 현지 표준 시간대는 협정 세계시(또는 UTC)입니다. 이는 DateTime, DateTimeOffsetTimeZoneInfo 형식과 이러한 형식의 멤버를 보여주는 예제의 동작 및 출력에 영향을 줄 수 있습니다.

이 문서에는 형식을 사용하는 몇 가지 예제가 DateTime 포함되어 있습니다.

초기화 예제

개체를 문자열로 서식 DateTime 지정 예제

문자열을 개체 예제로 DateTime 구문 분석

DateTime 해결 방법 예제

문화권 및 달력 예제

지속성 예제

DateTime 개체 초기화

여러 가지 방법으로 새 DateTime 값에 초기 값을 할당할 수 있습니다.

  • 값에 대한 인수를 지정하거나 암시적 매개 변수 없는 생성자를 사용하는 생성자를 호출합니다.
  • DateTime 속성 또는 메서드의 반환 값에 할당
  • DateTime 문자열 표현에서 값을 구문 분석합니다.
  • Visual Basic 관련 언어 기능을 DateTime사용하여 .

다음 코드 조각은 각각에 대한 예제를 보여 줍니다.

생성자 호출

날짜 및 시간 값의 DateTime 요소(예: 연도, 월, 일 또는 틱 수)를 지정하는 생성자의 오버로드를 호출합니다. 다음 코드는 연도, 월, 일, 시간, 분 및 초를 지정하는 생성자를 사용하여 DateTime 특정 날짜를 만듭니다.

Dim date1 As New Date(2008, 5, 1, 8, 30, 52)
var date1 = new DateTime(2008, 5, 1, 8, 30, 52);
Console.WriteLine(date1);
let date1 = DateTime(2008, 5, 1, 8, 30, 52)
printfn $"{date1}"

기본값으로 DateTime 초기화하려는 DateTime 경우 구조체의 암시적 매개 변수 없는 생성자를 호출합니다. (값 형식의 암시적 매개 변수 없는 생성자에 대한 자세한 내용은 다음을 참조하세요 .값 형식.) 일부 컴파일러에서는 값을 명시적으로 할당하지 않고도 값 선언 DateTime 을 지원합니다. 명시적 초기화 없이 값을 만들면 기본값도 생성됩니다. 다음 예제에서는 C# 및 Visual Basic의 DateTime 암시적 매개 변수 없는 생성자와 Visual Basic에서 할당이 없는 선언을 DateTime 보여 줍니다.

Dim dat1 As DateTime
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat1.Equals(Date.MinValue))

Dim dat2 As New DateTime()
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat2.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat2.Equals(Date.MinValue))
var dat1 = new DateTime();
// The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture));
// The following method call displays True.
Console.WriteLine(dat1.Equals(DateTime.MinValue));
let dat1 = DateTime()

// The following method call displays 1/1/0001 12:00:00 AM.
printfn $"{dat1.ToString System.Globalization.CultureInfo.InvariantCulture}"

// The following method call displays True.
printfn $"{dat1.Equals DateTime.MinValue}"

계산 값 할당

속성 또는 메서드에서 반환된 DateTime 날짜 및 시간 값을 개체에 할당할 수 있습니다. 다음 예제에서는 현재 날짜 및 시간, 현재 UTC(협정 세계시) 날짜 및 시간 및 현재 날짜를 세 개의 새 DateTime 변수에 할당합니다.

Dim date1 As Date = Date.Now
Dim date2 As Date = Date.UtcNow
Dim date3 As Date = Date.Today
DateTime date1 = DateTime.Now;
DateTime date2 = DateTime.UtcNow;
DateTime date3 = DateTime.Today;
let date1 = DateTime.Now
let date2 = DateTime.UtcNow
let date3 = DateTime.Today

DateTime을 나타내는 문자열 구문 분석

, ParseExact, TryParseTryParseExact 메서드는 Parse모두 문자열을 해당하는 날짜 및 시간 값으로 변환합니다. 다음 예제에서는 문자열 및 ParseExact 메서드를 사용하여 Parse 문자열을 구문 분석하고 값으로 DateTime 변환합니다. 두 번째 형식은 문자열 형식의 날짜 및 시간을 나타내는 ISO 8601 표준에서 지원하는 양식을 사용합니다. 이 표준 표현은 종종 웹 서비스에서 날짜 정보를 전송하는 데 사용됩니다.

Dim dateString As String = "5/1/2008 8:30:52 AM"
Dim date1 As Date = Date.Parse(dateString,
                       System.Globalization.CultureInfo.InvariantCulture)
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As Date = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                              System.Globalization.CultureInfo.InvariantCulture)
Console.WriteLine(dateISO8602)
var dateString = "5/1/2008 8:30:52 AM";
DateTime date1 = DateTime.Parse(dateString,
                          System.Globalization.CultureInfo.InvariantCulture);
var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                                System.Globalization.CultureInfo.InvariantCulture);
let dateString = "5/1/2008 8:30:52 AM"
let date1 = DateTime.Parse(dateString, System.Globalization.CultureInfo.InvariantCulture)
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

TryParseExact 메서드는 TryParse 문자열이 값의 DateTime 유효한 표현인지 여부를 나타내며, 값인 경우 변환을 수행합니다.

Visual Basic에 대한 언어별 구문

다음 Visual Basic 문은 새 DateTime 값을 초기화합니다.

Dim date1 As Date = #5/1/2008 8:30:52AM#

DateTime 값 및 해당 문자열 표현

내부적으로 모든 DateTime 값은 0001년 1월 1일 자정 12:00:00 이후 경과된 틱 수(100나노초 간격 수)로 표시됩니다. 실제 DateTime 값은 해당 값이 표시될 때 나타나는 방식과 독립적입니다. 값의 DateTime 모양은 값을 문자열 표현으로 변환하는 서식 지정 작업의 결과입니다.

날짜 및 시간 값의 모양을 문화권, 국제 표준, 애플리케이션 요구 사항 및 개인 기본 설정에 따라 달라 집니다. 이 구조는 DateTime 오버로드를 통해 날짜 및 시간 값의 ToString서식을 유연하게 지정할 수 있습니다. 기본 DateTime.ToString() 메서드는 현재 문화권의 짧은 날짜 및 긴 시간 패턴을 사용하여 날짜 및 시간 값의 문자열 표현을 반환합니다. 다음 예제에서는 기본 DateTime.ToString() 메서드를 사용합니다. 현재 문화권의 짧은 날짜 및 긴 시간 패턴을 사용하여 날짜와 시간을 표시합니다. en-US 문화권은 예제가 실행된 컴퓨터의 현재 문화권입니다.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString());
// For en-US culture, displays 3/1/2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"{date1.ToString()}"
// For en-US culture, displays 3/1/2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString())
' For en-US culture, displays 3/1/2008 7:00:00 AM

서버가 클라이언트와 다른 문화권에 있을 수 있는 웹 시나리오를 지원하려면 특정 문화권의 날짜 서식을 지정해야 할 수 있습니다. 메서드를 사용하여 DateTime.ToString(IFormatProvider) 특정 문화권에서 짧은 날짜 및 장시간 표현을 만드는 문화권을 지정합니다. 다음 예제에서는 fr-FR 문화권에 대 한 짧은 날짜 및 긴 시간 패턴을 사용 하 여 날짜와 시간을 표시 하는 메서드를 사용 합니다 DateTime.ToString(IFormatProvider) .

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 01/03/2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture "fr-FR")}"""
// Displays 01/03/2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 01/03/2008 07:00:00

다른 애플리케이션에는 다양 한 문자열 표현의 날짜 필요할 수 있습니다. 이 메서드는 DateTime.ToString(String) 현재 문화권의 서식 규칙을 사용하여 표준 또는 사용자 지정 형식 지정자가 정의한 문자열 표현을 반환합니다. 다음 예제에서는 이 메서드를 사용하여 DateTime.ToString(String) 예제가 실행된 컴퓨터의 현재 문화권인 en-US 문화권에 대한 전체 날짜 및 시간 패턴을 표시합니다.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F"));
// Displays Saturday, March 01, 2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString "F"}"""
// Displays Saturday, March 01, 2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F"))
' Displays Saturday, March 01, 2008 7:00:00 AM

마지막으로 메서드를 사용하여 DateTime.ToString(String, IFormatProvider) 문화권과 형식을 모두 지정할 수 있습니다. 다음 예제에서는 이 메서드를 DateTime.ToString(String, IFormatProvider) 사용하여 fr-FR 문화권의 전체 날짜 및 시간 패턴을 표시합니다.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F", new System.Globalization.CultureInfo("fr-FR")));
// Displays samedi 1 mars 2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString("F", new System.Globalization.CultureInfo "fr-FR")}"""
// Displays samedi 1 mars 2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F", New System.Globalization.CultureInfo("fr-FR")))
' Displays samedi 1 mars 2008 07:00:00

오버로드는 DateTime.ToString(String) 사용자 지정 형식 문자열과 함께 사용하여 다른 형식을 지정할 수도 있습니다. 다음 예제에서는 웹 서비스에 자주 사용되는 ISO 8601 표준 형식을 사용하여 문자열의 서식을 지정하는 방법을 보여 줍니다. Iso 8601 형식에는 해당 표준 형식 문자열이 없습니다.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc);
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture));
// Displays 2008-03-01T07:00:00+00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
printfn $"""{date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)}"""
// Displays 2008-03-01T07:00:00+00:00
Dim date1 As DateTime = New DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture))
' Displays 2008-03-01T07:00:00+00:00

값 서식 지정 DateTime 에 대한 자세한 내용은 표준 날짜 및 시간 서식 문자열사용자 지정 날짜 및 시간 형식 문자열을 참조하세요.

문자열에서 DateTime 값 구문 분석

구문 분석에서는 날짜 및 시간의 문자열 표현을 값으로 DateTime 변환합니다. 일반적으로 날짜 및 시간 문자열 애플리케이션에 두 개의 서로 다른 사용:

  • 날짜와 시간은 다양한 형식을 사용하며 현재 문화권 또는 특정 문화권의 규칙을 반영합니다. 예를 들어, 애플리케이션 사용자에 해당 현재 문화권이 EN-US "2013 년 12 월 15" 또는 "2013 년 12 월 15 년"로 날짜 값을 입력 허용 현재 문화권이 engb인 사용자는 날짜 값을 "2013년 15월 12일" 또는 "2013년 12월 15일"로 입력할 수 있습니다.

  • 날짜 및 시간은 미리 정의된 형식으로 표시됩니다. 예를 들어, 애플리케이션으로 "20130103" 앱이 실행 되는 culture와 독립적으로 날짜를 serialize 합니다. 애플리케이션에 필요한 날짜는 현재 문화권의 간단한 날짜 형식으로 입력 합니다.

또는 TryParse 메서드를 Parse 사용하여 문화권 DateTime 에서 사용하는 공통 날짜 및 시간 형식 중 하나에서 값으로 문자열을 변환합니다. 다음 예제에서는 다양한 문화권별 형식의 날짜 문자열을 값으로 변환하는 데 사용할 TryParse 수 있는 DateTime 방법을 보여 줍니다. 현재 문화권을 영어(영국)로 변경하고 메서드를 GetDateTimeFormats() 호출하여 날짜 및 시간 문자열의 배열을 생성합니다. 그런 다음 배열의 각 요소를 메서드에 TryParse 전달합니다. 예제의 출력은 구문 분석 메서드가 각 문화권별 날짜 및 시간 문자열을 성공적으로 변환할 수 있었다는 것을 보여줍니다.

System.Threading.Thread.CurrentThread.CurrentCulture =
    System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");

var date1 = new DateTime(2013, 6, 1, 12, 32, 30);
var badFormats = new List<String>();

Console.WriteLine($"{"Date String",-37} {"Date",-19}\n");
foreach (var dateString in date1.GetDateTimeFormats())
{
    DateTime parsedDate;
    if (DateTime.TryParse(dateString, out parsedDate))
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19}");
    else
        badFormats.Add(dateString);
}

// Display strings that could not be parsed.
if (badFormats.Count > 0)
{
    Console.WriteLine("\nStrings that could not be parsed: ");
    foreach (var badFormat in badFormats)
        Console.WriteLine($"   {badFormat}");
}
// Press "Run" to see the output.
System.Threading.Thread.CurrentThread.CurrentCulture <-
    System.Globalization.CultureInfo.CreateSpecificCulture "en-GB"

let date1 = DateTime(2013, 6, 1, 12, 32, 30)
let badFormats = ResizeArray<String>()

printfn "%-37s %-19s\n" "Date String" "Date"
for dateString in date1.GetDateTimeFormats() do
    match DateTime.TryParse dateString with
    | true, parsedDate ->
        printfn $"%-37s{dateString} %-19O{parsedDate}\n" 
    | _ ->
        badFormats.Add dateString

// Display strings that could not be parsed.
if badFormats.Count > 0 then
    printfn "\nStrings that could not be parsed: "
    for badFormat in badFormats do
        printfn $"   {badFormat}"
// Press "Run" to see the output.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")

Dim date1 As New DateTime(2013, 6, 1, 12, 32, 30)
Dim badFormats As New List(Of String)

Console.WriteLine($"{"Date String",-37} {"Date",-19}")
Console.WriteLine()
For Each dateString As String In date1.GetDateTimeFormats()
    Dim parsedDate As DateTime
    If DateTime.TryParse(dateString, parsedDate) Then
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19:g}")
    Else
        badFormats.Add(dateString)
    End If
Next

' Display strings that could not be parsed.
If badFormats.Count > 0 Then
    Console.WriteLine()
    Console.WriteLine("Strings that could not be parsed: ")
    For Each badFormat In badFormats
        Console.WriteLine($"   {badFormat}")
    Next
End If
' The example displays the following output:
'       Date String                           Date               
'       
'       01/06/2013                            01/06/2013 00:00:00
'       01/06/13                              01/06/2013 00:00:00
'       1/6/13                                01/06/2013 00:00:00
'       1.6.13                                01/06/2013 00:00:00
'       2013-06-01                            01/06/2013 00:00:00
'       01 June 2013                          01/06/2013 00:00:00
'       1 June 2013                           01/06/2013 00:00:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       01 June                               01/06/2013 00:00:00
'       01 June                               01/06/2013 00:00:00
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       2013-06-01T12:32:30                   01/06/2013 12:32:30
'       12:32                                 22/04/2013 12:32:00
'       12:32                                 22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       2013-06-01 12:32:30Z                  01/06/2013 05:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 07:32:30 PM              01/06/2013 19:32:30
'       01 June 2013 7:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 07:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 7:32:30 PM                01/06/2013 19:32:30
'       June 2013                             01/06/2013 00:00:00
'       June 2013                             01/06/2013 00:00:00

TryParseExact 메서드를 ParseExact 사용하여 특정 형식 또는 형식과 일치해야 하는 문자열을 값으로 DateTime 변환합니다. 하나 이상의 날짜 및 시간 형식 문자열을 구문 분석 메서드의 매개 변수로 지정합니다. 다음 예제에서는 메서드를 TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) 사용하여 "yyyyMMdd" 형식 또는 "HHmmss" 형식이어야 하는 문자열을 값으로 DateTime 변환합니다.

string[] formats = { "yyyyMMdd", "HHmmss" };
string[] dateStrings = { "20130816", "20131608", "  20130816   ",
                   "115216", "521116", "  115216  " };
DateTime parsedDate;

foreach (var dateString in dateStrings)
{
    if (DateTime.TryParseExact(dateString, formats, null,
                               System.Globalization.DateTimeStyles.AllowWhiteSpaces |
                               System.Globalization.DateTimeStyles.AdjustToUniversal,
                               out parsedDate))
        Console.WriteLine($"{dateString} --> {parsedDate:g}");
    else
        Console.WriteLine($"Cannot convert {dateString}");
}
// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
let formats = [| "yyyyMMdd"; "HHmmss" |]
let dateStrings = 
    [ "20130816"; "20131608"; "  20130816   "
      "115216"; "521116"; "  115216  " ]

for dateString in dateStrings do
    match DateTime.TryParseExact(dateString, formats, null,
                                System.Globalization.DateTimeStyles.AllowWhiteSpaces |||
                                System.Globalization.DateTimeStyles.AdjustToUniversal) with
    | true, parsedDate ->
        printfn $"{dateString} --> {parsedDate:g}"
    | _ ->
        printfn $"Cannot convert {dateString}"

// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
Dim formats() As String = {"yyyyMMdd", "HHmmss"}
Dim dateStrings() As String = {"20130816", "20131608",
                              "  20130816   ", "115216",
                              "521116", "  115216  "}
Dim parsedDate As DateTime

For Each dateString As String In dateStrings
    If DateTime.TryParseExact(dateString, formats, Nothing,
                           DateTimeStyles.AllowWhiteSpaces Or
                           DateTimeStyles.AdjustToUniversal,
                           parsedDate) Then
        Console.WriteLine($"{dateString} --> {parsedDate:g}")
    Else
        Console.WriteLine($"Cannot convert {dateString}")
    End If
Next
' The example displays the following output:
'       20130816 --> 8/16/2013 12:00 AM
'       Cannot convert 20131608
'         20130816    --> 8/16/2013 12:00 AM
'       115216 --> 4/22/2013 11:52 AM
'       Cannot convert 521116
'         115216   --> 4/22/2013 11:52 AM

한 가지 일반적인 용도 ParseExact 는 일반적으로 ISO 8601 표준 형식으로 웹 서비스에서 문자열 표현을 변환하는 것입니다. 다음 코드는 사용할 올바른 형식 문자열을 보여줍니다.

var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
    System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}");
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

printfn $"{iso8601String} --> {dateISO8602:g}"
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As DateTime = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", CultureInfo.InvariantCulture)
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}")

문자열을 구문 분석할 수 없는 경우 및 ParseExact 메서드는 Parse 예외를 throw합니다. 및 TryParseExact 메서드는 TryParse 변환의 성공 여부를 나타내는 값을 반환 Boolean 합니다. 성능이 TryParse 중요한 시나리오에서 메서드 또는 TryParseExact 메서드를 사용해야 합니다. 날짜 및 시간 문자열에 대한 구문 분석 작업은 실패율이 높고 예외 처리 비용이 많이 듭니다. 문자열이 사용자가 입력하거나 알 수 없는 소스에서 오는 경우 이러한 메서드를 사용합니다.

날짜 및 시간 값 구문 분석에 대한 자세한 내용은 날짜 및 시간 문자열 구문 분석을 참조 하세요.

DateTime 값

형식의 시간 값에 DateTime 대한 설명은 UTC(협정 세계시) 표준을 사용하여 표현되는 경우가 많습니다. 조정된 유니버설 타임은 그리니치 표준시(GMT)의 국제적으로 인정받는 이름입니다. 조정된 유니버설 타임은 경도 0도, UTC 원점으로 측정된 시간입니다. 일광 절약 시간제는 UTC에 적용되지 않습니다.

현지 시간은 특정 표준 시간대를 기준으로 합니다. 표준 시간대는 표준 시간대 오프셋과 연결됩니다. 표준 시간대 오프셋은 UTC 원본 지점에서 몇 시간 단위로 측정된 표준 시간대의 변위입니다. 또한 현지 시간은 시간 간격 조정을 추가하거나 빼는 일광 절약 시간의 영향을 선택적으로 받습니다. 현지 시간은 UTC에 표준 시간대 오프셋을 추가하고 필요한 경우 일광 절약 시간을 조정하여 계산됩니다. UTC 원점의 표준 시간대 오프셋은 0입니다.

UTC 시간은 계산, 비교 및 날짜 및 시간을 파일에 저장하는 데 적합합니다. 현지 시간 데스크톱 애플리케이션의 사용자 인터페이스에 표시 하기에 적합합니다. 표준 시간대 인식 애플리케이션 (예: 여러 웹 애플리케이션)는 또한 다양 한 다른 표준 시간대를 사용 하 여 작업 해야 합니다.

개체의 KindDateTime 속성이 DateTimeKind.Unspecified면 표시되는 시간이 현지 시간, UTC 시간 또는 다른 표준 시간대의 시간인지 지정되지 않습니다.

DateTime 확인

참고 항목

경과된 시간을 측정하기 위해 값에 대한 DateTime 날짜 및 시간 산술 연산을 수행하는 대신 클래스를 Stopwatch 사용할 수 있습니다.

이 속성은 Ticks 날짜 및 시간 값을 1000만 초 단위로 표현합니다. 이 속성은 Millisecond 날짜 및 시간 값에서 1/10000초를 반환합니다. 경과된 시간을 측정하기 위해 속성에 DateTime.Now 대한 반복 호출을 사용하는 것은 시스템 클록에 따라 달라집니다. Windows 7 및 Windows 8 시스템의 시스템 클록의 해상도는 약 15밀리초입니다. 이 해상도는 100밀리초 미만의 작은 시간 간격에 영향을 줍니다.

다음 예제에서는 시스템 클록의 해상도에 대한 현재 날짜 및 시간 값의 의존성을 보여 줍니다. 이 예제에서 외부 루프는 20회 반복되고 내부 루프는 외부 루프를 지연시키는 역할을 합니다. 외부 루프 카운터의 값이 10이면 메서드를 호출하면 Thread.Sleep 5밀리초 지연이 발생합니다. 다음 예제에서는 호출 Thread.Sleep후에만 속성에서 반환되는 DateTime.Now.Milliseconds 시간(밀리초)을 보여 줍니다.

string output = "";
for (int ctr = 0; ctr <= 20; ctr++)
{
    output += String.Format($"{DateTime.Now.Millisecond}\n");
    // Introduce a delay loop.
    for (int delay = 0; delay <= 1000; delay++)
    { }

    if (ctr == 10)
    {
        output += "Thread.Sleep called...\n";
        System.Threading.Thread.Sleep(5);
    }
}
Console.WriteLine(output);
// Press "Run" to see the output.
let mutable output = ""
for i = 0 to 20 do
    output <- output + $"{DateTime.Now.Millisecond}\n"
    // Introduce a delay loop.
    for _ = 0 to 1000 do ()

    if i = 10 then
        output <- output + "Thread.Sleep called...\n"
        System.Threading.Thread.Sleep 5

printfn $"{output}"
// Press "Run" to see the output.
Dim output As String = ""
For ctr As Integer = 0 To 20
    output += Date.Now.Millisecond.ToString() + vbCrLf
    ' Introduce a delay loop.
    For delay As Integer = 0 To 1000
    Next

    If ctr = 10 Then
        output += "Thread.Sleep called..." + vbCrLf
        Thread.Sleep(5)
    End If
Next
Console.WriteLine(output)
' The example displays output like the following:
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       Thread.Sleep called...
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143

DateTime 작업

구조체(예: 또는Subtract)를 Add 사용하는 DateTime 계산은 구조체의 값을 수정하지 않습니다. 대신 계산은 해당 값이 계산의 결과인 새 DateTime 구조를 반환합니다.

표준 시간대 간(예: UTC와 현지 시간 사이 또는 표준 시간대와 다른 표준 시간대 간) 간의 변환 작업은 일광 절약 시간을 고려하지만 산술 및 비교 작업은 고려하지 않습니다.

DateTime 구조체 자체는 한 표준 시간대에서 다른 표준 시간대로 변환하기 위한 제한된 지원을 제공합니다. 이 메서드를 ToLocalTime 사용하여 UTC를 현지 시간으로 변환하거나 이 메서드를 ToUniversalTime 사용하여 현지 시간에서 UTC로 변환할 수 있습니다. 그러나 클래스에서 표준 시간대 변환 메서드의 전체 집합을 TimeZoneInfo 사용할 수 있습니다. 이러한 방법을 사용하여 전 세계 표준 시간대의 시간을 다른 표준 시간대의 시간으로 변환합니다.

개체의 계산 및 비교 DateTime 는 개체가 동일한 표준 시간대의 시간을 나타내는 경우에만 의미가 있습니다. 두 항목이 TimeZoneInfo 느슨하게 결합되어 있지만 개체를 DateTime 사용하여 값의 표준 시간대를 나타낼 수 있습니다. DateTime 개체에는 해당 날짜 및 시간 값의 표준 시간대를 나타내는 개체를 반환하는 속성이 없습니다. 이 속성은 Kind UTC, 현지 시간을 나타내는지 DateTime 또는 지정되지 않은지를 나타냅니다. 표준 시간대 인식 애플리케이션에서 사용 해야 합니다는 표준 시간대를 확인 하는 일부 외부 메커니즘을 DateTime 개체가 만들어진 합니다. 값과 TimeZoneInfo 값의 표준 시간대를 DateTime 나타내는 개체를 모두 래핑하는 구조를 사용할 수 있습니다DateTime. 계산에 UTC를 사용하고 값과 DateTime 비교하는 방법에 대한 자세한 내용은 날짜 및 시간을 사용하여 산술 연산 수행을 참조하세요.

DateTime 멤버는 음력 달력을 암시적으로 사용하여 작업을 수행합니다. 예외는 달력을 암시적으로 지정하는 메서드입니다. 여기에는 달력을 지정하는 생성자와 다음과 같이 System.Globalization.DateTimeFormatInfo파생된 매개 변수가 있는 IFormatProvider메서드가 포함됩니다.

형식의 DateTime 멤버별 작업은 윤년 및 한 달의 일 수와 같은 세부 정보를 고려합니다.

DateTime 값 및 일정

.NET 클래스 라이브러리에는 다양한 달력 클래스가 포함되어 있으며, 모두 클래스에서 Calendar 파생됩니다. 아래에 이 계정과 키의 예시가 나와 있습니다.

Important

일본어 달력의 시대는 천황 통치 기간을 기준으로 하므로 변경되어야 합니다. 예를 들어 2019년 5월 1일은 JapaneseCalendarJapaneseLunisolarCalendar에서 레이와 시대의 시작을 나타냅니다. 이러한 시대 변경 내용은 해당 달력을 사용하는 모든 애플리케이션에 영향을 줍니다. 자세한 내용과 애플리케이션이 영향을 받는지 여부를 확인하려면 .NET의 일본 달력에서 새 시대 처리를 참조하세요. Windows 시스템에서 애플리케이션을 테스트하여 시대 변화에 대한 준비 상태를 확인하는 방법에 대한 자세한 내용은 일본 시대 변경을 위한 애플리케이션 준비를 참조하세요. 여러 연대가 있는 달력을 지원하는 .NET의 기능과 여러 연대를 지원하는 달력으로 작업할 때 모범 사례는 연대 작업(Working with era)을 참조 하세요.

각 문화권은 읽기 전용 CultureInfo.Calendar 속성으로 정의된 기본 달력을 사용합니다. 각 문화권은 읽기 전용 CultureInfo.OptionalCalendars 속성으로 정의된 하나 이상의 일정을 지원할 수 있습니다. 현재 특정 CultureInfo 개체에서 사용되는 달력은 해당 DateTimeFormatInfo.Calendar 속성에 의해 정의됩니다. 배열에 있는 달력 CultureInfo.OptionalCalendars 중 하나여야 합니다.

문화권의 현재 달력은 해당 문화권에 대한 모든 서식 지정 작업에 사용됩니다. 예를 들어 태국 불교 문화의 기본 달력은 클래스가 나타내는 ThaiBuddhistCalendar 태국 불교 시대 달력입니다. CultureInfo 태국 불교 문화를 나타내는 개체가 날짜 및 시간 서식 작업에 사용되는 경우 태국 불교 시대 달력은 기본적으로 사용됩니다. 다음 예제와 같이 문화권의 DateTimeFormatInfo.Calendar 속성이 변경된 경우에만 그레고리오력이 사용됩니다.

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = new DateTime(2016, 5, 28);

Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime(2016, 5, 28)

printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()

printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Dim thTH As New CultureInfo("th-TH")
Dim value As New DateTime(2016, 5, 28)

Console.WriteLine(value.ToString(thTH))

thTH.DateTimeFormat.Calendar = New GregorianCalendar()
Console.WriteLine(value.ToString(thTH))
' The example displays the following output:
'       28/5/2559 0:00:00
'       28/5/2016 0:00:00

다음 예제와 같이 문화권의 현재 달력은 해당 문화권에 대한 모든 구문 분석 작업에도 사용됩니다.

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = DateTime.Parse("28/05/2559", thTH);
Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime.Parse("28/05/2559", thTH)
printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()
printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Private Sub ThaiBuddhistEraParse()
    Dim thTH As New CultureInfo("th-TH")
    Dim value As DateTime = DateTime.Parse("28/5/2559", thTH)
    Console.WriteLine(value.ToString(thTH))

    thTH.DateTimeFormat.Calendar = New GregorianCalendar()
    Console.WriteLine(value.ToString(thTH))
    ' The example displays the following output:
    '       28/5/2559 0:00:00
    '       28/5/2016 0:00:00
End Sub

매개 변수가 DateTime 포함된 calendar DateTime 생성자를 호출하고 해당 달력을 나타내는 개체로 전달 Calendar 하여 특정 달력의 날짜 및 시간 요소(연도, 월 및 일 수)를 사용하여 값을 인스턴스화합니다. 다음 예제에서는 달력의 날짜 및 시간 요소를 ThaiBuddhistCalendar 사용합니다.

var thTH = new System.Globalization.CultureInfo("th-TH");
var dat = new DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar);
Console.WriteLine($"Thai Buddhist era date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Gregorian date:   {dat:d}");
// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
let thTH = System.Globalization.CultureInfo "th-TH"
let dat = DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)

printfn $"""Thai Buddhist era date: {dat.ToString("d", thTH)}"""
printfn $"Gregorian date:   {dat:d}"

// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
Dim thTH As New CultureInfo("th-TH")
Dim dat As New DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)
Console.WriteLine($"Thai Buddhist Era date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Gregorian date:   {dat:d}")
' The example displays the following output:
'       Thai Buddhist Era Date:  28/5/2559
'       Gregorian Date:     28/05/2016

DateTime 매개 변수를 포함하지 calendar 않는 생성자는 날짜 및 시간 요소가 그레고리오력의 단위로 표현된다고 가정합니다.

다른 DateTime 모든 속성과 메서드는 그레고리오력을 사용합니다. 예를 들어 속성은 DateTime.Year 그레고리오력에서 연도를 반환하고 DateTime.IsLeapYear(Int32) 메서드는 매개 변수가 year 그레고리오력의 1년이라고 가정합니다. 양력 달력을 사용하는 각 DateTime 멤버에는 특정 달력을 사용하는 클래스의 Calendar 해당 멤버가 있습니다. 예를 들어 메서드는 Calendar.GetYear 특정 달력에서 연도를 반환하고 메서드는 Calendar.IsLeapYear 매개 변수를 특정 달력의 year 연도 번호로 해석합니다. 다음 예제에서는 클래스의 DateTime 해당 멤버와 해당 멤버를 ThaiBuddhistCalendar 모두 사용합니다.

var thTH = new System.Globalization.CultureInfo("th-TH");
var cal = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(2559, 5, 28, cal);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Year: {cal.GetYear(dat)}");
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}\n");

Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Year: {dat.Year}");
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
let thTH = System.Globalization.CultureInfo "th-TH"
let cal = thTH.DateTimeFormat.Calendar
let dat = DateTime(2559, 5, 28, cal)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Year: {cal.GetYear dat}"
printfn $"Leap year: {cal.IsLeapYear(cal.GetYear dat)}\n"

printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Year: {dat.Year}"
printfn $"Leap year: {DateTime.IsLeapYear dat.Year}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
Dim thTH As New CultureInfo("th-TH")
Dim cal As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(2559, 5, 28, cal)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Year: {cal.GetYear(dat)}")
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}")
Console.WriteLine()

Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Year: {dat.Year}")
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :   28/5/2559
'       Year: 2559
'       Leap year :   True
'
'       Using the Gregorian calendar
'       Date :   28/05/2016
'       Year: 2016
'       Leap year :   True

구조체에는 DateTime 그레고리오력에서 요일을 반환하는 속성이 포함됩니다 DayOfWeek . 연도의 주 번호를 검색할 수 있는 멤버는 포함되지 않습니다. 연도의 주를 검색하려면 개별 일정의 Calendar.GetWeekOfYear 메서드를 호출합니다. 다음 예제에서 이에 대해 설명합니다.

var thTH = new System.Globalization.CultureInfo("th-TH");
var thCalendar = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(1395, 8, 18, thCalendar);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}");
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n");

var greg = new System.Globalization.GregorianCalendar();
Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Day of Week: {dat.DayOfWeek}");
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay,DayOfWeek.Sunday)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
let thTH = System.Globalization.CultureInfo "th-TH"
let thCalendar = thTH.DateTimeFormat.Calendar
let dat = DateTime(1395, 8, 18, thCalendar)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Day of Week: {thCalendar.GetDayOfWeek dat}"
printfn $"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n"

let greg = System.Globalization.GregorianCalendar()
printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Day of Week: {dat.DayOfWeek}"
printfn $"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
Dim thTH As New CultureInfo("th-TH")
Dim thCalendar As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(1395, 8, 18, thCalendar)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}")
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
Console.WriteLine()

Dim greg As Calendar = New GregorianCalendar()
Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Day of Week: {dat.DayOfWeek}")
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :  18/8/1395
'       Day of Week: Sunday
'       Week of year: 34
'       
'       Using the Gregorian calendar
'       Date :  18/08/0852
'       Day of Week: Sunday
'       Week of year: 34

날짜 및 일정에 대한 자세한 내용은 일정 작업을 참조 하세요.

DateTime 값 유지

다음과 같은 방법으로 값을 유지할 DateTime 수 있습니다.

값을 복원 DateTime 하는 루틴이 어떤 기술을 선택하든 데이터를 손실하거나 예외를 throw하지 않도록 해야 합니다. DateTime 값은 왕복이어야 합니다. 즉, 원래 값과 복원된 값은 동일해야 합니다. 또한 원래 DateTime 값이 단일 시간 인스턴스를 나타내는 경우 복원되는 동일한 시간을 식별해야 합니다.

값을 문자열로 유지

문자열로 유지되는 값을 성공적으로 복원 DateTime 하려면 다음 규칙을 따릅니다.

  • 문자열을 유지할 때와 같이 문자열을 복원할 때 문화권별 서식 지정에 대해 동일한 가정을 합니다. 현재 문화권이 저장된 시스템의 문화권과 다른 시스템에서 문자열을 복원할 수 있도록 하려면 고정 문화권의 규칙을 사용하여 오버로드를 호출 ToString 하여 문자열을 저장합니다. 고정 문화권의 Parse(String, IFormatProvider, DateTimeStyles) 규칙을 사용하여 문자열을 복원하려면 오버로드 또는 TryParse(String, IFormatProvider, DateTimeStyles, DateTime) 오버로드를 호출합니다. 현재 문화권의 ToString()Parse(String)규칙을 사용하는 오버로드 또는 TryParse(String, DateTime) 오버로드를 사용하지 마세요.

  • 날짜가 단일 시간을 나타내는 경우 다른 표준 시간대에서도 복원할 때 동일한 시간을 나타내는지 확인합니다. DateTime 값을 저장하거나 사용하기 DateTimeOffset전에 값을 UTC(협정 세계시)로 변환합니다.

값을 문자열로 유지할 DateTime 때 발생하는 가장 일반적인 오류는 기본 또는 현재 문화권의 서식 지정 규칙에 의존하는 것입니다. 문자열을 저장하고 복원할 때 현재 문화권이 다른 경우 문제가 발생합니다. 다음 예제에서는 이러한 문제를 보여 줍니다. 현재 문화권의 서식 규칙을 사용하여 5개의 날짜를 저장합니다. 이 경우 영어(미국)입니다. 다른 문화권의 서식 규칙을 사용하여 날짜를 복원합니다. 이 경우 영어(영국)입니다. 두 문화권의 서식 규칙이 다르기 때문에 두 날짜를 복원할 수 없으며 다시 기본 세 날짜가 잘못 해석됩니다. 또한 원래 날짜 및 시간 값이 시간의 단일 순간을 나타내는 경우 표준 시간대 정보가 손실되므로 복원된 시간이 잘못되었습니다.

public static void PersistAsLocalStrings()
{
    SaveLocalDatesAsString();
    RestoreLocalDatesFromString();
}

private static void SaveLocalDatesAsString()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreLocalDatesFromString()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParse(inputValue, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue:f}");
        }
        else
        {
            Console.WriteLine($"Cannot parse '{inputValue}'");
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...
let saveLocalDatesAsString () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date}"
            string date ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreLocalDatesFromString () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"

    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParse inputValue with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue:f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsLocalStrings () =
    saveLocalDatesAsString ()
    restoreLocalDatesFromString ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...

왕복 DateTime 값을 성공적으로 수행하려면 다음 단계를 수행합니다.

  1. 값이 시간의 단일 순간을 나타내는 경우 메서드를 호출 ToUniversalTime 하여 현지 시간에서 UTC로 변환합니다.
  2. 또는 String.Format(IFormatProvider, String, Object[]) 오버로드를 호출하여 날짜를 문자열 표현으로 ToString(String, IFormatProvider) 변환합니다. 인수로 provider 지정 CultureInfo.InvariantCulture 하여 고정 문화권의 서식 규칙을 사용합니다. "O" 또는 "R" 표준 형식 문자열을 사용하여 값이 왕복되도록 지정합니다.

데이터 손실 없이 지속형 DateTime 값을 복원하려면 다음 단계를 수행합니다.

  1. 또는 TryParseExact 오버로드를 호출 ParseExact 하여 데이터를 구문 분석합니다. 인수로 provider 지정 CultureInfo.InvariantCulture 하고 변환 중에 인수에 사용한 것과 동일한 표준 형식 문자열을 format 사용합니다. 인수에 DateTimeStyles.RoundtripKindstyles 값을 포함합니다.
  2. 값이 시간 단위 DateTime 의 단일 순간을 나타내는 경우 메서드를 호출 ToLocalTime 하여 구문 분석된 날짜를 UTC에서 현지 시간으로 변환합니다.

다음 예제에서는 고정 문화권 및 "O" 표준 형식 문자열을 사용하여 저장 및 복원된 값이 DateTime 원본 및 대상 시스템의 시스템, 문화권 또는 표준 시간대에 관계없이 동일한 시간을 나타내도록 합니다.

public static void PersistAsInvariantStrings()
{
    SaveDatesAsInvariantStrings();
    RestoreDatesAsInvariantStrings();
}

private static void SaveDatesAsInvariantStrings()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)
                  + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInvariantStrings()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine("Current Time Zone: {0}",
                      TimeZoneInfo.Local.DisplayName);
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
                              DateTimeStyles.RoundtripKind, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}");
        }
        else
        {
            Console.WriteLine("Cannot parse '{0}'", inputValue);
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...
let saveDatesAsInvariantStrings () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreDatesAsInvariantStrings () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    
    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsInvariantStrings () =
    saveDatesAsInvariantStrings ()
    restoreDatesAsInvariantStrings ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...

값을 정수로 유지

날짜와 시간을 여러 틱을 Int64 나타내는 값으로 유지할 수 있습니다. 이 경우 값이 유지되고 복원되는 시스템의 DateTime 문화권을 고려할 필요가 없습니다.

값을 정수로 유지 DateTime 하려면 다음을 수행합니다.

  1. 값이 시간 단위 DateTime 의 단일 순간을 나타내는 경우 메서드를 호출 ToUniversalTime 하여 UTC로 변환합니다.
  2. 해당 속성에서 값으로 DateTime 표시되는 틱 수를 검색합니다 Ticks .

정수로 DateTime 유지된 값을 복원하려면 다음을 수행합니다.

  1. 생성자에 값을 전달 Int64 하여 새 DateTime 개체를 DateTime(Int64) 인스턴스화합니다.
  2. 값이 DateTime 한 순간을 나타내는 경우 메서드를 호출 ToLocalTime 하여 UTC에서 현지 시간으로 변환합니다.

다음 예제에서는 값 배열을 미국 태평양 표준 시간대의 DateTime 시스템에 정수로 유지합니다. UTC 영역의 시스템에서 복원합니다. 정수가 포함된 파일에는 바로 뒤에 있는 총 값 수를 Int64 나타내는 값이 포함 Int32 됩니다.

public static void PersistAsIntegers()
{
    SaveDatesAsInts();
    RestoreDatesAsInts();
}

private static void SaveDatesAsInts()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    var ticks = new long[dates.Length];
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        ticks[ctr] = dates[ctr].ToUniversalTime().Ticks;
    }
    var fs = new FileStream(filenameInts, FileMode.Create);
    var bw = new BinaryWriter(fs);
    bw.Write(ticks.Length);
    foreach (var tick in ticks)
        bw.Write(tick);

    bw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInts()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    FileStream fs = new FileStream(filenameInts, FileMode.Open);
    BinaryReader br = new BinaryReader(fs);
    int items;
    DateTime[] dates;

    try
    {
        items = br.ReadInt32();
        dates = new DateTime[items];

        for (int ctr = 0; ctr < items; ctr++)
        {
            long ticks = br.ReadInt64();
            dates[ctr] = new DateTime(ticks).ToLocalTime();
        }
    }
    catch (EndOfStreamException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    catch (IOException)
    {
        Console.WriteLine("Unspecified I/O error. Unable to restore data...");
        return;
    }
    // Thrown during array initialization.
    catch (OutOfMemoryException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    finally
    {
        br.Close();
    }

    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    foreach (var value in dates)
        Console.WriteLine(value.ToString("f"));

    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...
let saveDatesAsInts () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    let ticks =
        [| for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().Ticks |]
    use fs = new FileStream(filenameInts, FileMode.Create)
    use bw = new BinaryWriter(fs)
    bw.Write ticks.Length

    for tick in ticks do
        bw.Write tick

    printfn "Saved dates..."

let restoreDatesAsInts () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    use fs = new FileStream(filenameInts, FileMode.Open)
    use br = new BinaryReader(fs)

    try
        let items = br.ReadInt32()
        let dates =
            [| for _ in 0..items do
                let ticks = br.ReadInt64()
                DateTime(ticks).ToLocalTime() |]

        printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
        for value in dates do
            printfn $"{value:f}"
    with 
    | :? EndOfStreamException ->
        printfn "File corruption detected. Unable to restore data..."
    | :? IOException ->
        printfn "Unspecified I/O error. Unable to restore data..."
    // Thrown during array initialization.
    | :? OutOfMemoryException ->
        printfn"File corruption detected. Unable to restore data..."

    printfn "Restored dates..."

let persistAsIntegers () =
    saveDatesAsInts ()
    restoreDatesAsInts ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...

DateTime 값 직렬화

serialization을 통해 스트림 또는 파일에 값을 유지 DateTime 한 다음 역직렬화를 통해 복원할 수 있습니다. DateTime 데이터는 지정된 개체 형식으로 직렬화됩니다. 개체는 역직렬화될 때 복원됩니다. 포맷터 또는 serializer(예: JsonSerializer 직렬화 또는 XmlSerializer직렬 변환기)는 직렬화 및 역직렬화 프로세스를 처리합니다. serialization 및 .NET에서 지원하는 serialization 유형에 대한 자세한 내용은 Serialization을 참조하세요.

다음 예제에서는 클래스를 XmlSerializer 사용하여 값을 직렬화하고 역직렬화합니다 DateTime . 값은 21세기의 모든 윤년 일을 나타냅니다. 현재 문화권이 영어(영국)인 시스템에서 예제가 실행되는 경우 출력은 결과를 나타냅니다. 개체 자체를 역직렬화 DateTime 했으므로 코드는 날짜 및 시간 형식의 문화권 차이를 처리할 필요가 없습니다.

public static void PersistAsXML()
{
    // Serialize the data.
    var leapYears = new List<DateTime>();
    for (int year = 2000; year <= 2100; year += 4)
    {
        if (DateTime.IsLeapYear(year))
            leapYears.Add(new DateTime(year, 2, 29));
    }
    DateTime[] dateArray = leapYears.ToArray();

    var serializer = new XmlSerializer(dateArray.GetType());
    TextWriter sw = new StreamWriter(filenameXml);

    try
    {
        serializer.Serialize(sw, dateArray);
    }
    catch (InvalidOperationException e)
    {
        Console.WriteLine(e.InnerException?.Message);
    }
    finally
    {
        if (sw != null) sw.Close();
    }

    // Deserialize the data.
    DateTime[]? deserializedDates;
    using (var fs = new FileStream(filenameXml, FileMode.Open))
    {
        deserializedDates = (DateTime[]?)serializer.Deserialize(fs);
    }

    // Display the dates.
    Console.WriteLine($"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    int nItems = 0;
    if (deserializedDates is not null)
    {
        foreach (var dat in deserializedDates)
        {
            Console.Write($"   {dat:d}     ");
            nItems++;
            if (nItems % 5 == 0)
                Console.WriteLine();
        }
    }
}
// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096
let persistAsXML () =
    // Serialize the data.
    let leapYears =
        [| for year in 2000..4..2100 do
            if DateTime.IsLeapYear year then
                DateTime(year, 2, 29) |]

    let serializer = XmlSerializer(leapYears.GetType())
    use sw = new StreamWriter(filenameXml)

    try
        serializer.Serialize(sw, leapYears)
    with :? InvalidOperationException as e ->
        printfn $"{e.InnerException.Message}"

    // Deserialize the data.
    use fs = new FileStream(filenameXml, FileMode.Open)
        
    let deserializedDates = serializer.Deserialize fs :?> DateTime []

    // Display the dates.
    printfn $"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    
    let mutable nItems = 0
    for dat in deserializedDates do
        printf $"   {dat:d}     "
        nItems <- nItems + 1
        if nItems % 5 = 0 then
            printfn ""

// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096

이전 예제에는 시간 정보가 포함되지 않습니다. 값이 DateTime 특정 시간을 나타내고 현지 시간으로 표현되는 경우 메서드를 호출 ToUniversalTime 하여 직렬화하기 전에 현지 시간에서 UTC로 변환합니다. 역직렬화한 후 메서드를 호출 ToLocalTime 하여 UTC에서 현지 시간으로 변환합니다.

DateTime과 TimeSpan 비교

값 형식과 TimeSpan 값 형식은 DateTime 시간 간격을 DateTime 나타내는 반면, 시간 간격은 TimeSpan 인스턴트를 나타낸다는 점에서 다릅니다. 한 인스턴스를 DateTime 다른 인스턴스에서 빼서 둘 사이의 시간 간격을 TimeSpan 나타내는 개체를 가져올 수 있습니다. 또는 현재 DateTime 에 긍정 TimeSpan 을 추가하여 미래 날짜를 나타내는 값을 가져올 DateTime 수 있습니다.

개체에서 DateTime 시간 간격을 추가하거나 뺄 수 있습니다. 시간 간격은 음수 또는 양수일 수 있으며 틱, 초 또는 개체와 같은 단위로 TimeSpan 표현할 수 있습니다.

허용 범위 내의 같음 비교

값에 대한 DateTime 같음 비교는 정확합니다. 같게 간주하려면 두 값을 같은 수의 틱으로 표현해야 합니다. 이러한 정밀도는 종종 많은 애플리케이션에서 불필요하거나 정확하지 않습니다. 종종 개체가 거의 같은DateTime 테스트하려고 합니다.

다음 예제에서는 거의 동등한 DateTime 값을 비교하는 방법을 보여 줍니다. 같음으로 선언할 때 약간의 차이 여백을 허용합니다.

public static bool RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds)
{
    long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds;
    delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;
    return Math.Abs(delta) < windowInSeconds;
}

public static void TestRoughlyEquals()
{
    int window = 10;
    int freq = 60 * 60 * 2; // 2 hours;

    DateTime d1 = DateTime.Now;

    DateTime d2 = d1.AddSeconds(2 * window);
    DateTime d3 = d1.AddSeconds(-2 * window);
    DateTime d4 = d1.AddSeconds(window / 2);
    DateTime d5 = d1.AddSeconds(-window / 2);

    DateTime d6 = (d1.AddHours(2)).AddSeconds(2 * window);
    DateTime d7 = (d1.AddHours(2)).AddSeconds(-2 * window);
    DateTime d8 = (d1.AddHours(2)).AddSeconds(window / 2);
    DateTime d9 = (d1.AddHours(2)).AddSeconds(-window / 2);

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}");

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}");
}
// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
let roughlyEquals (time: DateTime) (timeWithWindow: DateTime) windowInSeconds frequencyInSeconds =
    let delta = 
        int64 (timeWithWindow - time).TotalSeconds % frequencyInSeconds
    
    let delta = if delta > windowInSeconds then frequencyInSeconds - delta else delta
    abs delta < windowInSeconds

let testRoughlyEquals () =
    let window = 10
    let window' = 10.
    let freq = 60 * 60 * 2 // 2 hours

    let d1 = DateTime.Now

    let d2 = d1.AddSeconds(2. * window')
    let d3 = d1.AddSeconds(-2. * window')
    let d4 = d1.AddSeconds(window' / 2.)
    let d5 = d1.AddSeconds(-window' / 2.)

    let d6 = (d1.AddHours 2).AddSeconds(2. * window')
    let d7 = (d1.AddHours 2).AddSeconds(-2. * window')
    let d8 = (d1.AddHours 2).AddSeconds(window' / 2.)
    let d9 = (d1.AddHours 2).AddSeconds(-window' / 2.)

    printfn $"d1 ({d1}) ~= d1 ({d1}): {roughlyEquals d1 d1 window freq}"
    printfn $"d1 ({d1}) ~= d2 ({d2}): {roughlyEquals d1 d2 window freq}"
    printfn $"d1 ({d1}) ~= d3 ({d3}): {roughlyEquals d1 d3 window freq}"
    printfn $"d1 ({d1}) ~= d4 ({d4}): {roughlyEquals d1 d4 window freq}"
    printfn $"d1 ({d1}) ~= d5 ({d5}): {roughlyEquals d1 d5 window freq}"

    printfn $"d1 ({d1}) ~= d6 ({d6}): {roughlyEquals d1 d6 window freq}"
    printfn $"d1 ({d1}) ~= d7 ({d7}): {roughlyEquals d1 d7 window freq}"
    printfn $"d1 ({d1}) ~= d8 ({d8}): {roughlyEquals d1 d8 window freq}"
    printfn $"d1 ({d1}) ~= d9 ({d9}): {roughlyEquals d1 d9 window freq}"

// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
Public Shared Function RoughlyEquals(time As DateTime, timeWithWindow As DateTime,
                             windowInSeconds As Integer,
                             frequencyInSeconds As Integer) As Boolean
    Dim delta As Long = (timeWithWindow.Subtract(time)).TotalSeconds _
                                            Mod frequencyInSeconds

    If delta > windowInSeconds Then
        delta = frequencyInSeconds - delta
    End If

    Return Math.Abs(delta) < windowInSeconds
End Function

Public Shared Sub TestRoughlyEquals()
    Dim window As Integer = 10
    Dim freq As Integer = 60 * 60 * 2 ' 2 hours;
    Dim d1 As DateTime = DateTime.Now

    Dim d2 As DateTime = d1.AddSeconds(2 * window)
    Dim d3 As DateTime = d1.AddSeconds(-2 * window)
    Dim d4 As DateTime = d1.AddSeconds(window / 2)
    Dim d5 As DateTime = d1.AddSeconds(-window / 2)

    Dim d6 As DateTime = d1.AddHours(2).AddSeconds(2 * window)
    Dim d7 As DateTime = d1.AddHours(2).AddSeconds(-2 * window)
    Dim d8 As DateTime = d1.AddHours(2).AddSeconds(window / 2)
    Dim d9 As DateTime = d1.AddHours(2).AddSeconds(-window / 2)

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}")

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}")
End Sub
' The example displays output similar to the following:
'    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True

COM interop 고려 사항

DateTime 관리 되는 애플리케이션을 다시 전송한 다음 COM 애플리케이션에 전송 되는 값을 왕복 이라고 합니다. 그러나 DateTime 시간만 지정하는 값은 예상한 대로 왕복하지 않습니다.

오후 3시와 같은 시간만 왕복하는 경우 최종 날짜와 시간은 1899년 12월 30일 오후 3시(0001년 1월 1일 오후 3:00)가 아닌 오후 3시입니다. NET 및 COM은 시간만 지정된 경우 기본 날짜를 가정합니다. 그러나 COM 시스템은 1899년 12월 30일 C.E.의 기본 날짜를 가정하고. .NET은 0001년 1월 1일의 기본 날짜를 가정합니다.

.NET에서 COM으로 시간만 전달되면 시간을 COM에서 사용하는 형식으로 변환하는 특수 처리가 수행됩니다. COM에서 .NET으로 시간만 전달되면 1899년 12월 30일 또는 그 이전에 합법적인 날짜와 시간이 손상되기 때문에 특별한 처리가 수행되지 않습니다. 날짜가 COM에서 왕복을 시작하는 경우 .NET 및 COM은 날짜를 유지합니다.

.NET 및 COM의 동작은 애플리케이션 DateTime 이 시간만 지정하는 왕복하는 경우 애플리케이션이 최종 DateTime 개체의 잘못된 날짜를 수정하거나 무시해야 함을 의미합니다.