Dalam aplikasi web tipikal, tanggal diambil dari lapisan basis data yang diketik dengan kuat (mis. Dalam c # sebagai System.DateTime sebagai lawan System.String).
Ketika suatu tanggal perlu dinyatakan sebagai string (misalnya ditampilkan pada halaman), konversi dari DateTime ke string dilakukan di tingkat presentasi.
Kenapa ini? Mengapa hal yang buruk untuk mengubah DateTime ke string pada tingkat basis data?
Lihat juga debat panas dalam obrolan , dan pertanyaan awal yang memulai semua ini .
database
sql
formatting
John Wu
sumber
sumber
Jawaban:
Tanggal, DateTimes, dan benar-benar objek yang diketik lainnya, umumnya harus dibiarkan dalam format yang diketik dengan benar sampai saat Anda membutuhkannya untuk dibuat menjadi beberapa jenis lainnya - terutama ketika jenis itu adalah bentuk yang dapat dibaca manusia, dan terutama ketika itu merupakan lossy / konversi satu arah.
Mengapa? Karena diasumsikan bahwa tipe tersebut memberi Anda banyak fungsionalitas bawaan yang praktis, seperti pengujian kesetaraan yang tepat, penambahan dan pengurangan, perbandingan (lebih besar dari, kurang dari), zona waktu dan fungsionalitas lokal (terutama penting untuk apa pun yang berkaitan dengan waktu), dll. Jika Anda memutuskan ingin mendukung orang Amerika dan format "Hari Bulan [Tahun], Tahun" serta gaya umum Inggris "Hari Bulan Tahun", atau standar ISO "Tahun-Bulan-Hari"? Apa yang akan Anda lakukan jika itu adalah string dan Anda perlu melakukan perubahan itu, menguraikannya kembali menjadi Tanggal? Ugh, tidak, terima kasih - ada banyak kejahatan dan bug pengecut seperti itu, yang sebaiknya dihindari sepenuhnya.
Lebih khusus, Anda menyebutkan arsitektur berjenjang, yang memiliki lapisan presentasi terpisah dari data nanti. Ini sebenarnya adalah alasan besar lainnya untuk melewatkan Tanggal sebagai Tanggal dan bukan string - karena jenis format string mana yang harus dimasukkan tanggal? Bahasa Inggris, Mandarin, dengan atau tanpa detik / milidetik, nama atau digit bulan penuh, akankah Anda ingin mengurutkan pada bidang tanggal nanti (menyortir string menuntut format string tertentu jika Anda ingin berfungsi dengan benar), dll? Ini semua pertanyaan presentasi - bagaimana pengguna harus melihat data - dan menempatkan logika itu di tempat lain akan membatasi keuntungan memiliki arsitektur berjenjang di tempat pertama. Basis data tidak perlu tahu atau peduli bagaimana Anda ingin melihat tanggal di masa depan.
Akhirnya, hampir semua aplikasi yang kompleks (untuk apa arsitektur berjenjang) yang peduli dengan waktu pasti akan menggunakan waktu / tanggal dalam banyak, banyak cara, dan seringkali pada semua tingkat arsitektur yang berbeda. Objek yang diketik terkait dengan waktu dan tanggal ada untuk alasan yang sangat bagus: waktu itu sendiri, dan terutama sistem kalender manusia, aneh dan sulit. Pada akhirnya, waktu dan tanggal bukanlah string untuk alasan yang sama dengan bilangan bulat dan floating point bukan string, dan itu hanya akan membuat hidup Anda lebih sulit jika Anda mencoba berpura-pura bahwa mereka benar-benar hanya array karakter, karena sebenarnya tidak.
sumber
Why? Because it is assumed that the type provides you with lots of handy built in functionality
Menurut saya ini hanya sekunder. Alasan sebenarnya adalah bahwa tipe memberi tahu Anda apa itu sesuatu . Sebuah tanggal bukanlah sebuah string, itu hanya terjadi dengan mudah menerjemahkan ke dalam string yang dapat dibaca manusia.Saya ingin tahu tipenya.
Saya benar-benar tidak peduli jika database Anda menyimpan informasi dalam sebuah string, beberapa int, atau byte, karena, pada akhirnya itu selalu byte. String yang mengambil lebih banyak ruang daripada yang dibutuhkan dalam database Anda tidak mengganggu saya. Yang mengganggu saya adalah berkencan seperti ini:
11/10/2016
Dan tidak tahu apakah itu bulan kesebelas atau bulan kesepuluh.
Tapi itu divalidasi katamu. Tentu Anda memasukkannya melalui proses validasi. Tanggalnya benar sekali. Tapi di sini saya mempertahankan hal ini dan yang saya tahu adalah tanggal adalah sebuah string. Aku bahkan tidak bisa memberitahumu tanggal berapa ini.
"Hari kesepuluh November dalam dua ribu enam belas tahun junjungan kita."
Itu sebuah string. Salah satu presentasi kami membutuhkannya dalam format itu. Anda bilang database mengubah semua tanggal menjadi string, kan? Bersenang-senanglah dengan itu.
Pekerjaan basis data adalah menyimpan data bukan menyajikan data. Tentu, Anda bisa melakukannya dalam string tetapi kemudian Anda harus menguraikannya agar berguna untuk disajikan untuk format lain. Menyimpannya dalam bentuk parsing standar untuk jenis apa pun yang ditawarkan DB membuat kita hampir siap untuk menyajikannya tanpa membuat keputusan presentasi. Tidak masalah bagi saya jika DB mendukung tipe itu dengan string atau ints atau bytes. Selama ia tahu apa yang dilakukannya.
Tetapi ketika Anda tidak memberi tahu DB kami sedang berurusan dengan kencan dan menyimpan tanggal sebagai string, Anda secara prematur menyajikan dan memilih satu presentasi daripada yang lainnya. Ini memaksa semua presenter lain untuk menguraikan sebelum mengkonversi. Tidak, basis data bukan bagian dari lapisan presentasi. Jangan memintanya.
Demikian juga lapisan presentasi bukan bagian dari database sehingga tidak bijaksana untuk memasangkan laporan ke detail basis data. Jauh lebih tangguh untuk bertindak berdasarkan tipe.
sumber
Lokal
Konversi tanggal ke string untuk keperluan presentasi memerlukan mengetahui preferensi pengguna, karena tanggal yang sama persis umumnya harus ditampilkan secara berbeda untuk pengguna di berbagai lokal. Bahkan jika Anda menggunakan satu lokal di aplikasi Anda, perilaku yang tepat harus menggunakan lokal aplikasi alih-alih server database; dan mereka tidak dijamin identik bahkan jika saat ini mereka secara kebetulan cocok.
Konversi dari tipe tanggal universal ke string spesifik lokal harus terjadi di lapisan presentasi karena itu lapisan yang tahu bagaimana konversi harus dilakukan.
sumber
Ini tidak diinginkan karena alasan yang sama Anda tidak akan hanya ingin secara diam-diam mengubah tipe apa pun menjadi string segera setelah menyentuh tier aplikasi. Ada kemungkinan besar Anda akan ingin menggunakan objek itu dalam beberapa cara sebelum menyajikannya kepada pengguna (jika Anda bahkan mempresentasikannya kepada pengguna). Untuk contoh khusus ini, bayangkan Anda perlu melakukan matematika tanggal pada objek. Tidak ada kerugian untuk hanya mengkonversi objek ke string tepat sebelum Anda menampilkannya.
sumber
Jenis ada karena suatu alasan, jika mereka menambahkan tidak ada manfaat maka kita tidak akan memilikinya dan tidak akan menggunakannya dan kita hanya akan memiliki "jenis" dan semuanya akan seperti itu. Mereka tidak hanya nyaman tetapi juga menambah keamanan dan efisiensi. Berikut ini adalah daftar mengapa Anda harus selalu bertahan mengetik dalam format asli mereka dan bukan sebagai string . Saya menggunakan
DateTime
sebagai contoh sebagian besar waktu tetapi prinsip yang sama berlaku untuk semua tipe primitif seperti bilangan bulat, desimal, biner, dll.Penyimpanan data
Kendala
Ketik Kendala
Hampir semua penyimpanan data memungkinkan untuk menentukan batasan pada data, ini termasuk batasan tipe. Salah satu manfaat utama dari menentukan
DateTime
contoh adalah bahwa data yang disimpan akan dibatasi untuk jenis itu. Tidak akan mungkin untuk memasukkan apa pun selain waktu tanggal terlepas dari bagaimana data dimasukkan ke dalam toko. Yang terakhir ini penting untuk sistem yang lebih besar di mana ada beberapa proses yang berinteraksi langsung dengan toko. Ini juga termasuk mencoba menambahkan tanggal yang salah seperti 30 Februari, (tahun apa saja) karena Februari hanya dapat memiliki 29 hari pada tahun kabisat dan 28 hari untuk tahun tidak kabisat.Kendala Validasi
Ada juga kendala validasi yang dapat diimplementasikan di Data Store seperti memastikan bahwa tanggal yang dimasukkan tidak melebihi tanggal saat ini atau bahwa tanggal mulai terjadi sebelum tanggal akhir.
Operasi
Sebagian besar penyimpanan data juga memiliki operasi / fungsi seperti
DateAdd
atauDatePart
di MS Sql Server. Ini memungkinkan Anda untuk mulai memfilter atau memilih data tertentu saat data masih tersimpan (belum diambil ke aplikasi).Format yang diterima secara universal
Dengan menggunakan tipe asli, pengembang atau sistem lain yang juga berinteraksi dengan toko tidak harus diberi tahu tentang detail kecil tentang bagaimana tipe primitif itu disimpan. Ini bukan kasus jika tipe itu disimpan sebagai string, maka Anda harus memastikan bahwa semua orang memahami format
DateTime
representasi string itu. Sistem ini menjadi rapuh ketika berurusan dengan data yang mencakup lokal, wilayah, dan budaya dalam asal data, lokasi fisik aplikasi, dan atribut pengguna akhir / sistem yang berinteraksi dengan data tersebut. Contoh: format tanggal di satu negara mungkin MM / dd / yyyy (seperti di AS) tetapi di negara lain bisa jadi dd / MM / yyyy, mendeteksi perbedaan itu menjadi hampir mustahil.Kecepatan
Kecepatan pengambilan, kecepatan validasi, kecepatan operasi dan efisiensi penyimpanan juga merupakan faktor penting. Contoh kecepatan pengambilan: penyimpanan data memungkinkan untuk indeks pada kolom dan indeks ini umumnya dapat lebih efisien digunakan jika jenis disimpan dalam format aslinya.
Aplikasi
Akses data
Mengeksekusi kueri terhadap toko menjadi lebih mudah menggunakan sistem tipe asli karena pengembang, sekali lagi, tidak perlu menebak format penyimpanan. Hampir semua penyedia aplikasi penyimpanan data ( contoh: ado.net ) menyediakan mekanisme untuk membuat kueri parameterisasi yang tepat berdasarkan tipe asli yang disahkan. Berikut adalah contoh menambahkan bagian Tanggal ke kueri ado.net terhadap toko Server Sql, melakukan hal yang sama dengan string akan sangat rumit dan rapuh / rentan kesalahan.
Operasi
Tipe asli dalam kode juga menyediakan operasi standar seperti tipe .net
System.Date
. Operasi biasanya bersifat matematis seperti menambahkan tanggal, menemukan perbedaan antara tanggal, dll. Sekali lagi, ini tidak mungkin dilakukan dengan mudah pada tipe string.Lapisan presentasi
Lokal
Ketika tipe primitif akhirnya dikonversi ke string di lapisan presentasi ( lokasi yang benar dalam tumpukan program untuk melakukannya ) programmer sekarang memiliki berbagai opsi untuk menampilkannya dengan benar sesuai dengan konteks di mana ia disajikan. Konteks ini umumnya terdiri dari makna aktual data dan lokal pengguna.
Contoh 1Contoh datetime dapat diformat secara otomatis berdasarkan lokal pengguna.
Contoh 2Contoh desimal dapat mewakili jumlah (mata uang) dan lokal pengguna kemudian harus juga menampilkan jumlah sesuai dengan preferensi mereka. Aplikasi c # kemudian dapat menampilkan nilai menggunakan
Ini bisa menjadi kritis karena budaya yang berbeda menampilkan angka secara berbeda. Pada periode AS (.) Dan koma (,) memiliki makna terbalik yang tepat seperti di Belanda.
Lokasi
Ini sangat spesifik untuk
DateTime
instance. Tanggal dan waktu merupakan kejadian pada saat tertentu dalam waktu tetapi ini biasanya harus disampaikan / disajikan kepada pengguna tergantung pada zona waktu mereka sendiri. Contoh: sebuahDateTime
instance2016-09-21T23:38:21.399Z
dapat ditampilkan9/21/2016 5:21 PM
untuk pengguna di Zona Waktu Timur di AS. Ada banyak cara untuk mencapai ini tetapi menjadi hampir mustahil jika instance waktu tanggal disimpan dalam memori sebagai tipe string atau dalam penyimpanan data sebagai tipe string.Peraturan umum
2 aturan umum untuk sebuah aplikasi mengikuti ketika datang untuk mengkonversi tipe primitif apa pun ke representasi string adalah seperti ini
sumber
Tidak ada yang salah dengan melakukan ini (itu dilakukan sepanjang waktu dalam layanan) selama Anda menggunakan format yang tidak ambigu untuk kencan Anda. Dengan jelas, maksud saya bukan saja tanggalnya jelas (mis. MM / DD vs. DD / MM) tetapi juga zona waktu yang digunakan. Jadi di muka, jika Anda akan merepresentasikan tanggal sebagai teks, gunakan format ISO . Saya sangat suka string waktu berdasarkan UTC.
Pro:
Kekurangan:
Jika seseorang berkata mereka ingin melakukan ini, saya akan bertanya "mengapa?" karena tidak banyak gunanya. Jika alasan seseorang ingin mengembalikan tanggal sebagai String adalah karena mereka hanya akan menampilkannya secara langsung, ini bukan alasan yang baik untuk menggunakan Strings dari DB.
sumber