DateTime'ı web UTC biçimine nasıl biçimlendirebilirim?


90

Biçimlendirmek istediğim bir DateTime var " 2009-09-01T00:00:00.000Z", ancak aşağıdaki kod bana " 2009-09-01T00:00:00.000+01:00" (her iki satır) veriyor :

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")

Nasıl çalıştırılacağına dair bir fikrin var mı?

Yanıtlar:


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

1
@Downvoter: Bu yanıtta neyin yanlış olduğunu bize söylemek ister misiniz?
LukeH

12
Bu işe yaradı, ancak .ToUniversalTime (), zaten UTC'de ise mevcut tarihinizi bozacak, ancak yourDateTime değişkeni bunu belirtmiyor. Sonunda .ToUniversalTime () 'ı kaldırdım ve tarihler daha sonra her iki uçta da beklenenlerle (veritabanı ve web istemcisi) sıralandı.
Robin Vessey

10
Tarih saatiniz zaten evrensel saat ise, istediğiniz .ToUniversalTime()her şeyi arayabilirsiniz , değiştirmez. - Bununla birlikte, yerel saat olarak saklanan evrensel bir zaman değeriniz varsa, o zaman elbette onu değiştirecektir (ama bu durumda başa çıkmanız gereken daha büyük sorunlarınız var!) - Neyse, bu cevap korkunç. Bunun "O"yerine, aşağıdaki yanıtta belirtilen biçim dizesini kullanmalısınız.
BrainSlugs83

1
@ BrainSlugs83: Bu "korkunç" cevabı aslında onlar için ne sordu OP verir: 2009-09-01T00:00:00.000Z. "O" belirteci kullanarak onları farklı bir şey verecekti: 2009-09-01T00:00:00.0000000Z.
LukeH


75

Neden Gidiş-Dönüş ("O", "o") Biçim Tanımlayıcısını kullanmıyorsunuz ?

"O" veya "o" standart biçim belirticisi, saat dilimi bilgilerini koruyan ve ISO 8601 ile uyumlu bir sonuç dizesi yayan bir model kullanan özel bir tarih ve saat biçimi dizesini temsil eder. DateTime değerleri için bu biçim belirticisi, tarihi korumak için tasarlanmıştır. ve metindeki DateTime.Kind özelliği ile birlikte saat değerleri. Biçimlendirilmiş dize, styles parametresi DateTimeStyles.RoundtripKind olarak ayarlanmışsa, DateTime.Parse (String, IFormatProvider, DateTimeStyles) veya DateTime.ParseExact yöntemi kullanılarak geri ayrıştırılabilir.

"O" veya "o" standart biçim belirteci, "yyyy" - "MM" - "gg'T'HH": "mm": "ss". "FffffffK" Tarih Saat değerleri için özel biçim dizesine ve "yyyy '-' MM '-' gg'T'HH ':' mm ':' ss '.' fffffffzzz" DateTimeOffset değerleri için özel biçim dizesi. Bu dizede, kısa çizgiler, iki nokta üst üste ve "T" harfi gibi tek tek karakterleri sınırlayan tek tırnak işareti çiftleri, tek tek karakterin değiştirilemeyecek bir değişmez değer olduğunu belirtir. Kesme işaretleri çıktı dizesinde görünmez.

O "veya" o "standart biçim belirleyicisi (ve" yyyy '-' MM '-' gg'T'HH ':' mm ':' ss '.' FffffffK "özel biçim dizesi) üç yoldan yararlanır ISO 8601, DateTime değerlerinin Kind özelliğini korumak için saat dilimi bilgilerini temsil eder:

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

İstendiği gibi çalışmadığı için, sonuçta alıntı yaptınız - "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffzzz" Zulu formatı değil.
astrowalker

@astrowalker Çalışmalı. Cevabında size birden fazla seçenek sundu. Sadece birini seçmen gerekiyor. Sizin durumunuzda (ve OP'lerde), sonunda "z" olan dizeler üretmek için DateTimeKind.Utc kullanırsınız (aka "Zulu Biçimi" veya "UTC Saati"). UTC için örnek çıktısına bakın. Benim durumumda, kullandım: veya dtVariable.ToUniversalTime().ToString("o")dönüşecek . Not: Bunu Javscript'in yöntemiyle de test ettim ve bunun ürettiği tarih dizesini doğru bir şekilde ayrıştırıyor. "2019-05-26T19:50:34.4400000Z""yyyy-MM-ddTHH:mm:ss.fffffffZ"new Date(dtDateString).getTime()
MikeTeeVee

@MikeTeeVee, sağlanan çözümlerin işe yaramayacağını söylüyordum (DTO için). Uygun yol dto.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFF'Z'"). Kayıt için sadece "o"ofset ekler, Zulu formatı değildir.
astrowalker

1
$"{DateTime.UtcNow:O}"
Tiago César Oliveira

19
string.Format("{0:yyyy-MM-ddTHH:mm:ss.FFFZ}", DateTime.UtcNow)

döndürür 2017-02-10T08: 12: 39.483Z


Bunun fffyerine kullanmanız gerekir FFFveya 000 tam olarak işarette bir saniye görüntülenmez.
Ryan Lundy

6

Kullanılacak en iyi format "yyyy '-' MM '-' gg'T'HH ':' mm ':' ss '.' FffK" şeklindedir.

Dize üzerindeki son K, tarih UTC ise 'Z' veya yerelse saat dilimi (+ -hh: mm) olarak değiştirilecektir. ( http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx )

LukeH'nin dediği gibi, tüm tarihlerin UTC olmasını istiyorsanız ToUniversalTime'ı kullanmak iyidir.

Nihai kod:

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

6

Bazı insanlar, 'ToUniversalTime'ın, istenmeyen yanlış zaman değişimlerine neden olabileceği için biraz güvensiz olduğuna dikkat çekmişlerdir. Bunu genişleterek, daha ayrıntılı bir çözüm örneği sunuyorum. Buradaki örnek, ToString'i istediğiniz gibi kullanabileceğiniz bir UTC DateTime'ı güvenli bir şekilde döndüren DateTime nesnesine bir uzantı oluşturur….

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();
    }
}

5

DateTimeOffset sınıfını kullanmak istiyorsunuz .

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

özür dilerim orijinal biçimlendirmenizi milisaniyelerle kaçırdım

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

5

Bu kod benim için çalışıyor:

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);

-3

Bunu dene:

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

Daha önce sorulan soru


3
Henüz ayrıştırmaya çalışmıyorum, yazdırmaya çalışıyorum.
Grzenio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.