Bagaimana Anda menyimpan "tanggal fuzzy" ke dalam database?

125

Ini adalah masalah yang saya alami beberapa kali. Bayangkan Anda memiliki catatan yang ingin Anda simpan ke dalam tabel database. Tabel ini memiliki kolom DateTime yang disebut "date_created". Satu catatan khusus ini dibuat sejak lama, dan Anda tidak benar-benar yakin tentang tanggal pastinya, tetapi Anda tahu tahun dan bulan. Catatan lain yang Anda tahu tahun itu. Catatan lain Anda tahu hari, bulan dan tahun.

Anda tidak dapat menggunakan bidang DateTime, karena "Mei 1978" bukan tanggal yang valid. Jika Anda membaginya menjadi beberapa kolom, Anda kehilangan kemampuan untuk bertanya. Adakah orang lain yang mengalami hal ini, jika demikian bagaimana Anda menanganinya?

Untuk memperjelas sistem yang saya bangun, ini adalah sistem yang melacak arsip. Beberapa konten telah diproduksi sejak lama, dan yang kita tahu adalah "Mei 1978". Saya dapat menyimpannya sebagai 1 Mei 1978, tetapi hanya dengan beberapa cara untuk menyatakan bahwa tanggal ini hanya akurat untuk bulan tersebut. Dengan begitu beberapa tahun kemudian ketika saya mengambil arsip itu, saya tidak bingung ketika tanggal tidak cocok.

Untuk tujuan saya, penting untuk membedakan "hari yang tidak diketahui pada bulan Mei 1978" dengan "1 Mei 1978". Juga, saya tidak ingin menyimpan yang tidak dikenal sebagai 0, seperti "0 Mei 1978" karena kebanyakan sistem basis data akan menolak itu sebagai nilai tanggal yang tidak valid.

nbv4
sumber
14
Apakah penting untuk membedakan "hari tak dikenal pada Mei 1978" dengan "1 Mei 1978"?
5
@MichaelT: ya, penting untuk membedakan.
nbv4
6
@aslum: Sebagian besar sistem basis data akan menolak itu sebagai nilai tanggal tidak valid
nbv4
9
@JimmyHoffa - Anda tidak pernah mengalami skenario tanggal fuzzy, atau skenario di mana Anda perlu membandingkan tanggal? Dalam kedua kasus, yang umum adalah riwayat medis: Anda ingat bahwa operasi usus buntu adalah tahun lalu pada tanggal 1 April, tetapi tonsilektomi sekitar tahun 1975, dan sesuatu yang lain terjadi selama bulan Mei dan Juni tahun tertentu. Bagaimana jika Anda ingin tahu apakah suatu peristiwa medis terjadi sebelum atau sesudah suatu terobosan medis lainnya? Apakah ini terjadi sebelum atau setelah mereka memeriksa persediaan darah untuk HIV?
thursdaysgeek

Jawaban:

148

Menyimpan semua tanggal di bidang DATE normal dalam database dan memiliki bidang akurasi tambahan seberapa akurat bidang DATE sebenarnya.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = tanggal pasti, 2 = bulan, 3 = tahun.

Jika kencan Anda tidak jelas (mis. Mei 1980) simpan tanggalnya di awal periode (mis. 1 Mei 1980). Atau jika tanggal Anda akurat untuk tahun (mis. 1980) simpan tanggal 1 Januari. 1980 dengan nilai akurasi yang sesuai.

Cara ini dapat dengan mudah meminta dengan cara yang agak alami dan masih memiliki gagasan tentang seberapa akurat tanggal. Sebagai contoh, ini memungkinkan Anda untuk menanyakan tanggal antara Jan 1st 1980dan Feb 28th 1981, dan mendapatkan tanggal fuzzy 1980dan May 1980.

Juha Syrjälä
sumber
1
Anda masih harus menghitung tanggal-akhir di sini dari apa yang dapat saya lihat, jadi saya pikir di antara kueri cukup jelek karena Anda memiliki bidang terhitung yang Anda pilih terbaik.
Wyatt Barnett
8
Jawaban yang bagus, sangat pintar. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. Jenius.
Naftuli Kay
58
Saya akan mendorong Anda untuk mempertimbangkan keakuratan tanggal hanya "hari". Di mana hari yang tepat adalah 0. Dengan cara ini seseorang dapat menggunakan tanggal yang lebih fleksibel "Suatu saat di musim panas" memiliki akurasi tanggal 90 hari berdasarkan pada tanggal 1 Juni daripada rentang tanggal tertentu yang dikodekan dengan keras. Itu juga bisa menangani akurasi multi-tahun.
1
Anda mungkin harus mengirimkannya sebagai jawaban, MichaelT
Supr
1
+1: Satu hal yang menyenangkan tentang solusi ini adalah Anda kemudian dapat menambahkan logika tampilan berdasarkan nilai date_created_accuracybidang. Anda dapat menampilkan "Mei 1980" atau hanya "1980" di hasil atau UI jika seakurat yang ditunjukkan bidang.
Kyralessa
27

Jika Anda tidak perlu menggunakan data seperti ini sebagai informasi waktu-tanggal reguler, format string apa pun bisa dilakukan.

Tetapi jika Anda perlu menjaga semua fungsinya, ada dua solusi yang dapat saya pikirkan, keduanya membutuhkan informasi tambahan yang disimpan dalam database:

  1. Buat min datedan max datebidang, yang memiliki nilai berbeda untuk data "tidak lengkap", tetapi akan bertepatan untuk tanggal yang akurat.
  2. Buat jenis untuk setiap jenis tanggal yang tidak akurat (tidak ada _ 0, date_missing _ 1, month_missing _ 2, year_missing_4, dll _ sehingga Anda dapat menggabungkannya). Tambahkan typebidang ke catatan dan simpan informasi yang hilang.
superM
sumber
Bidang tanggal min dan maks adalah pikiran pertama saya juga.
Michael Itzoe
1
Lama startup yang lalu, kami harus menyelesaikan masalah yang sama persis. Pengguna dapat menceritakan kisah tentang peristiwa yang terjadi kapan saja di masa lalu, jadi kami harus mendukung tanggal yang tidak jelas. Setelah banyak bolak-balik, solusi yang kami dapatkan paling mirip dengan saran superM di sini, di mana tanggal disimpan sebagai min & maks instance yang mungkin yang berisi tanggal cerita. Saat melaporkan tanggal, keakuratan (yaitu "catatan ini akurat untuk bulan / tahun / hari") dapat diekstraksi dari delta antara tanggal min & maks. Tidak perlu menyimpan bidang ke-3 untuk akurasi.
meetamit
4
+1 untuk min datedan max datebidang. Saya pikir itu adalah solusi yang paling fleksibel, namun tepat dan mudah digunakan.
Supr
1
Awalnya saya menentang ide ini. Tetapi menyadari itu adalah pendekatan yang paling fleksibel, saya memilih ini.
Anurag Kalia
Itu wajar. Anda menjelaskan bukan tanggal yang tidak jelas tetapi jangka waktu ..... yang memiliki awal dan akhir.
Pieter B
20

Ini lebih merupakan definisi persyaratan daripada masalah teknis - yang perlu Anda fokuskan adalah "bagaimana kita dapat menentukan tanggal di masa lalu" dan solusi teknis akan mengalir.

Saat-saat saya harus mendekati sesuatu seperti ini biasanya kami:

  • Tetapkan cara memetakan hal - seperti yang disarankan MichaelT , putuskan bahwa apa pun yang didefinisikan sebagai Bulan / Hari ditetapkan sebagai tengah malam pada tanggal 1 bulan tersebut. Ini biasanya cukup baik untuk sebagian besar tujuan - jika tanggal yang tepat adalah penting Anda mungkin akan memiliki catatan 35 tahun kemudian, kan?
  • Cari tahu apakah Anda perlu melacak ini - IE, apakah catatan dengan tanggal dibuat sedikit dibuat perlu bendera mengatakan demikian? Atau itu hanya masalah pelatihan pengguna sehingga orang tahu dan dapat bertindak sesuai.

Kadang-kadang seseorang perlu melakukan sesuatu seperti membuat tanggal menjadi kabur - misalnya, yang mungkin satu tanggal mungkin perlu menanggapi permintaan untuk apa pun pada Mei 1978. Ini bisa dilakukan - buat saja bidang create_date 2 Anda, catatan lama mendapat 30 hari tersebar sebagaimana mestinya, yang baru mendapatkan 2 nilai yang identik.

Wyatt Barnett
sumber
1
+1 - Saya sedang berupaya merumuskan jawaban dengan pendekatan tanggal ganda. Jawaban Anda ada di sini dulu.
2
+1, Ini jelek dan membuat banyak informasi tambahan yang tidak berguna untuk entri baru yang tidak memerlukannya, tetapi di sisi lain itu membuat kueri lebih sederhana daripada yang seharusnya. Kami telah menggunakan solusi serupa untuk masalah terkait untuk sementara waktu sekarang.
Izkata
3
@Izkata - Poin wajar, tapi seberapa elegan Anda bisa dapatkan ketika Anda perlu membuat sesuatu yang seharusnya menjadi satu titik dalam rentang waktu sebulan. Tentu saja lebih cantik daripada harus menghitung mulai dan berakhir untuk permintaan dengan cepat di suatu tempat.
Wyatt Barnett
1
+1 karena mampu menunjukkan granularitas arbitrer tanpa ledakan nilai enum.
Dan Neely
18

Cara paling sederhana untuk menunjukkan jika tanggal akurat adalah dengan membuat bidang akurasi INT (1) dengan NULL default

Jika tanggal akurat simpan tanggal-waktu di "date_created" & tinggalkan akurasi NULL

Jika tanggal hanya akurat untuk tanggal toko tanggal waktu sebagai 1 Bulan dengan nilai akurasi 1

Jika tanggal hanya akurat untuk tanggal toko tahun waktu 1 Januari dengan nilai akurasi 2

Anda dapat menggunakan angka yang berbeda untuk menyimpan nilai yang berbeda seperti kuartal pertama, dll

david strachan
sumber
Pertanyaan menjadi sangat berbulu ketika Anda melakukannya.
Blrfl
3
Ini memiliki kesulitan dengan data yang tidak pada batas bulan bersih seperti "Q2 1991" dan "Winter 1978-1979".
1
OP ingin beberapa cara untuk menyatakan bahwa tanggal ini hanya akurat untuk bulan tersebut.
david strachan
7
Anda menyalahgunakan arti NULL di sini. NULL berarti "tidak dikenal", jadi jika tanggalnya akurat, akurasinya tidak bisa NULL. Itu bisa '1'.
Konerak
@Konerak Semantik ya. Tetapi karena mayoritas tanggal akurat, hanya kasus khusus yang perlu diidentifikasi dan menggunakan NULL di sini sebagai default.
david strachan
17

Di masa lalu saya telah menyimpan tanggal-dengan-akurasi sebagai tanggal mulai dan tanggal akhir. Hari may21.2012 akan direpresentasikan sebagai mulai = 12 pagi, 21 Mei 2012 dan akhir = 12 pagi, 22222012. Tahun 2012 akan direpresentasikan sebagai awal = 12 pagi, Jan 1.2012 akhir = 12 pagi, Jan.12013.

Saya tidak yakin apakah saya akan merekomendasikan pendekatan ini. Saat menampilkan informasi kepada pengguna, Anda perlu mendeteksi dengan benar bahwa rentang tanggal persis mencakup satu hari untuk menunjukkan "mungkin 25" alih-alih dua titik akhir yang terlalu spesifik (yang berarti berurusan dengan penghematan siang hari dan sebagainya).

Namun, ketika Anda tidak mencoba menerjemahkan ke manusia, pemrograman dengan titik akhir jauh lebih mudah daripada dengan akurasi pusat +. Anda tidak berakhir dengan banyak kasus. Cukup bagus.

Craig Gidney
sumber
Sebenarnya, tidak perlu terlalu rumit untuk menentukan cara menyajikan rentang jika rentang selalu disimpan sebagai UTC. Karena stempel waktu UTC, setiap hari, minggu, bulan, tahun - bahkan musim dan kuartal - akan memiliki dua angka konstan, global, berbeda, dan mudah ditentukan yang mewakili awal dan akhir periode. Logikanya hanya menjadi beberapa jika-pernyataan untuk melihat apakah dua tanggal berada di awal dan akhir dari beberapa jenis periode. Tidak diperlukan matematika atau zona waktu yang rumit :)
Supr
@Supr Menentukan apakah detik tertentu ada di perbatasan periode manusia tertentu, dalam dirinya sendiri, merupakan masalah yang sulit. Terutama dalam jangka panjang, dengan rotasi Bumi melambat dan perubahan kecil tak berujung pada definisi manusia waktu setempat.
Craig Gidney
14

Mengapa tidak menyimpan dua kurma.

Created_After dan Created_Before. Semantik aktual "dibuat pada atau setelah" dan "dibuat pada atau sebelum"

Jadi jika Anda tahu tanggal pastinya maka Created_After dan Created_Before akan menjadi tanggal yang sama.

Jika Anda tahu itu adalah minggu pertama di bulan Mei 2000 maka Created_After = '2000-05-01' dan Created_Before = '2000-05-07'.

Jika Anda hanya tahu Mei 1999 maka nilainya akan menjadi '1999-05-01' dan '1999-05-30'.

Jika "Summer of '42" maka nilainya akan menjadi '1942-06-01' dan '1942-08-31'.

Skema ini mudah di-query dengan SQL normal, dan cukup mudah diikuti oleh pengguna yang tidak teknis.

Misalnya untuk menemukan semua dokumen yang mungkin telah dibuat pada Mei 2001:

SELECT * FROM DOCTAB WHERE Created_After < '2001-05-31' And Created_Before > 2001-05-01;

Sebaliknya untuk menemukan semua dokumen yang pasti dibuat pada Mei 2001:

SELECT * FROM DOCTAB WHERE Created_After > '2001-05-01' And Created_Before < 2001-05-31;
James Anderson
sumber
1
Saya pikir ini adalah solusi paling elegan.
Pieter B
Ini sama dengan jawaban superM dan Strilanc. +1 meskipun untuk menjelaskan lebih jelas dan menunjukkan betapa sederhananya kueri.
Supr
9

Format waktu tanggal ISO 8601 hadir dengan definisi durasi, mis

2012-01-01P1M (baca: 2012, 1 Januari, periode: 1 bulan) adalah apa yang seharusnya “pada Januari 2012”.

Saya akan menggunakan ini untuk menyimpan data. Anda mungkin perlu bidang database tipe String untuk melakukannya. Ini adalah topik yang berbeda bagaimana melakukan pencarian yang masuk akal tentang itu.

Matthias Ronge
sumber
Memberi +1 untuk gagasan tetapi -1 untuk tidak menggunakan bidang tanggal karena alasan bagaimana mencari dan / atau menemukan
user151019
Tergantung pada database. Namun ini bisa menjadi dasar ekspansi, tetapi pertanyaannya adalah: Apakah dokumen dalam hasil ditetapkan jika Anda mencari, dalam hal ini, semua dokumen lebih baru dari 12 Januari, atau bukan? Itu tidak sepele. Di sini, pertanyaannya adalah bagaimana cara menyimpan kurma fuzzy.
Matthias Ronge
3

Secara umum, saya masih menyimpannya sebagai tanggal ke bisnis kueri umum masih dimungkinkan walaupun sedikit kurang akurat.

Jika penting untuk mengetahui keakuratan yang saya miliki di masa lalu baik menyimpan "jendela" akurasi baik sebagai +/- desimal atau sebagai pencarian (hari, bulan, tahun, dll). Dalam kasus lain, alih-alih jendela, saya hanya menyimpan nilai tanggal asli sebagai string dan mengonversi apa yang saya bisa ke datetime, mungkin 1978-05-01 00:00:00 dan "Mei 1978" untuk contoh Anda.

Tagihan
sumber
3

Jika Anda membaginya menjadi beberapa kolom, Anda kehilangan kemampuan untuk bertanya.

Kata siapa? Inilah yang Anda lakukan:

  1. Memiliki 3 kolom, Hari, Bulan, Tahun, masing-masing tipe int, dan kolom keempat Tanggal Tanggal tipe DateTime.
  2. Memiliki pemicu yang menggunakan 3 kolom Hari, Bulan, Tahun untuk membangun TheDate jika TheDate dibiarkan nol tetapi satu atau lebih bidang Hari, Bulan, Tahun memiliki nilai.
  3. Memiliki pemicu yang mengisi bidang Hari, Bulan, Tahun saat TheDate diberikan tetapi bidang ini tidak.

Jadi jika saya melakukan penyisipan seperti: insert into thistable (Day, Month, Year) values (-1, 2, 2012);maka TheDate akan menjadi 2/1/2013 tetapi saya akan tahu ini benar-benar tanggal yang tidak ditentukan pada 2/2012 karena -1 di bidang Day.

Jika saya insert into thistable (TheDate) values ('2/5/2012');maka Hari akan menjadi 5, Bulan akan menjadi 2, dan Tahun akan menjadi 2012 dan karena tidak satupun dari mereka adalah -1, saya akan tahu ini adalah tanggal yang tepat.

Saya tidak kehilangan kemampuan untuk bertanya karena pemicu sisipan / pembaruan memastikan 3 bidang saya (Hari, Bulan, Tahun) selalu menghasilkan nilai DateTime di TheDate yang dapat ditanyakan.

sampah
sumber
3

Pilihan lain adalah menyimpan tanggal sebagai bilangan bulat dari formulir YYYYMMDD.

  • Anda hanya tahu tahun 1951: Simpan sebagai 19510000
  • Anda tahu bulan dan tahun adalah Maret 1951: Simpan sebagai 19510300
  • Anda tahu tanggal lengkapnya adalah 14 Maret 1951: Simpan sebagai 19510314
  • Tanggal yang sama sekali tidak dikenal: Simpan sebagai 0

Manfaat

Anda dapat menyimpan tanggal fuzzy Anda dalam satu bidang alih-alih dua bidang tanggal atau tanggal dan akurasi seperti yang disarankan oleh banyak jawaban lainnya.

Pertanyaan masih mudah:

  • semua catatan untuk tahun 1951 - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • semua catatan untuk Maret 1951 - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • semua catatan untuk 14 Maret 1951 - SELECT * FROM table where thedate=19510314

CATATAN

  • GUI Anda akan membutuhkan GetDateString(int fuzzyDate)yang cukup mudah untuk diterapkan.
  • Penyortiran mudah dengan format int. Anda harus tahu bahwa tanggal yang tidak diketahui akan didahulukan. Anda dapat membalikkan ini dengan menggunakan 99'padding' alih-alih 00untuk bulan atau hari.
Rick
sumber
Bagaimana Anda mewakili tanggal kabur "musim dingin 1941-1942"? Bisa jadi Desember 1941, atau Januari 1942.
1
Pertanyaan Anda terkait dengan kasus solusi umum. Pertanyaan awal tidak mencantumkan ini sebagai masalah. Berdasarkan pertanyaan yang diposting, terkadang tanggal lengkap diketahui, kadang-kadang hanya tahun dan bulan, dan kadang-kadang hanya tahun. Tidak ada masalah rentang tanggal fuzzy disebutkan sebagai persyaratan. Saya setuju Anda perlu dua tanggal jika Anda perlu menyelesaikan masalah ini (walaupun, menyimpan rentang sebagai dua "tanggal int fuzzy" dapat memberikan lebih banyak fleksibilitas daripada menyimpan dua tanggal "keras").
Rick
1

ISO 8601 juga menentukan sintaks untuk "tanggal fuzzy". 12 Februari 2012 jam 3 sore adalah "2012-02-12T15" dan Februari 2012 bisa jadi "2012-02". Ini meluas dengan baik menggunakan penyortiran leksikografis standar:

$ (echo "2013-03"; echo "2013-03"; echo "2012-02-12T15"; echo "2012-02"; echo "2011") | sort
2011
2012
2012-02
2012-02-12T15
2013-03
Sebuah jawaban
sumber
0

Inilah pendapat saya tentang ini:

Mulai dari fuzzy date ke objek datetime (yang akan masuk ke dalam database)

import datetime
import iso8601

def fuzzy_to_datetime(fuzzy):
    flen = len(fuzzy)
    if flen == 4 and fuzzy.isdigit():
        dt = datetime.datetime(year=int(fuzzy), month=1, day=1, microsecond=111111)

    elif flen == 7:
        y, m = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=1, microsecond=222222)

    elif flen == 10:
        y, m, d = fuzzy.split('-')
        dt = datetime.datetime(year=int(y), month=int(m), day=int(d), microsecond=333333)

    elif flen >= 19:
        dt = iso8601.parse_date(fuzzy)

    else:
        raise ValueError("Unable to parse fuzzy date: %s" % fuzzy)

    return dt

Dan kemudian fungsi yang mengambil objek datetime, dan memindahkannya kembali ke tanggal fuzzy.

def datetime_to_fuzzy(dt):
    ms = str(dt.microsecond)
    flag1 = ms == '111111'
    flag2 = ms == '222222'
    flag3 = ms == '333333'

    is_first = dt.day == 1
    is_jan1 = dt.month == 1 and is_first

    if flag1 and is_jan1:
        return str(dt.year)

    if flag2 and is_first:
        return dt.strftime("%Y-%m")

    if flag3:
        return dt.strftime("%Y-%m-%d")

    return dt.isoformat()

Dan kemudian tes unit. Apakah saya melewatkan kasus?

if __name__ == '__main__':
    assert fuzzy_to_datetime('2001').isoformat() == '2001-01-01T00:00:00.111111'
    assert fuzzy_to_datetime('1981-05').isoformat() == '1981-05-01T00:00:00.222222'
    assert fuzzy_to_datetime('2012-02-04').isoformat() == '2012-02-04T00:00:00.333333'
    assert fuzzy_to_datetime('2010-11-11T03:12:03Z').isoformat() == '2010-11-11T03:12:03+00:00'

    exact = datetime.datetime(year=2001, month=1, day=1, microsecond=231)
    assert datetime_to_fuzzy(exact) == exact.isoformat()

    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=1, day=1, microsecond=111111)) == '2001'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=3, day=1, microsecond=222222)) == '2001-03'
    assert datetime_to_fuzzy(datetime.datetime(year=2001, month=6, day=6, microsecond=333333)) == '2001-06-06'

    assert datetime_to_fuzzy(fuzzy_to_datetime('2002')) == '2002'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-05')) == '2002-05'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2002-02-13')) == '2002-02-13'
    assert datetime_to_fuzzy(fuzzy_to_datetime('2010-11-11T03:12:03.293856+00:00')) == '2010-11-11T03:12:03.293856+00:00'

Ada kasus sudut di mana peristiwa yang terjadi secara tepat 2001-01-01T00:00:00.333333tetapi sistem akan menafsirkan sebagai hanya "2001", tetapi itu tampaknya sangat tidak mungkin.

nbv4
sumber
0

Saya bekerja untuk sebuah perusahaan penerbitan yang berurusan dengan banyak buku-buku tua di mana kita sering tidak bisa mendapatkan tanggal pasti untuk segala hal. Kami biasanya memiliki dua bidang untuk entri tanggal tertentu, tanggal dan sekitar boolean:

date date
dateCirca enum('Y', 'N')

Kami menggunakan bidang tanggal untuk menunjukkan tanggal dari beberapa peristiwa, atau tanggal yang "cukup dekat" dalam kasus di mana kami tidak tahu tanggal yang sebenarnya. Jika kami tidak mengetahui tanggal sebenarnya, kami menandai dateCircabidang sebagai Ydan memberikan tanggal yang cukup dekat, yang ditandai sebagai "tanggal 1", seperti

1st March, 2013  // We don't know the day of the month
1st January, 2013  // We don't know the month/day of the year
1st January, 2000  // We don't know the month/day/year, we only know the century
user7007
sumber
0

Gambaran

Ada banyak kemungkinan representasi, dan dengan demikian skema database, untuk menyimpan tanggal fuzzy (atau bahkan hanya tanggal fuzzy):

  1. Tanggal-waktu dan kode menunjukkan ketepatan atau keakuratannya
  2. Tanggal-waktu dan interval di mana ada beberapa kemungkinan untuk mewakili suatu interval:
    1. Mewakili semua interval sebagai kuantitas bilangan bulat (atau angka lainnya) dari beberapa unit tetap, misalnya hari, menit, nanodetik.
    2. Menampilkan interval sebagai kuantitas integer (atau numerik lainnya) dan kode yang menunjukkan unitnya.
  3. Tanggal mulai dan berakhir
  4. Tali
  5. Distribusi kemungkinan:
    1. Kuantitas atau titik apung untuk parameter yang menentukan distribusi tertentu dalam kelompok tertentu, misalnya mean dan standar deviasi dari distribusi normal.
    2. Fungsi distribusi probabilitas, misalnya sebagai kode (pencarian) (berpotensi dengan parameter nilai tertentu), atau sebagai ekspresi dalam bahasa, format, atau representasi yang cukup ekspresif.

[1], [2], dan [3] adalah semua interval seragam (secara implisit), yaitu seperangkat (sama) poin yang mungkin dalam waktu.

[4] adalah yang paling ekspresif, yaitu ketika memungkinkan kalimat atau frasa bahasa tertulis yang memungkinkan (atau setidaknya panjang). Tapi itu juga yang paling sulit untuk dikerjakan. Dalam batas tersebut, AI tingkat manusia akan diperlukan untuk menangani nilai-nilai sewenang-wenang. Secara praktis, kisaran nilai yang mungkin perlu dibatasi secara ketat, dan nilai 'terstruktur' alternatif mungkin akan lebih disukai untuk banyak operasi, misalnya penyortiran, pencarian.

[5] mungkin merupakan representasi kompak paling umum yang (agak) praktis.

Interval Seragam

Interval yang seragam adalah cara ringkas paling sederhana untuk mewakili sekumpulan nilai waktu tanggal (mungkin).

Untuk [1], bagian-bagian dari nilai tanggal-waktu diabaikan, yaitu bagian-bagian yang terkait dengan unit yang lebih halus daripada presisi atau akurasi yang ditunjukkan; jika tidak, ini setara dengan [2] dan kode presisi / keakuratan setara dengan interval dengan unit yang sama (dan kuantitas tersirat dari 1).

[2] dan [3] secara ekuivalen setara. [1] sangat kurang ekspresif daripada karena ada interval efektif yang tidak dapat diwakili oleh [1], mis. tanggal-waktu fuzzy setara dengan interval 12 jam yang mencakup batas tanggal.

[1] lebih mudah bagi pengguna untuk memasukkan daripada representasi lainnya dan umumnya harus (setidaknya sedikit) kurang mengetik. Jika tanggal-waktu dapat dimasukkan dalam berbagai representasi teks, misalnya "2013", "2014-3", "2015-5-2", "7/30/2016 11p", "2016-07-31 18:15" , ketepatan atau keakuratan juga dapat disimpulkan secara otomatis dari input.

Keakuratan atau ketepatan [1] juga paling mudah untuk dikonversi ke formulir yang akan disampaikan kepada pengguna, misalnya '2015-5 dengan akurasi bulan' hingga "Mei 2015", dibandingkan "13 Mei 2015 2p, plus atau minus 13,5 hari" (perhatikan bahwa yang terakhir tidak dapat diwakili oleh [1] lagipula).

String

Secara praktis, nilai-nilai string perlu dikonversi ke representasi lain untuk kueri, mengurutkan, atau membandingkan beberapa nilai. Jadi, sementara bahasa alami (manusia) apa pun tertulis lebih ekspresif daripada [1], [2], [3], atau [5], kami belum memiliki cara untuk menangani lebih dari sekadar representasi atau format teks standar. Mengingat itu, ini mungkin representasi yang paling tidak berguna dengan sendirinya .

Salah satu keuntungan dari representasi ini adalah bahwa nilai-nilai harus, dalam praktiknya, dapat ditampilkan kepada pengguna apa adanya dan tidak memerlukan transformasi agar mudah dipahami.

Distribusi Probabilitas

Distribusi probabilitas menggeneralisasi representasi interval yang seragam [1], [2], [3], dan (bisa dibilang) setara dengan representasi string (umum) [4].

Salah satu keuntungan dari distribusi probabilitas dibandingkan string adalah bahwa yang pertama tidak ambigu.

[5-1] akan sesuai untuk nilai-nilai yang (sebagian besar) sesuai dengan distribusi yang ada, misalnya output nilai tanggal-waktu dari perangkat yang pengukurannya diketahui (atau dipikirkan) agar sesuai dengan distribusi tertentu.

[5-2] mungkin cara terbaik (agak) praktis untuk secara kompak mewakili nilai 'fuzzy datetime'. Tentu saja komputabilitas dari distribusi probabilitas khusus menggunakan hal-hal dan pasti ada masalah yang menarik (dan mungkin tidak mungkin) untuk dipecahkan ketika menanyakan, menyortir, atau membandingkan nilai-nilai yang berbeda, tetapi banyak dari ini mungkin sudah diketahui atau diselesaikan di suatu tempat pada saat ini literatur matematika dan statistik jadi ini jelas berdiri sebagai representasi yang sangat umum dan tidak ambigu.

Kenny Evitt
sumber
-1

Saya sangat menyukai solusi James Anderson - Membatasi tanggal secara akurat adalah cara untuk mendapatkan struktur permintaan yang paling fleksibel. Cara lain untuk mencapai hal yang sama adalah dengan menggunakan start, end atau bahkan pusat dateplus interval(tersedia setidaknya di PostgreSQL , Oracle dan SQLAlchemy ).

l0b0
sumber
-2

Dalam kasus Anda, Anda hanya perlu tahun, bulan, dan hari. Tahun dan bulan diperlukan, hari adalah opsional. Saya akan menggunakan sesuatu seperti itu:

year smallint not null,
month smallint not null,
day smallint

Plus, Anda masih dapat menggunakan indeks dengan sangat efektif. Antrian (kecil = minus, mendapatkan sedikit lebih "rumit" (lebih lama).

Pelaut Danubia
sumber
1
Tetapi ini berarti bahwa jika ketidakjelasan menelan bagian bulan juga, pendekatan ini gagal.
Anurag Kalia
1
@AnuragKalia - jadi buat bidang bulan tidak dapat dihapus. Tidak ada alasan ini tidak dapat dikonfigurasi ulang di kemudian hari.
JeffO
Itu hanya sebuah contoh. Solusinya harus cukup umum untuk mengakomodasi masalah di masa depan. Jika rentang yang Anda tentukan adalah 15 Mar 2013 hingga 22 Mar 2013, pendekatan ini tidak berfungsi. Jawaban min-max di atas adalah yang paling umum.
Anurag Kalia
1
Sudahkah Anda menemukan persyaratan seperti itu di pos OP atau itu hanya fantasi Anda?
Danubian Sailor
Menjadikan bulan tidak dapat dihapus memungkinkan Anda menentukan hari tetapi tidak ada bulan. Juga tidak masuk akal. Kapan itu 1978-??-31?
MSalters
-2

Saya hanya akan menyimpan waktu yang tepat untuk tanggal normal dan membuat bagian waktu dari tanggal fuzzy generik seperti 00:00:00. Saya kemudian akan membuat semua tanggal fuzzy tanggal 1 bulan itu.

Saat Anda bertanya, Anda

  1. periksa rentang tanggal di mana waktu juga sama dengan 00:00:00 (kabur)
  2. periksa rentang tanggal di mana waktu TIDAK sama dengan 00:00:00 (nyata)
  3. periksa rentang tanggal tetapi abaikan bagian waktu (gabungan)

Ada solusi yang lebih baik dari ini, tetapi saya pribadi benci metadata (data tentang data saya). Itu hanya memiliki kebiasaan keluar dari tangan setelah beberapa saat.

Kapten Kenpachi
sumber
2
bagaimana kesepakatan ini dengan tanggal nyata memiliki waktu 00:00:00?
Agak
Meskipun secara teori dimungkinkan untuk menambahkan tanggal nyata dengan waktu itu, itu tidak akan terjadi. Saya telah melihat tabel dengan jutaan baris dan tidak satupun dari mereka memiliki nilai waktu data di mana waktu adalah 00:00:00. Pragmatisme mengalahkan konvensi.
Kapten Kenpachi