2009-11-30 16 views
48

Mam DateTime, które chcę sformatować na "2009-09-01T00: 00: 00.000Z", ale poniższy kod daje mi "2009-09-01T00: 00: 00.000 + 01: 00" (obie linie) :Jak sformatować DateTime na internetowy format UTC?

new DateTime(2009, 9, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzz") 
new DateTime(2009, 9, 1, 0, 0, 0, 0, DateTimeKind.Utc).ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffzzz") 

Jakieś pomysły, jak to działa?

Odpowiedz

99
string foo = yourDateTime.ToUniversalTime() 
         .ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); 
+0

@Dvvoter: Czy chciałbyś nam powiedzieć, co uważasz za błędne w tej odpowiedzi? – LukeH

+10

To zadziałało, ale funkcja .ToUniversalTime() zepsułaby twoją istniejącą datę, jeśli jest już w UTC, ale zmienna yourDateTime jej nie określa. Skończyło się na usunięciu .ToUniversalTime(), a daty były zestawione z oczekiwaniami na obu końcach (baza danych i klient sieciowy). –

-2

Spróbuj tego:

DateTime date = DateTime.ParseExact(
    "Tue, 1 Jan 2008 00:00:00 UTC", 
    "ddd, d MMM yyyy HH:mm:ss UTC", 
    CultureInfo.InvariantCulture); 

Previously asked question

+3

Nie próbuję analizować go (jeszcze), I próbuję to wydrukować. – Grzenio

3

Chcesz użyć DateTimeOffset klasę.

var date = new DateTimeOffset(2009, 9, 1, 0, 0, 0, 0, new TimeSpan(0L)); 
var stringDate = date.ToString("u"); 

Niestety brakowało mi swoje oryginalne formatowanie z milisekundach

var stringDate = date.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"); 
6

Najlepszy format do wykorzystania jest „yyyy '-' MM '-' dd'T'GG ':' mm ':' ss '.' fffK ".

Ostatni ciąg znaków w łańcuchu zostanie zmieniony na "Z", jeśli data to UTC lub strefa czasowa (+ -hh: mm), jeśli jest lokalna. (http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx)

Jak powiedział LukeH, dobrze jest używać ToUniversalTime, jeśli chcesz, aby wszystkie daty były UTC.

Ostateczny kod jest:

string foo = yourDateTime.ToUniversalTime() 
         .ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffK"); 
42

Dlaczego nie wystarczy użyć The Round-trip ("O", "o") Format Specifier?

„O” lub „o” standardowym formacie specifier reprezentuje ciąg formatu daty i czasu zwyczaj stosując wzór, który zachowuje informacje o strefie czasowej i emituje ciąg wynik, który jest zgodny z normą ISO 8601. Dla wartości DateTime, ten format Specifier ma na celu zachowanie wartości daty i godziny wraz z właściwością DateTime.Kind w tekście. Sformatowany ciąg może zostać ponownie przeanalizowany za pomocą metody DateTime.Parse (String, IFormatProvider, DateTimeStyles) lub DateTime.ParseExact, jeśli parametr style jest ustawiony na DateTimeStyles.RoundtripKind.

Specyfikator standardowego formatu "O" lub "o" odpowiada "yyyy" - "MM" - "dd'T'HH": "mm": "ss". "FffffffK" niestandardowy ciąg znaków dla DateTime wartości i do "yyyy" - "MM" - "dd'T'HH": "mm": "ss". "fffffffzzz" ciąg w formacie niestandardowym dla wartości DateTimeOffset. W tym ciągu pary pojedynczych cudzysłowów, które ograniczają poszczególne znaki, takie jak łączniki, dwukropki i litera "T", wskazują, że indywidualny znak jest literałem, którego nie można zmienić. Apostrofy nie pojawiają się w łańcuchu wyjściowym.

Specyfikator standardowego formatu O "lub" o "(i" yyyy "-" MM "-" dd'T'HH ":" mm ":" ss "." FffffffK "niestandardowy format) z trzech sposobów, że ISO 8601 reprezentuje informacje strefy czasowej do zachowania własności rodzaju wartości DateTime:

public class Example 
{ 
    public static void Main() 
    { 
     DateTime dat = new DateTime(2009, 6, 15, 13, 45, 30, 
            DateTimeKind.Unspecified); 
     Console.WriteLine("{0} ({1}) --> {0:O}", dat, dat.Kind); 

     DateTime uDat = new DateTime(2009, 6, 15, 13, 45, 30, 
            DateTimeKind.Utc); 
     Console.WriteLine("{0} ({1}) --> {0:O}", uDat, uDat.Kind); 

     DateTime lDat = new DateTime(2009, 6, 15, 13, 45, 30, 
            DateTimeKind.Local); 
     Console.WriteLine("{0} ({1}) --> {0:O}\n", lDat, lDat.Kind); 

     DateTimeOffset dto = new DateTimeOffset(lDat); 
     Console.WriteLine("{0} --> {0:O}", dto); 
    } 
} 
// The example displays the following output: 
// 6/15/2009 1:45:30 PM (Unspecified) --> 2009-06-15T13:45:30.0000000 
// 6/15/2009 1:45:30 PM (Utc) --> 2009-06-15T13:45:30.0000000Z 
// 6/15/2009 1:45:30 PM (Local) --> 2009-06-15T13:45:30.0000000-07:00 
//  
// 6/15/2009 1:45:30 PM -07:00 --> 2009-06-15T13:45:30.0000000-07:00 
+0

W metatagu takim jak 'http-equiv =" last-modified "' format to *** 2013-10-23 @ 17: 23: 00 UTC ***, czy to możliwe? –

3

Niektórzy ludzie zwracają uwagę, że „ToUniversalTime” jest dość niebezpieczne, ponieważ może to spowodować niezamierzone błędne dispalys czasowych Rozbudowując to dostarczam bardziej szczegółowego przykładu rozwiązania.Ten przykład tutaj tworzy rozszerzenie obiektu DateTime, który bezpiecznie zwraca UTC DateTime, gdzie można użyć ToString zgodnie z życzeniem ....

class Program 
{ 
    static void Main(string[] args) 
    { 
     DateTime dUtc = new DateTime(2016, 6, 1, 3, 17, 0, 0, DateTimeKind.Utc); 
     DateTime dUnspecified = new DateTime(2016, 6, 1, 3, 17, 0, 0, DateTimeKind.Unspecified); 

     //Sample of an unintended mangle: 
     //Prints "2016-06-01 10:17:00Z" 
     Console.WriteLine(dUnspecified.ToUniversalTime().ToString("u")); 

     //Prints "2016 - 06 - 01 03:17:00Z" 
     Console.WriteLine(dUtc.SafeUniversal().ToString("u")); 

     //Prints "2016 - 06 - 01 03:17:00Z" 
     Console.WriteLine(dUnspecified.SafeUniversal().ToString("u")); 
    } 
} 

public static class ConvertExtensions 
{ 
    public static DateTime SafeUniversal(this DateTime inTime) 
    { 
     return (DateTimeKind.Unspecified == inTime.Kind) 
      ? new DateTime(inTime.Ticks, DateTimeKind.Utc) 
      : inTime.ToUniversalTime(); 
    } 
} 
1
string.Format("{0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow) 

powraca 2017-02-10T08: 12: 39.483Z

0

Ten kod działa dla mnie:

var datetime = new DateTime(2017, 10, 27, 14, 45, 53, 175, DateTimeKind.Local); 
var text = datetime.ToString("o"); 
Console.WriteLine(text); 
-- 2017-10-27T14:45:53.1750000+03:00 

// datetime from string 
var newDate = DateTime.ParseExact(text, "o", null); 
Powiązane problemy