“Bulanık tarihleri” bir veritabanında nasıl saklarsınız?


125

Bu birkaç kez karşılaştığım bir problem. Bir veritabanı tablosuna kaydetmek istediğiniz bir kaydınız olduğunu hayal edin. Bu tabloda "date_created" adlı bir DateTime sütunu vardır. Bu belirli bir kayıt uzun zaman önce oluşturuldu ve kesin tarih konusunda tam olarak emin değilsiniz, ancak yılı ve ayı biliyorsunuz. Sadece yılı bildiğin diğer kayıtlar. Gün, ay ve yılı bildiğiniz diğer kayıtlar.

Bir DateTime alanını kullanamazsınız, çünkü "Mayıs 1978" geçerli bir tarih değildir. Birden çok sütuna bölerseniz, sorgulama yeteneğini kaybedersiniz. Başkası bununla karşılaştı mı, eğer öyleyse nasıl başardın?

Yaptığım sistemi netleştirmek için arşivleri izleyen bir sistem. Bazı içerikler uzun zaman önce üretildi ve bildiğimiz tek şey "Mayıs 1978". 1 Mayıs 1978'de saklayabilirim, ancak bu tarihin yalnızca ay için doğru olduğunu belirtmek için bir yolla. Bu şekilde birkaç yıl sonra o arşivi alırken tarihler uyuşmadığında kafam karışmaz.

Benim amaçlarıma göre, "19 Mayıs 1978’deki bilinmeyen günü" ile "1 Mayıs 1978" arasında ayrım yapmak önemlidir. Ayrıca, bilinmeyenleri "0 Mayıs 1978" gibi 0 olarak saklamak istemem çünkü çoğu veritabanı sistemi bunu geçersiz bir tarih değeri olarak kabul edecektir.


14
"1978 Mayıs'ındaki bilinmeyen gün" ile "1 Mayıs 1978" arasındaki farkı ayırt etmek önemli mi?

5
@MichaelT: Evet, ayırt etmek önemlidir.
nbv4


6
@aslum: Çoğu veritabanı sistemi geçersiz bir tarih değeri olarak bunu reddedecek
nbv4

9
@JimmyHoffa - Asla bulanık tarihler senaryosuna ya da tarihleri ​​karşılaştırmak için ihtiyaç duyduğunuz birine rastlamadınız mı? Her iki durumda da, bilinen bir tıp tarihidir: apendektominin 1 Nisan'da geçen yıl olduğunu, ancak tonsilektominin bazen 1975'te olduğunu ve bir yılın Mayıs ve Haziran aylarında başka bir şey olduğunu hatırlarsınız. Bazı tıbbi olayların başka bir tıbbi buluştan önce mi, yoksa sonra mı olduğunu bilmek istiyorsanız? Bu, kan dolaşımını HIV için kontrol etmeden önce mi, sonra mı oldu?
perşembe günleri,

Yanıtlar:


148

Tüm tarihleri ​​veritabanında normal DATE alanına kaydedin ve DATE alanının gerçekte ne kadar doğru olduğunu ek bir doğruluk alanına sahip olun.

date_created DATE,
date_created_accuracy INTEGER, 

date_created_accuracy: 1 = kesin tarih, 2 = ay, 3 = yıl.

Randevunuz belirsizse (örneğin Mayıs 1980) dönemin başında saklayın (ör. 1 Mayıs 1980). Veya tarihiniz yıl için doğruysa (örneğin 1980) 1 Ocak olarak saklayın. 1980 karşılık gelen doğruluk değeri ile.

Bu yol kolayca doğal bir şekilde sorgulayabilir ve tarihlerin ne kadar doğru olduğu konusunda fikir sahibi olabilir. Örneğin bu arasındaki tarihleri sorgulamak için izin verir Jan 1st 1980ve Feb 28th 1981, ve bulanık tarihleri almak 1980ve May 1980.


1
Burada tarih-sonu görebildiklerimden hesaplamanız gerekiyor, bu yüzden en iyisi seçtiğiniz hesaplanmış bir alana sahip olduğunuzda sorgu arasında oldukça çirkin olduğunu düşünüyorum.
Wyatt Barnett

8
Güzel cevap, gerçekten akıllı. select * from mytable where date_created between "1980/1/1" and "1981/2/28" and date_created_accuracy <= 2;. Cin.
Naftuli Kay

58
Tarih doğruluğunu sadece "günler" olarak düşünmenizi tavsiye ederim. Kesin bir gün 0'dır. Bu yolla, zor kodlanmış belirli tarih aralıkları yerine 1 Haziran tarihine dayanarak 90 günlük tarih doğruluğu olan "yaz mevsiminde" daha esnek tarihler kullanılabilir. Aynı zamanda çok yıllı doğruluğu da kaldırabilirdi.

1
Bunu bir cevap olarak vermelisin, MichaelT
Supr

1
+1: Bu çözümle ilgili başka güzel bir şey daha sonra date_created_accuracyalanın değerini temel alarak ekran mantığı ekleyebilirsiniz . Alanın gösterdiği kadar doğru olması halinde, sonuçlarda veya kullanıcı arayüzünde "Mayıs 1980" veya yalnızca "1980" i gösterebilirsiniz.
Kyralessa

27

Bu tür verileri normal tarih-saat bilgisi olarak kullanmanız gerekmiyorsa, basit bir dize formatı kullanır.

Ancak, tüm işlevselliği korumanız gerekirse, her ikisi de veritabanında depolanan ek bilgileri gerektiren, düşünebildiğim iki geçici çözüm vardır:

  1. "Eksik" veriler için farklı değerlere sahip olan min dateve max datekesin tarihler için geçerli olan alanlar oluşturun .
  2. Her yanlış tarih türü için türler oluşturun (hiçbiri _ 0, date_missing _ 1, month_missing _ 2, year_missing_4, vb _ onları birleştirmek için). typeKayıtlara bir alan ekleyin ve hangi bilgilerin eksik kalmasını sağlayın.

Min ve max tarih alanları benim de ilk düşüncemdi.
Michael Itzoe

1
Uzun zaman önce, aynı sorunu çözmek zorunda kaldık. Kullanıcılar geçmişte herhangi bir zamanda gerçekleşen olaylar hakkında hikayeler anlatabiliyordu, bu yüzden bulanık tarihleri ​​desteklememiz gerekti. Geri dönüp durduktan sonra, ulaştığımız çözüm en çok superM'in önerisine benzer, burada tarihler hikayenin tarihini içerecek en düşük ve en fazla olası bilgi kaynağı olarak depolanır. Tarihi bildirirken, doğruluk (yani "bu kayıt ay / yıl / gün için doğrudur") minimum ve maksimum tarihler arasındaki deltadan çıkarılabilir. Doğruluk için 3. bir alanı kaydetmeye gerek yoktur.
meetamit

4
+1 min dateve max datealanlar için. Bunun en esnek, ancak kesin ve kullanımı kolay bir çözüm olduğunu düşünüyorum.
Supr

1
İlk başta bu fikre karşı düşmanca davrandım. Ancak bunun en esnek yaklaşım olduğunun farkındayım, buna oy veriyorum.
Anurag Kalia

O sadece doğal. Bulanık bir tarihi değil, bir başlangıcı ve sonu olan bir zaman dilimini ... çok fazla tanımlıyorsunuz.
Pieter B,

20

Bu gerçekten teknik bir problemden çok bir ihtiyaç tanımından daha fazlasıdır - odaklanmanız gereken şey “geçmişte tarihleri ​​nasıl tanımlayabiliriz” ve teknik çözüm akacaktır.

Böyle bir şeye yaklaşmak zorunda kaldığım zamanlar genelde:

  • Bir şeylerin nasıl haritalanacağını tanımlayın - MichaelT'nin önerdiği gibi , Ay / Gün olarak tanımlanan herhangi bir şeyin, söz konusu ayın 1'inde gece yarısı olarak tanımlanmasına karar verin. Bu genellikle çoğu amaç için yeterince iyidir - eğer kesin tarih bu kadar önemliyse, muhtemelen 35 yıl sonra bir rekoruna sahip olacaksınız, değil mi?
  • Bunu izlemeniz gerekip gerekmediğini anlayın - IE, biraz oluşturulmuş tarihler içeren kayıtların bir bayrak söylemesi gerekiyor mu? Yoksa bu sadece bir kullanıcı eğitimi meselesidir, böylece insanlar bilir ve buna göre davranabilir.

Bazen, tarihleri ​​bulanıklaştırmak gibi bir şey yapmanız gerekebilir - örneğin, bir tarih Mayıs 1978’deki herhangi bir sorguyu yanıtlamanız gerekebilir. Bu yapılabilir - create_date 2 alanlarınızı eski yapın, 30 Günler uygun şekilde yayıldı, yenileri 2 aynı değere sahip.


1
+1 - İki tarih yaklaşımı ile bir cevap formüle etmek için çalışıyordum. Cevabınız önce buraya geldi.

2
+1, Çirkin ve gerektirmeyen yeni girişler için çok fazla gereksiz bilgi yaratıyor, ancak diğer yandan sorguları diğerlerinden daha basit tutuyor. Bir süredir benzer bir çözümü ilgili bir sorun için kullanıyoruz.
Izkata

3
@Izkata - Adil nokta, ancak ayda bir tek nokta olması gereken bir şeyi yapmanız gerektiğinde ne kadar da şık olursunuz. Kesinlikle bir yerde anında sorgular için başlangıç ​​ve bitiş hesaplamak zorunda daha güzel.
Wyatt Barnett

1
Enum değerleri patlaması olmadan rastgele ayrıntı derecesini gösterebilme özelliği için +1.
Dan Neely,

18

Tarihin doğru olup olmadığını göstermenin en basit yolu, varsayılan NULL değerine sahip bir INT (1) doğruluk alanı oluşturmaktır.

Tarih "date_created" deki tarih ve saatin doğru olduğu bir tarihse ve doğruluktan ayrılsın NULL

Tarih yalnızca ayın tarihine doğruysa, tarih-saatini doğruluk değeri 1 olan Ay'ın 1'i olarak

Eğer tarih sadece yıl boyunca doğruysa, doğruluk değeri 2 olan 1 Ocak tarih-tarihi

İlk çeyrek vb. Gibi farklı değerleri tutmak için farklı sayıları kullanabilirsiniz.


Bunu yaptığınızda sorgular gerçekten kıllı hale gelir.
Blrfl

3
Bu, “2. Çeyrek 1991” ve “Kış 1978-1979” gibi temiz bir ay sınırları içinde olmayan veriler konusunda güçlük çekiyor.

1
OP, bu tarihin sadece ay için doğru olduğunu belirtmek için bir yol istiyor.
david strachan

7
Burada NULL'un anlamını kötüye kullanıyorsun. NULL "bilinmeyen" anlamına gelir, yani tarih doğruysa doğruluk NULL olamaz. '1' olabilir.
Konerak

@Konerak Anlamsal olarak evet. Ancak tarihlerin çoğu doğru olduğundan, yalnızca özel durumların tanımlanması ve burada NULL kullanılarak varsayılan olarak kullanılması gerekir.
david strachan

17

Geçmişte başlangıç ​​tarihi ve bitiş tarihi olarak doğrulukla tarihleri ​​sakladım. 21212012 günü başlangıç ​​= 12 am, may 21, 2012 ve bitiş = 12 am, may 22, 2012 olarak temsil edilecektir. 2012 yılı, başlangıç ​​= 12, Ocak1,2012 sonu = 12, Ocak1,2013 olarak temsil edilecektir.

Bu yaklaşımı tavsiye edip edemeyeceğimden emin değilim. Kullanıcıya bilgileri görüntülerken, bir tarih aralığının tam olarak bir günü kapsayan iki aşırı spesifik son nokta yerine "25 Mayıs" göstermesi için tam olarak bir günü kapsadığını tespit etmeniz gerekir (bu, gün ışığından yararlanma vb. İle ilgilidir).

Ancak, insana tercüme etmeye çalışmadığınızda, uç noktalarla programlama, merkez + hassasiyetinden çok daha kolaydır. Birçok dava ile bitmiyorsun. Bu oldukça hoş.


Aslında, aralığın her zaman UTC olarak depolanması durumunda bir aralığın nasıl sunulacağını belirlemek o kadar zor olmak zorunda değildir. UTC zaman damgaları olarak, her gün, hafta, ay, yıl - hatta mevsimler ve çeyrekler - dönemin başlangıcını ve sonunu temsil eden iki sabit, küresel, belirgin ve kolayca belirlenebilir sayıya sahip olacaktır. Mantık, iki tarihin bir dönemin başında ve sonunda olup olmadığını görmek için birkaç if-ifadesi haline gelir. Hiçbir karmaşık matematik veya zaman dilimi şeyler gerekli :)
Supr

@Supr Belirli bir saniyenin belirli bir insan periyodunun sınırında olup olmadığının belirlenmesi, kendi başına zor bir problemdir. Özellikle uzun vadede, Dünya'nın rotasyonu yavaşlar ve yerel zamanın insan tanımında küçük değişiklikler olur.
Craig Gidney

14

Neden iki tarih saklamıyorsun?

Created_After ve Created_Before. Asıl anlam "" üzerinde veya sonra yaratılmış "ve" üzerinde veya önce yaratılmış "

Yani kesin tarihi biliyorsanız, Created_After ve Created_Before aynı tarihte olacaktır.

Mayıs 2000'de ilk hafta olduğunu biliyorsanız, Created_After = '2000-05-01' ve Created_Before = '2000-05-07'.

Sadece Mayıs 1999’ı biliyorsanız, o zaman değerler 1999 1999-05-01 ’ve 1999 1999-05-30’ olacaktır.

Eğer '42'nin Yaz'ı ise, o zaman değerler '1942-06-01' ve '1942-08-31' olur.

Bu şema normal SQL ile sorgulamak kolaydır ve teknik olmayan bir kullanıcının izlemesi oldukça kolaydır.

Örneğin , Mayıs 2001'de oluşturulmuş olabilecek tüm belgeleri bulmak için :

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

Tersine , Mayıs 2001'de kesinlikle oluşturulan tüm belgeleri bulmak :

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

1
Bunun en zarif çözüm olduğunu düşünüyorum.
Pieter B,

Bu, superM ve Strilanc'ın cevaplarıyla aynı. +1 daha net bir şekilde açıklamak ve sorgulamanın ne kadar basit olduğunu göstermek için.
Supr

9

ISO 8601 tarih saat biçimi, örneğin;

2012-01-01P1M (okuma: 2012, 1 Ocak, dönem: 1 ay) “Ocak 2012'de” ne olması gerektiğidir.

Bunu verileri depolamak için kullanırdım . Bunu yapmak için String türünde bir veritabanı alanına ihtiyacınız olabilir. Bu konuda mantıklı bir arama yapılması farklı bir konudur.


Fikir için +1, ancak arama ve / veya bulmanın nedeni için bir tarih alanı kullanmadığı için -1
kullanıcı151019

Veritabanına bağlı. Bununla birlikte, bu genişlemenin temelini oluşturabilir, ancak soru şudur: Sonuçtaki belge, arama yapıyorsanız, bu durumda, 12 Ocak'tan daha yeni olan tüm belgeleri arayacak mı, yoksa değil mi? Önemsiz değil. Burada soru bulanık tarihlerin nasıl depolanacağıydı .
Matthias Ronge

3

Genel olarak, bunları hala daha az doğru olsa bile, genel sorgu işleme tarihleri ​​olarak saklıyorum.

Geçmişte bulunduğum doğruluğu bilmek önemliyse ya +/- ondalık, ya da arama (gün, ay, yıl, vb.) Olarak bir doğruluk "penceresi" kaydedilmiş. Pencere yerine diğer durumlarda, sadece orijinal tarih değerini bir dize olarak saklıyorum ve verdiğiniz örnek için muhtemelen 1978-05-01 00:00:00 ve "Mayıs 1978" tarihlerini değiştirebiliyorum.


3

Birden çok sütuna bölerseniz, sorgulama yeteneğini kaybedersiniz.

Kim söylüyor? İşte yaptığınız şey:

  1. 3 sütun, Gün, Ay, Yıl, int türünün her biri ve dördüncü sütun The DateTime türünün tarihi.
  2. TheDate boş bırakılmışsa ancak Gün, Ay, Yıl alanlarından birinin veya daha fazlasının değeri varsa, TheDate oluşturmak için Gün, Ay, Yıl 3 sütununu kullanan bir tetikleyici kullanın.
  3. TheDate verildiğinde Gün, Ay, Yıl alanlarını dolduran ancak bu alanların doldurulmadığını gösteren bir tetikleyici kullanın.

Öyleyse şöyle bir ekleme insert into thistable (Day, Month, Year) values (-1, 2, 2012);yaparsam, o zaman TheDate 2/1/2013 olacak, ancak 2/2012'de Gün alanındaki -1 nedeniyle gerçekten belirsiz bir tarih olduğunu bileceğim.

Eğer o insert into thistable (TheDate) values ('2/5/2012');zaman Gün 5 olacak, Ay 2 olacak ve Yıl 2012 olacak ve bunların hiçbiri -1 olmadığından bunun kesin tarih olduğunu bileceğim.

Insert / update tetiği 3 alanımın (Gün, Ay, Yıl) her zaman TheDate'de sorgulanabilecek bir DateTime değeri üretmesini sağladığından, sorgulama yeteneğimi kaybetmiyorum.


3

Diğer bir seçenek ise tarihleri ​​formun tamsayıları olarak depolamak olacaktır YYYYMMDD.

  • Sadece senenin 1951 olduğunu biliyorsun: 19510000
  • Ayın ve yılın Mart 1951 olduğunu biliyorsunuz. 19510300
  • Biliyorsunuz tam tarih 14 Mart 1951: Mağaza olarak 19510314
  • Tamamen bilinmeyen bir tarih: Farklı sakla 0

Yararları

Bulanık tarihinizi iki tarih alanı yerine bir alanda veya bir tarihte ve diğer cevapların çoğunun önerdiği doğrulukta saklayabilirsiniz.

Sorgular hala kolaydır:

  • 1951 yılına ait tüm kayıtlar - SELECT * FROM table WHERE thedate>=19510000 and thedate<19520000
  • Mart 1951 için tüm kayıtlar - SELECT * FROM table where thedate>=19510300 and thedate<19510400
  • tüm kayıtlar 14 mart 1951 - SELECT * FROM table where thedate=19510314

NOTLAR

  • GUI'nizin GetDateString(int fuzzyDate)uygulanması oldukça kolay olan bir şeye ihtiyacınız var .
  • İnt formatı ile sıralama kolaydır. Bilinmeyen tarihlerin önce geleceğini bilmelisin. Bunu ay veya gün 99yerine 'doldurma' işlevini kullanarak tersine çevirebilirsiniz 00.

"1941-1942 kışı" nın bulanık tarihini nasıl temsil ediyorsunuz? Aralık 1941 veya Ocak 1942 olabilir.

1
Sorunuz genel bir çözüm vakasıyla ilgilidir. Asıl soru bunu problem olarak listelemiyor. Gönderilen soruya bağlı olarak, bazen tam tarih, bazen sadece yıl ve ay ve bazen de sadece yıl bilinmektedir. Bulanık tarih aralığındaki hiçbir sorun şart olarak belirtilmemiştir. Bu sorunu çözmeniz gerekiyorsa iki tarihe ihtiyacınız olduğunu kabul ediyorum (ancak, aralığı iki "bulanık tarih inç" olarak saklamak, iki "zor" tarihi saklamak için daha fazla esneklik sağlayabilir).
Rick

1

ISO 8601 ayrıca "bulanık tarihler" için bir sözdizimi de belirtir. Öğleden sonra saat 3'de 12 Şubat 2012'de "2012-02-12T15", Şubat 2012'de ise "2012-02" olabilir. Bu, standart sözlük bilgisi sıralamasını kullanarak güzel bir şekilde uzanır:

$ (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

0

İşte benim bu konuda benim:

Bulanık tarihten datetime nesnesine gidin (bir veritabanına sığacak)

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

Sonra datetime nesnesini alan ve tekrar bulanık bir tarihe taşıyan bir işlev.

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

Ve sonra bir birim testi. Herhangi bir vakayı özledim mi?

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'

Kesin olarak gerçekleştiği bir olay olduğu 2001-01-01T00:00:00.333333halde, sistemin sadece "2001" olarak yorumlayacağı ancak bunun pek olası görünmediği bir köşe durumu var .


0

Çoğu şey için kesin tarihleri ​​bulamadığımız birçok eski kitapla ilgilenen bir yayıncılık şirketi için çalışıyorum. Belirli bir tarih girişi için genellikle iki alanımız vardır, tarih ve yaklaşık boolean:

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

Tarih alanını bazı etkinliklerin tarihini veya gerçek tarihi bilmediğimiz durumlarda "yeterince yakın" bir tarihi belirtmek için kullanırız. Gerçek tarihi bilmiyorsak, dateCircaalanı olduğu gibi Yişaretler ve "1" olarak işaretlenen, yeterince yakın bir tarih veririz ;

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

0

genel bakış

Bulanık tarih zamanlarını (ya da sadece bulanık tarihleri ​​bile) saklamak için birçok olası temsil ve dolayısıyla veritabanı şemaları vardır:

  1. Hassasiyet veya doğruluğunu gösteren tarih ve kod
  2. Bir aralığı temsil etmek için çeşitli olasılıkların olduğu tarih-zaman ve aralık:
    1. Tüm aralıkları, bazı sabit birimlerin tam sayı (veya başka bir sayısal) miktarı, örneğin günler, dakikalar, nanosaniyeler gibi gösterir.
    2. Bir tamsayı (veya başka bir sayısal) miktar olarak bir aralığı ve birimlerini belirten bir kodu temsil eder.
  3. Başlangıç ​​ve bitiş tarihi-zamanları
  4. sicim
  5. Olasılık dağılımı:
    1. Belirli bir ailede belirli bir dağılımı belirten parametreler için ondalık ya da kayan nokta miktarları, örneğin normal bir dağılımın ortalama ve standart sapması.
    2. Olasılık dağılım işlevi, örneğin (arama) kodu (potansiyel olarak belirli değerlerin parametreleriyle birlikte) veya yeterince açıklayıcı bir dilde, formatta veya göstergede ifade olarak.

[1], [2] ve [3] tümü (dolaylı olarak) tek biçimli aralıklardır, yani zaman içinde (eşit olarak) olası noktalardan oluşan bir kümedir.

[4] en etkileyicidir, yani herhangi bir olası (veya en azından keyfi bir şekilde uzun) yazılı dil cümleleri veya ifadelerine izin verirken. Ama aynı zamanda birlikte çalışması en zor olanı. Sınırda, isteğe bağlı değerleri ele almak için insani seviye AI gerekli olacaktır. Pratik olarak, olası değerlerin aralığının ciddi şekilde kısıtlanması gerekecek ve alternatif “yapılandırılmış” değerler muhtemelen birçok işlem için, örneğin sıralama, arama gibi tercih edilecektir.

[5] muhtemelen (biraz) pratik olan en genel kompakt temsildir.

Düzgün Aralıklar

Düzgün aralıklar, (olası) bir tarih-zaman değerleri kümesini temsil etmenin en basit ve küçük yoludur.

[1] için, tarih-zaman değerinin bazı kısımları göz ardı edilir; yani, belirtilen hassasiyet veya hassasiyetten daha ince birimlere karşılık gelen kısımlar; Aksi halde, bu [2] 'ye eşittir ve hassasiyet / doğruluk kodu aynı birimlerle (ve ima edilen miktarda 1) bir aralığa eşdeğerdir.

[2] ve [3] açıkça eşdeğerdir. [1], [1] ile temsil edilemeyecek etkili aralıklar olduğu için kesinlikle daha az anlamlıdır. Bir tarih sınırına yayılan 12 saatlik bir aralığa denk olan bulanık bir tarih-saat.

[1], kullanıcıların herhangi bir diğer gösterime göre girmeleri daha kolaydır ve genellikle (en azından biraz) daha az yazı yazması gerekir. Tarih zamanları çeşitli metin gösterimlerinde girilebilirse, örneğin "2013", "2014-3", "2015-5-2", "7/30/2016 11p", "2016-07-31 18:15" hassasiyet veya doğruluk da girdiden otomatik olarak çıkarılabilir.

[1] 'in doğruluğu ya da kesinliği, kullanıcılara iletilecek bir forma dönüştürmek için en kolay yoldur, örneğin,' 13 Mayıs 2015 2p artı ya da eksi 13,5 gün "yerine '2015-5 ay doğruluğu ile'" Mayıs 2015 "e (Tho ikincisinin [1] tarafından temsil edilemeyeceğini unutmayın).

Teller

Pratik olarak, dize değerlerinin birden fazla değeri sorgulamak, sıralamak veya başka şekilde karşılaştırmak için diğer temsillere dönüştürülmesi gerekir. Dolayısıyla, herhangi bir yazılı doğal (insan) dil [1], [2], [3] veya [5] öğesinden kesinlikle daha anlamlı olsa da, standart metin sunumları veya biçimlerinin ötesinde çok şey kullanma imkanımız yoktur. Buna bakıldığında, bu muhtemelen kendi başına en az yararlı temsildir .

Bu gösterimin tho bir avantajı, değerlerin pratikte olduğu gibi kullanıcılara olduğu gibi gösterilebilir olması ve kolayca anlaşılması için dönüşüm gerektirmemesidir.

Olasılık Dağılımları

Olasılık dağılımları düzgün aralıklı gösterimleri genelleştirir [1], [2], [3] ve (tartışmalı) (genel) dizi temsiline [4] eşdeğerdir.

Dizgelere göre olasılık dağılımının bir avantajı, birincisinin kesin olmasıdır.

[5-1] (çoğunlukla) mevcut bir dağılıma uyan değerler için uygun olacaktır; örneğin, ölçümlerin belirli bir dağılıma uyduğu bilinen bir cihazdan (ya da sanılan) çıkan bir tarih-zaman değeri çıktısı.

[5-2], muhtemelen en iyi (biraz), pratik bir yoldur kompakt rasgele 'bulanık tarih saat değerlerini temsil etmektedir. Tabii ki, kullanılan belirli olasılık dağılımlarının hesaplanabilirliği önemlidir ve farklı değerleri sorgularken, sıralarken veya karşılaştırırken çözülmesi gereken ilginç (ve belki de imkansız) problemler vardır, ancak bunların çoğu halihazırda bir yerde zaten bilinir veya çözülür. matematiksel ve istatistiksel literatür bu yüzden bu kesinlikle son derece genel ve belirsiz bir temsil olarak duruyor.



-2

Senin durumunda sadece yıl, ay ve gün gerekir. Yıl ve ay gereklidir, gün isteğe bağlıdır. Böyle bir şey kullanırdım:

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

Artı, hala çok etkili bir şekilde indeksleri kullanabilirsiniz. (Minik = eksi, kuyruklar biraz daha "karmaşık" olur (daha uzun).


1
Ancak, eğer belirsizlik ayın bir kısmını da yükseltirse, bu yaklaşım başarısız olur.
Anurag Kalia

1
@AnuragKalia - bu nedenle ay alanını boşuna çevirin. Bunun daha sonraki bir tarihte yeniden yapılandırılmasının bir nedeni yoktur.
JeffO

Bu sadece bir örnekti. Çözüm gelecekteki sorunları karşılayacak kadar genel olmalıdır. Belirttiğiniz aralık 15 Mart 2013 - 22 Mart 2013 arasındaysa, bu yaklaşım işe yaramaz. Yukarıdaki min-max cevabı henüz en genel olanıdır.
Anurag Kalia

1
OP'lerin gönderisinde bu tür bir gereksinim buldunuz mu yoksa sadece fanteziniz mi?
Danubian Sailor,

Ayın boş bırakılması, bir gün belirtmenizi sağlar, ancak ay belirtmez. Hiçbir anlam ifade etmiyor. Ne zaman oldu 1978-??-31?
MSalters

-2

Sadece normal tarihler için tam zamanı saklar ve bulanık tarihin zaman kısmını 00:00:00 gibi jenerik yapardım. O zaman bütün bulanık tarihleri ​​ayın 1'inde yapardım.

Sorguladığınızda

  1. Saatin 00:00: 00'a eşit olduğu tarih aralıklarını kontrol et (belirsiz)
  2. Saatin 00:00: 00'a eşit olmadığı tarih aralıklarını kontrol et (gerçek)
  3. tarih aralıklarını kontrol et ancak zaman bölümünü göz ardı et.

Bundan daha iyi çözümler var, ancak meta verilerden nefret ediyorum (verilerimle ilgili veriler). Sadece bir süre sonra elden çıkma alışkanlığı var.


2
Gerçek tarihle 00:00:00 arasında olan bu durum nasıl olurdu?
gnat

O zamana gerçek bir tarih eklemek teorik olarak mümkün olsa da, olmayacak. Milyonlarca satır içeren tablolar gördüm ve bunlardan hiçbirinin saat 00:00:00 olduğu tarihin değeri yoktu. Pragmatizm kongre kurallarına uymuyor.
Kaptan Kenpachi,
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.