DateTime.ToString ("MM / hh / tttt HH: mm: ss.fff") menghasilkan sesuatu seperti "09/14/2013 07.20.31.371"

131

Saya memiliki aplikasi WP8, yang akan mengirim waktu saat ini ke layanan web.

Saya mendapatkan string datetime dengan menelepon

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff")

Untuk sebagian besar pengguna ini berfungsi dengan baik dan memberi saya string yang benar seperti "09/10/2013 04:04:31.415". Tetapi untuk beberapa pengguna string yang dihasilkan adalah sesuatu seperti "09/14/2013 07.20.31.371", yang menyebabkan masalah dalam layanan web saya.

Apakah karena beberapa masalah format budaya? Bagaimana saya bisa memastikan string hasil dibatasi oleh titik dua bukan titik?

Eldorado
sumber
2
satu-satunya perbedaan adalah titik dua vs titik.
Eldorado
Lihat sampel .Net Standard 2
Sina Lotfi

Jawaban:

244

Apakah karena beberapa masalah format budaya?

Iya. Pengguna Anda harus dalam budaya di mana pemisah waktu adalah titik. Baik ":" dan "/" ditafsirkan dalam cara yang peka budaya dalam format tanggal dan waktu khusus .

Bagaimana saya bisa memastikan string hasil dibatasi oleh titik dua bukan titik?

Saya sarankan menentukan CultureInfo.InvariantCulture:

string text = dateTime.ToString("MM/dd/yyyy HH:mm:ss.fff",
                                CultureInfo.InvariantCulture);

Atau, Anda bisa mengutip pemisah waktu dan tanggal:

string text = dateTime.ToString("MM'/'dd'/'yyyy HH':'mm':'ss.fff");

... tapi itu akan memberi Anda hasil "menarik" yang mungkin tidak Anda harapkan jika Anda membuat pengguna menjalankan budaya di mana sistem kalender default bukan kalender Gregorian. Misalnya, ambil kode berikut:

using System;
using System.Globalization;
using System.Threading;

class Test
{
    static void Main()        
    {
        DateTime now = DateTime.Now;
        CultureInfo culture = new CultureInfo("ar-SA"); // Saudi Arabia
        Thread.CurrentThread.CurrentCulture = culture;
        Console.WriteLine(now.ToString("yyyy-MM-ddTHH:mm:ss.fff"));
    }
} 

Itu menghasilkan output (pada 18 September 2013) dari:

11/12/1434 15:04:31.750

Dugaan saya adalah bahwa layanan web Anda akan terkejut dengan itu!

Saya sebenarnya menyarankan tidak hanya menggunakan budaya invarian, tetapi juga mengubah ke format tanggal ISO-8601:

string text = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff");

Ini adalah format yang lebih diterima secara global - format ini juga dapat disortir, dan membuat urutan bulan dan hari menjadi jelas. (Bahwa 06/07/2013 dapat diartikan sebagai 7 Juni atau 6 Juli tergantung pada budaya pembaca.)

Jon Skeet
sumber
terima kasih Jon. Saya pikir string hasil akan persis seperti string format. Saya akan mencoba saran Anda.
Eldorado
3
Hanya satu pertimbangan kecil. Saat memuat objek CultureInfo dari kode tertentu, saya selalu menyarankan untuk mengatur useUserOverrideparameter ke false, jika tidak beberapa pengaturan pengguna dapat menimpa pengaturan budaya. Misalnya dalam kasus Anda, saya sarankan untuk menggunakan yang baru CultureInfo("ar-SA", false).
Davide Icardi
@DavideIcardi: Menarik, terima kasih - walaupun dalam hal ini tujuan menggunakan Arab Saudi secara khusus untuk mengatakan mengapa menggunakan budaya invarian mungkin benar. Akan mengingatnya untuk posting selanjutnya.
Jon Skeet
7
Di tengah jawaban yang luas ini, saya mulai bertanya-tanya: apakah ini Jon lagi? Ya.
Grimace of Despair
Bagaimana cara mengelola yang sama dengan Html.TextBoxFor (x => x.Date, "{0: MM / dd / yyyy}")?
VISHMAY
9

:memiliki arti khusus: itu adalah pemisah waktu. ( String Format Tanggal dan Waktu Kustom ).

Gunakan \untuk menghindarinya:

DateTime.ToString(@"MM/dd/yyyy HH\:mm\:ss.fff")

Atau gunakan CultureInfo.InvariantCulture:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture)

Saya akan menyarankan pergi dengan yang kedua, karena /memiliki makna khusus juga (itu adalah pemisah tanggal. ), Sehingga Anda dapat memiliki masalah dengan itu juga.

MarcinJuraszek
sumber
2
Bukan hanya pemisah tanggal yang menjadi masalah - lihat jawaban saya untuk contoh budaya yang mempengaruhi angka sebenarnya, juga ...
Jon Skeet
1
Aku tidak menghindarinya!
Shereef Marzouk
8

Anda dapat menggunakan InvariantCulture karena pengguna Anda harus berada dalam budaya yang menggunakan titik alih-alih titik dua:

DateTime.ToString("MM/dd/yyyy HH:mm:ss.fff", CultureInfo.InvariantCulture);
Jon La Marr
sumber
7

Saya bertemu dengan masalah ini belakangan ini dengan Windows 10 dari arah lain, dan menemukan jawaban dari @JonSkeet sangat membantu dalam memecahkan masalah saya.

Saya juga melakukan riset lebih lanjut dengan formulir tes dan menemukan bahwa ketika budaya saat ini diatur ke "no"atau "nb-NO"saat runtime ( Thread.CurrentThread.CurrentCulture = new CultureInfo("no");), panggilan ToString ("yyyy-MM-dd HH: mm: ss") merespons secara berbeda pada Windows 7 dan Windows 10. Ini mengembalikan apa yang saya harapkan di Windows 7 dan HH.mm.ss di Windows 10!

Saya pikir ini agak menakutkan! Karena saya percaya bahwa budaya adalah budaya di setiap versi Windows setidaknya.

Halo Seljåsen
sumber
Saya akan sangat ingin tahu apa yang sebenarnya menyebabkan ini.
Lauri Peltonen
2
Telah diakui dan diperbaiki sebagai Bug lokalisasi Windows 10. Jadi pembaruan windows pada mesin klien akan memperbaiki masalah. Rincian lebih lanjut tersedia di posting blog ini: heikniemi.net/hardcoded/2015/08/…
Håkon Seljåsen
Blog Jouni Heikniemi, yang saya tautkan di atas tampaknya rusak. Pembaruan windows yang relevan di mana masalah telah diperbaiki tercantum di sana: 2015-10-09: KB3093266 - Windows 10 KB3088956 - Windows Server 2012 R2 dan Windows 8.1 KB3088955 - Windows Server 2012 dan Windows 8 KB3088957 - Windows 7 SP1, Windows Server 2008 SP2 , Windows Server 2008 R2 SP1, dan Windows Vista SP2 Mencoba menghubungkan ke blog lagi, kali ini archive.org: web.archive.org/web/20161030193739/http://www.heikniemi.net/…
Håkon Seljåsen
4

Anda dapat menggunakan String.Format:

DateTime d = DateTime.Now;
string str = String.Format("{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}.{6:000}", d.Month, d.Day, d.Year, d.Hour, d.Minute, d.Second, d.Millisecond);
// I got this result: "02/23/2015 16:42:38.234"
Cosmin
sumber
0

Konversi Tanggal Ke String

Gunakan nama Spasi

using System.Globalization;

Kode

string date = DateTime.ParseExact(datetext.Text, "dd-MM-yyyy", CultureInfo.InstalledUICulture).ToString("yyyy-MM-dd");
Hafsal
sumber
Ini bukan cara mengonversi tanggal menjadi string. Parsing adalah kebalikannya!
Vincent Vancalbergh