DateTime 객체가 주어지면 어떻게 ISO 8601 날짜를 문자열 형식으로 얻습니까?
주어진:
DateTime.UtcNow
ISO 8601 호환 형식 에서 동일한 값을 나타내는 문자열을 얻으려면 어떻게해야 합니까?
ISO 8601은 여러 유사한 형식을 정의합니다. 내가 찾고있는 특정 형식은 다음과 같습니다.
yyyy-MM-ddTHH:mm:ssZ
독자 참고 사항 : 여러 의견 작성자가이 답변에서 몇 가지 문제를 지적했습니다 (특히 첫 번째 제안과 관련됨). 자세한 내용은 댓글 섹션을 참조하세요.
DateTime.UtcNow.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");
그러면 2008-09-22T13 : 57 : 31.2311892-04 : 00 과 유사한 날짜가 표시됩니다 .
또 다른 방법은 다음과 같습니다.
DateTime.UtcNow.ToString("o");
2008-09-22T14 : 01 : 54.9571247Z 를 제공합니다 .
지정된 형식을 얻으려면 다음을 사용할 수 있습니다.
DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ")
DateTime.UtcNow.ToString("s", System.Globalization.CultureInfo.InvariantCulture)
"s"형식 지정자는 정렬 가능한 날짜 / 시간 패턴으로 설명되므로 찾고있는 것을 제공해야합니다. ISO 8601을 준수합니다.
DateTime.UtcNow.ToString("s")
2008-04-10T06 : 30 : 00과 같은 값을 반환합니다.
UtcNow
분명히 UTC 시간을 반환 하므로 해가 없습니다.
string.Concat(DateTime.UtcNow.ToString("s"), "Z")
사용하다:
private void TimeFormats()
{
DateTime localTime = DateTime.Now;
DateTime utcTime = DateTime.UtcNow;
DateTimeOffset localTimeAndOffset = new DateTimeOffset(localTime, TimeZoneInfo.Local.GetUtcOffset(localTime));
//UTC
string strUtcTime_o = utcTime.ToString("o");
string strUtcTime_s = utcTime.ToString("s");
string strUtcTime_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");
//Local
string strLocalTimeAndOffset_o = localTimeAndOffset.ToString("o");
string strLocalTimeAndOffset_s = localTimeAndOffset.ToString("s");
string strLocalTimeAndOffset_custom = utcTime.ToString("yyyy-MM-ddTHH:mm:ssK");
//Output
Response.Write("<br/>UTC<br/>");
Response.Write("strUtcTime_o: " + strUtcTime_o + "<br/>");
Response.Write("strUtcTime_s: " + strUtcTime_s + "<br/>");
Response.Write("strUtcTime_custom: " + strUtcTime_custom + "<br/>");
Response.Write("<br/>Local Time<br/>");
Response.Write("strLocalTimeAndOffset_o: " + strLocalTimeAndOffset_o + "<br/>");
Response.Write("strLocalTimeAndOffset_s: " + strLocalTimeAndOffset_s + "<br/>");
Response.Write("strLocalTimeAndOffset_custom: " + strLocalTimeAndOffset_custom + "<br/>");
}
산출
UTC
strUtcTime_o: 2012-09-17T22:02:51.4021600Z
strUtcTime_s: 2012-09-17T22:02:51
strUtcTime_custom: 2012-09-17T22:02:51Z
Local Time
strLocalTimeAndOffset_o: 2012-09-17T15:02:51.4021600-07:00
strLocalTimeAndOffset_s: 2012-09-17T15:02:51
strLocalTimeAndOffset_custom: 2012-09-17T22:02:51Z
출처 :
표준 날짜 및 시간 형식 문자열 (MSDN)
사용자 지정 날짜 및 시간 형식 문자열 (MSDN)
System.DateTime.UtcNow.ToString("o")
=>
val it : string = "2013-10-13T13:03:50.2950037Z"
다음 코드로 "Z"( ISO 8601 UTC )를 얻을 수 있습니다 .
Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z
그 이유는 다음과 같습니다.
ISO 8601에는 몇 가지 다른 형식이 있습니다.
DateTimeKind.Local
2009-06-15T13:45:30.0000000-07:00
DateTimeKind.Utc
2009-06-15T13:45:30.0000000Z
DateTimeKind.Unspecified
2009-06-15T13:45:30.0000000
.NET은 이러한 옵션이 포함 된 열거 형을 제공합니다.
'2009-06-15T13:45:30.0000000-07:00
Dim strTmp1 As String = New DateTime(Now.Ticks, DateTimeKind.Local).ToString("o")
'2009-06-15T13:45:30.0000000Z
Dim strTmp2 As String = New DateTime(Now.Ticks, DateTimeKind.Utc).ToString("o")
'2009-06-15T13:45:30.0000000
Dim strTmp3 As String = New DateTime(Now.Ticks, DateTimeKind.Unspecified).ToString("o")
참고 : Visual Studio 2008 "감시 유틸리티"를 toString ( "o") 부분에 적용하면 다른 결과를 얻을 수 있습니다. 버그인지는 모르겠지만이 경우에는 String 변수를 사용하여 더 나은 결과를 얻을 수 있습니다. 디버깅하는 경우.
출처 : 표준 날짜 및 시간 형식 문자열 (MSDN)
ISO 8601에 대해 DateTime을 사용해야하는 경우 ToString ( "o")은 원하는 것을 산출해야합니다. 예를 들면
2015-07-06T12:08:27
그러나 DateTime + TimeZone은 블로그 게시물 DateTime 및 DateTimeOffset in .NET에 설명 된 다른 문제를 나타낼 수 있습니다 . 모범 사례 및 일반적인 함정 :
DateTime에는 코드 버그를 제공하도록 설계된 수많은 트랩이 있습니다.
1.- DateTimeKind.Unspecified가있는 DateTime 값은 나쁜 소식입니다.
2.- DateTime은 비교를 할 때 UTC / Local을 고려하지 않습니다.
3.- DateTime 값은 표준 형식 문자열을 인식하지 못합니다.
4.- UTC 마커가있는 문자열을 DateTime으로 구문 분석하는 것은 UTC 시간을 보장하지 않습니다.
나는 그냥 사용합니다 XmlConvert
:
XmlConvert.ToString(DateTime.UtcNow, XmlDateTimeSerializationMode.RoundtripKind);
시간대가 자동으로 유지됩니다.
이러한 답변의 대부분은 ISO 8601에서 분명히 지원하지 않는 밀리 초 / 마이크로 초입니다. 정답은 다음과 같습니다.
System.DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssK");
// or
System.DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
참조 :
DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ss zzz");
DateTime.Now.ToString("O");
참고 : 사용자가 수행하는 변환에 따라 첫 번째 줄 (가장 비슷 함) 또는 두 번째 줄을 사용하게됩니다.
"zzz"는 UTC 변환을위한 시간대 정보이므로 현지 시간에만 적용하십시오.
DateTime.UtcNow를 yyyy-MM-ddTHH : mm : ssZ 의 문자열 표현으로 변환하려면 사용자 지정 형식 지정 문자열과 함께 DateTime 구조의 ToString () 메서드를 사용할 수 있습니다. DateTime과 함께 사용자 지정 형식 문자열을 사용할 때 작은 따옴표를 사용하여 구분자를 이스케이프해야한다는 점을 기억하는 것이 중요합니다.
다음은 원하는 문자열 표현을 반환합니다.
DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
"s"
표준 형식 지정자에 의해 정의 된 사용자 지정 날짜 및 시간 형식 문자열을 나타냅니다 DateTimeFormatInfo.SortableDateTimePattern 속성을. 패턴은 정의 된 표준 ( ISO 8601 )을 반영하며 속성은 읽기 전용입니다. 따라서 사용 된 문화권이나 제공된 형식 공급자에 관계없이 항상 동일합니다. 사용자 지정 형식 문자열은"yyyy'-'MM'-'dd'T'HH':'mm':'ss"
입니다.이 표준 형식 지정자를 사용하면 형식 지정 또는 구문 분석 작업에서 항상 고정 문화권을 사용합니다.
– MSDN에서
사용자 지정 형식 "yyyy-MM-ddTHH : mm : ssK"(ms 없음)가 가장 빠른 형식 방법이라는 점이 흥미 롭습니다.
또한 "S"형식이 Classic에서는 느리고 Core에서는 빠르다는 점도 흥미 롭습니다.
물론 숫자는 매우 가깝고 일부 행 사이의 차이는 미미합니다 (접미사 _Verify
가있는 테스트 는 해당 접미사가없는 테스트와 동일하며 결과 반복성을 보여줍니다)
BenchmarkDotNet=v0.10.5, OS=Windows 10.0.14393
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233539 Hz, Resolution=309.2587 ns, Timer=TSC
[Host] : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
Clr : Clr 4.0.30319.42000, 64bit RyuJIT-v4.6.1637.0
Core : .NET Core 4.6.25009.03, 64bit RyuJIT
Method | Job | Runtime | Mean | Error | StdDev | Median | Min | Max | Rank | Gen 0 | Allocated |
--------------------- |----- |-------- |-----------:|----------:|----------:|-----------:|-----------:|-----------:|-----:|-------:|----------:|
CustomDev1 | Clr | Clr | 1,089.0 ns | 22.179 ns | 20.746 ns | 1,079.9 ns | 1,068.9 ns | 1,133.2 ns | 8 | 0.1086 | 424 B |
CustomDev2 | Clr | Clr | 1,032.3 ns | 19.897 ns | 21.289 ns | 1,024.7 ns | 1,000.3 ns | 1,072.0 ns | 7 | 0.1165 | 424 B |
CustomDev2WithMS | Clr | Clr | 1,168.2 ns | 16.543 ns | 15.474 ns | 1,168.5 ns | 1,149.3 ns | 1,189.2 ns | 10 | 0.1625 | 592 B |
FormatO | Clr | Clr | 1,563.7 ns | 31.244 ns | 54.721 ns | 1,532.5 ns | 1,497.8 ns | 1,703.5 ns | 14 | 0.2897 | 976 B |
FormatS | Clr | Clr | 1,243.5 ns | 24.615 ns | 31.130 ns | 1,229.3 ns | 1,200.6 ns | 1,324.2 ns | 13 | 0.2865 | 984 B |
FormatS_Verify | Clr | Clr | 1,217.6 ns | 11.486 ns | 10.744 ns | 1,216.2 ns | 1,205.5 ns | 1,244.3 ns | 12 | 0.2885 | 984 B |
CustomFormatK | Clr | Clr | 912.2 ns | 17.915 ns | 18.398 ns | 916.6 ns | 878.3 ns | 934.1 ns | 4 | 0.0629 | 240 B |
CustomFormatK_Verify | Clr | Clr | 894.0 ns | 3.877 ns | 3.626 ns | 893.8 ns | 885.1 ns | 900.0 ns | 3 | 0.0636 | 240 B |
CustomDev1 | Core | Core | 989.1 ns | 12.550 ns | 11.739 ns | 983.8 ns | 976.8 ns | 1,015.5 ns | 6 | 0.1101 | 423 B |
CustomDev2 | Core | Core | 964.3 ns | 18.826 ns | 23.809 ns | 954.1 ns | 935.5 ns | 1,015.6 ns | 5 | 0.1267 | 423 B |
CustomDev2WithMS | Core | Core | 1,136.0 ns | 21.914 ns | 27.714 ns | 1,138.1 ns | 1,099.9 ns | 1,200.2 ns | 9 | 0.1752 | 590 B |
FormatO | Core | Core | 1,201.5 ns | 16.262 ns | 15.211 ns | 1,202.3 ns | 1,178.2 ns | 1,225.5 ns | 11 | 0.0656 | 271 B |
FormatS | Core | Core | 993.5 ns | 19.272 ns | 24.372 ns | 999.4 ns | 954.2 ns | 1,029.5 ns | 6 | 0.0633 | 279 B |
FormatS_Verify | Core | Core | 1,003.1 ns | 17.577 ns | 16.442 ns | 1,009.2 ns | 976.1 ns | 1,024.3 ns | 6 | 0.0674 | 279 B |
CustomFormatK | Core | Core | 878.2 ns | 17.017 ns | 20.898 ns | 877.7 ns | 851.4 ns | 928.1 ns | 2 | 0.0555 | 215 B |
CustomFormatK_Verify | Core | Core | 863.6 ns | 3.968 ns | 3.712 ns | 863.0 ns | 858.6 ns | 870.8 ns | 1 | 0.0550 | 215 B |
암호:
public class BenchmarkDateTimeFormat
{
public static DateTime dateTime = DateTime.Now;
[Benchmark]
public string CustomDev1()
{
var d = dateTime.ToUniversalTime();
var sb = new StringBuilder(20);
sb.Append(d.Year).Append("-");
if (d.Month <= 9)
sb.Append("0");
sb.Append(d.Month).Append("-");
if (d.Day <= 9)
sb.Append("0");
sb.Append(d.Day).Append("T");
if (d.Hour <= 9)
sb.Append("0");
sb.Append(d.Hour).Append(":");
if (d.Minute <= 9)
sb.Append("0");
sb.Append(d.Minute).Append(":");
if (d.Second <= 9)
sb.Append("0");
sb.Append(d.Second).Append("Z");
var text = sb.ToString();
return text;
}
[Benchmark]
public string CustomDev2()
{
var u = dateTime.ToUniversalTime();
var sb = new StringBuilder(20);
var y = u.Year;
var d = u.Day;
var M = u.Month;
var h = u.Hour;
var m = u.Minute;
var s = u.Second;
sb.Append(y).Append("-");
if (M <= 9)
sb.Append("0");
sb.Append(M).Append("-");
if (d <= 9)
sb.Append("0");
sb.Append(d).Append("T");
if (h <= 9)
sb.Append("0");
sb.Append(h).Append(":");
if (m <= 9)
sb.Append("0");
sb.Append(m).Append(":");
if (s <= 9)
sb.Append("0");
sb.Append(s).Append("Z");
var text = sb.ToString();
return text;
}
[Benchmark]
public string CustomDev2WithMS()
{
var u = dateTime.ToUniversalTime();
var sb = new StringBuilder(23);
var y = u.Year;
var d = u.Day;
var M = u.Month;
var h = u.Hour;
var m = u.Minute;
var s = u.Second;
var ms = u.Millisecond;
sb.Append(y).Append("-");
if (M <= 9)
sb.Append("0");
sb.Append(M).Append("-");
if (d <= 9)
sb.Append("0");
sb.Append(d).Append("T");
if (h <= 9)
sb.Append("0");
sb.Append(h).Append(":");
if (m <= 9)
sb.Append("0");
sb.Append(m).Append(":");
if (s <= 9)
sb.Append("0");
sb.Append(s).Append(".");
sb.Append(ms).Append("Z");
var text = sb.ToString();
return text;
}
[Benchmark]
public string FormatO()
{
var text = dateTime.ToUniversalTime().ToString("o");
return text;
}
[Benchmark]
public string FormatS()
{
var text = string.Concat(dateTime.ToUniversalTime().ToString("s"),"Z");
return text;
}
[Benchmark]
public string FormatS_Verify()
{
var text = string.Concat(dateTime.ToUniversalTime().ToString("s"), "Z");
return text;
}
[Benchmark]
public string CustomFormatK()
{
var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
return text;
}
[Benchmark]
public string CustomFormatK_Verify()
{
var text = dateTime.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssK");
return text;
}
}
https://github.com/dotnet/BenchmarkDotNet 이 사용되었습니다.
아무도 제안하지 않았다는 사실에 놀랐습니다.
System.DateTime.UtcNow.ToString("u").Replace(' ','T')
UniversalSortableDateTimePattern은 (더 인 당신이 원하는 당신에게 거의 모든 방법을 얻을 수 RFC 3339 표현).
If you're developing under SharePoint 2010 or higher you can use
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
...
string strISODate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now)
To format like 2018-06-22T13:04:16 which can be passed in the URI of an API use:
public static string FormatDateTime(DateTime dateTime)
{
return dateTime.ToString("s", System.Globalization.CultureInfo.InvariantCulture);
}
Using Newtonsoft.Json, you can do
JsonConvert.SerializeObject(DateTime.UtcNow)
Example: https://dotnetfiddle.net/O2xFSl
As mentioned in other answer, DateTime
has issues by design.
NodaTime
I suggest to use NodaTime to manage date/time values:
- Local time, date, datetime
- Global time
- Time with timezone
- Period
- Duration
Formatting
So, to create and format ZonedDateTime
you can use the following code snippet:
var instant1 = Instant.FromUtc(2020, 06, 29, 10, 15, 22);
var utcZonedDateTime = new ZonedDateTime(instant1, DateTimeZone.Utc);
utcZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T10:15:22Z
var instant2 = Instant.FromDateTimeUtc(new DateTime(2020, 06, 29, 10, 15, 22, DateTimeKind.Utc));
var amsterdamZonedDateTime = new ZonedDateTime(instant2, DateTimeZoneProviders.Tzdb["Europe/Amsterdam"]);
amsterdamZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
// 2020-06-29T12:15:22Z
For me NodaTime
code looks quite verbose. But types are really useful. They help to handle date/time values correctly.
Newtonsoft.Json
To use
NodaTime
withNewtonsoft.Json
you need to add reference toNodaTime.Serialization.JsonNet
NuGet package and configure JSON options.
services
.AddMvc()
.AddJsonOptions(options =>
{
var settings=options.SerializerSettings;
settings.DateParseHandling = DateParseHandling.None;
settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
});
'Development Tip' 카테고리의 다른 글
CGI (Common Gateway Interface) 란 무엇입니까? (0) | 2020.09.29 |
---|---|
POST와 PUT HTTP REQUEST의 차이점은 무엇입니까? (0) | 2020.09.29 |
JavaScript를 사용하여 페이지를 다시로드하는 방법 (0) | 2020.09.29 |
Node.js 모범 사례 예외 처리 (0) | 2020.09.29 |
충돌이있는 자식 병합을 실행 취소하는 방법 (0) | 2020.09.29 |