Pertanyaan Apakah ada standar untuk interval waktu inklusif / eksklusif?


Saya ingin tahu apakah ada standar atau "normal" berarti menafsirkan titik akhir data interval waktu sehubungan dengan inklusivitas / eksklusivitas nilai yang mendefinisikan titik akhir. Namun perlu dicatat bahwa saya bertanya apa standar (atau paling umum) Konvensi adalah (jika ada), bukan untuk disertasi tentang preferensi pribadi Anda. Jika Anda benar-benar ingin memberikan disertasi, lampirkan ke referensi standar yang diterbitkan seseorang atau teks standar tentang masalah tersebut. Standar terbuka (yang tidak perlu saya bayar untuk dibaca) sangat disukai kecuali mereka pada dasarnya cacat :).

Tentu saja ada 4 kemungkinan untuk interval waktu dari A ke B:

  1. (A, B) - Kedua ujungnya eksklusif.
  2. [A, B] - Kedua ujung bersifat inklusif.
  3. [A, B) - Start bersifat inklusif dan end bersifat eksklusif
  4. (A, B] - Mulai bersifat eksklusif dan akhir bersifat inklusif

Masing-masing memiliki karakteristik yang berbeda (seperti yang saya lihat, jangan ragu untuk menunjukkan lebih banyak)

Konvensi [A, B] akan memiliki properti yang tampaknya tidak nyaman bahwa B terkandung dengan inteval [A, B] dan juga [B, C]. Ini sangat tidak nyaman jika B dimaksudkan untuk merepresentasikan batas tengah malam dan Anda mencoba untuk menentukan pada hari mana ia jatuh sebagai contoh. Juga, ini berarti durasi interval sedikit irritatig untuk menghitung sejak [A, B] di mana A = B harus memiliki panjang 1 dan karena itu durasi [A, B] adalah (B - A) +1 

Demikian pula konvensi (A, B) akan memiliki kesulitan bahwa B tidak masuk dalam (A, B) atau (B, C) ... melanjutkan analogi dengan batas hari, tengah malam akan menjadi bagian dari hari. Ini juga secara logis tidak nyaman karena [A, B] di mana A = B adalah interval non-akal dengan durasi kurang dari nol, tetapi membalik A dan B tidak membuatnya menjadi interval yang valid.

Jadi saya pikir saya ingin [A, B], atau (A, B) dan saya tidak tahu bagaimana memutuskan di antara mereka.

Jadi, jika seseorang memiliki tautan ke dokumen standar, rujuk ke teks standar atau serupa yang memperjelas konvensi yang akan menjadi hebat. Sebagai alternatif, jika Anda dapat menghubungkan berbagai dokumen standar dan / atau referensi yang kurang lebih sepenuhnya gagal untuk disetujui, maka saya dapat memilih satu yang tampaknya memiliki kewenangan yang cukup untuk CMA dan diselesaikan dengan itu :).

Akhirnya, saya akan bekerja di Jawa, jadi saya sangat rentan terhadap jawaban yang bekerja dengan baik di Jawa.


32
2018-03-20 21:38


asal


Jawaban:


Dalam kasus umum, [A, B) memiliki banyak hal untuk itu dan saya tidak melihat alasan mengapa hal yang sama tidak berlaku untuk interval waktu.

Djikstra menulis artikel bagus tentangnya Mengapa penomoran harus dimulai dari nol yang - terlepas dari namanya - kebanyakan berurusan dengan hal ini.

Ringkasan singkat keuntungannya:

  • end - start sama dengan jumlah item dalam daftar
  • batas atas interval sebelumnya adalah batas bawah berikutnya
  • memungkinkan untuk mengindeks interval mulai dari 0 dengan angka yang tidak ditandatangani [1]

Secara pribadi, poin kedua adalah sangat berguna untuk banyak masalah; mempertimbangkan fungsi rekursif yang cukup standar (dalam python semu):

def foo(start, end):
    if end - start == 1:
        # base case
    else:
        middle = start + (end - start) / 2
        foo(start, middle)
        foo(middle, end)

Menulis yang sama dengan batas atas inklusif memperkenalkan banyak kesalahan yang rawan oleh satu kesalahan.

[1] Itulah kelebihan dibandingkan (A, B] - interval mulai dari 0 jauh lebih umum daripada interval yang diakhiri dengan MAX_VAL. Perhatikan bahwa juga berkaitan dengan satu masalah tambahan: Menggunakan dua batas inklusif berarti kita dapat menunjukkan urutan yang panjangnya tidak dapat diekspresikan dengan ukuran yang sama.


37
2018-03-21 18:09



Saya akan memberikan apa yang saya tulis untuk tim kami sebagai jawaban menggunakan tautan Voo sampai saat Voo menambahkan jawaban, maka saya akan memberinya kredit sebagai gantinya. Inilah yang saya putuskan untuk kasus kami:

Interval waktu dalam aplikasi kami akan diwakili sebagai sepasang   waktu sesaat dengan konvensi bahwa waktu mulai adalah   inklusif dan waktu akhir bersifat eksklusif. Konvensi ini   matematis nyaman karena perbedaan batas adalah   sama dengan panjang interval, dan juga numerik   konsisten dengan cara array dan daftar yang ditulis dalam java   program (lihat http://www.cs.utexas.edu/~EWD/ewd08xx/EWD831.PDF). Itu   hasil praktis dari ini adalah interval 2012-03-17T00: 00: 00.000Z -   2012-03-18T00: 00: 00.000Z menandakan keseluruhan Hari St. Patrick,   dan setiap tanggal yang dimulai dengan 2012-03-17 akan diidentifikasi sebagai   termasuk dalam Hari St Patrick, tetapi 2012-03-18T00: 00: 00.000Z tidak akan   disertakan, dan Hari St Patrick akan mencakup tepat 24 * 60 * 60 * 1000   milidetik.


4
2018-03-21 14:59



Saya tidak bisa mengatakan dengan pasti, tapi saya ragu ada standar atau konvensi. Apakah Anda menyertakan awal atau akhir instan akan tergantung pada kasus penggunaan Anda, jadi pertimbangkan apakah itu penting bagi Anda. Jika keputusan itu sewenang-wenang, pilih satu, perhatikan bahwa pilihan itu sewenang-wenang dan pindah.

Adapun apa yang didukung di Jawa, alat perpustakaan Joda Time IntervalItu termasuk waktu mulai tetapi bukan waktu akhir


2
2018-03-20 21:45



Meskipun thread ini lebih fokus pada Java, saya pikir itu akan sangat menarik untuk melihat konvensi lain yang diadopsi, terutama mengingat bahwa pandas Python Perpustakaan di mana-mana untuk analisis data hari ini, dan fakta bahwa halaman StackOverflow ini adalah salah satu hasil pencarian teratas ketika mencari konvensi tentang inklusivitas / eksklusivitas rentang waktu.

Mengutip halaman ini:

Tanggal mulai dan akhir sangat inklusif. Jadi tidak akan menghasilkan tanggal di luar tanggal tersebut jika ditentukan.

Selain itu, ini tidak hanya menghasilkan rentang tanggal. Konvensi ini juga diadopsi ketika mencoba untuk mengindeks ke dalam data time-series. Berikut ini tes sederhana pada frame data dengan DatetimeIndex

>>> import pandas as pd
>>> pd.__version__
'0.20.2'
>>> df = pd.DataFrame(list(range(20)))
>>> df.index = pd.date_range(start="2017-07-01", periods=20)
>>> df["2017-07-01":"2017-07-05"]
            0
2017-07-01  0
2017-07-02  1
2017-07-03  2
2017-07-04  3
2017-07-05  4

1
2017-08-02 19:23



java.time & Setengah Terbuka

Itu java.time kelas yang menggantikan kelas tanggal-waktu warisan yang sulit serta proyek Joda-Time mendefinisikan rentang waktu menggunakan pendekatan Setengah-Terbuka [) di mana awalnya adalah inklusif sedangkan endingnya eksklusif.

Untuk tanggal-waktu dengan detik pecahan ini menghilangkan masalah mencoba untuk menangkap momen terakhir. Selisih kedua yang tak dapat dipisahkan harus diselesaikan, tetapi berbagai sistem menggunakan berbagai perincian seperti milidetik, mikrodetik, nanodetik, atau yang lain. Dengan Setengah Terbuka, sehari, misalnya, dimulai pada saat pertama hari dan berjalan hingga, tetapi tidak tidak termasuk, momen pertama di hari berikutnya. Masalah dipecahkan, tidak perlu bergumul dengan momen terakhir hari itu dan detik-detik pecahannya.

Saya telah melihat manfaat menggunakan pendekatan ini secara konsisten di seluruh kode penanganan tanggal-tanggal saya. Seminggu misalnya mulai pada hari Senin berjalan hingga, tetapi tidak termasuk, hari Senin berikutnya. Satu bulan dimulai pada tanggal 1 dan berjalan hingga, tetapi tidak termasuk, yang pertama dari bulan berikutnya dengan demikian mengabaikan tantangan untuk menentukan jumlah hari terakhir bulan termasuk 28 Desember Tahun Leap 28 Februari.

Manfaat lain dari penggunaan Half-Open yang konsisten [] adalah mengurangi muatan kognitif setiap kali saya harus mendeteksi dan menguraikan dan memverifikasi bagian dari pendekatan rentang waktu kode. Dalam pemrograman saya sendiri, saya hanya melirik untuk menyebutkan Setengah Terbuka dalam komentar di atas dan saya langsung tahu cara membaca kode itu.

Hasil dari penggunaan Half-Open yang konsisten mengurangi kemungkinan bug dalam kode saya karena gaya berpikir dan menulis saya seragam dan tidak ada kesempatan untuk bingung tentang inklusif-eksklusif.

By the way, perhatikan bahwa Half-Open [) berarti menghindari SQL BETWEEN konjungsi seperti yang selalu tertutup sepenuhnya [].

Mengenai pemikiran bisnis dari para pelanggan yang saya layani, di mana semestinya saya mencoba meyakinkan mereka untuk menggunakan Half-Open secara konstan juga. Saya telah melihat banyak situasi di mana berbagai pelaku bisnis membuat asumsi yang salah tentang periode waktu yang tercakup dalam laporan. Penggunaan Half-Open yang konsisten menghindari ambiguitas yang tidak menguntungkan ini. Tetapi jika pelanggan bersikeras, saya mencatat ini di kode saya dan menyesuaikan input / output sehingga menggunakan Half-Open dalam logika saya sendiri. Sebagai contoh, logika saya menggunakan satu minggu Senin-Senin, tetapi pada laporan dikurangi satu hari untuk menunjukkan hari Minggu.

Untuk lebih banyak kelas yang mewakili rentang waktu dengan pendekatan Setengah-Terbuka [), lihat ThreeTen-Ekstra proyek untuk nya Interval kelas (sepasang Instant objek) dan LocalDateRange kelas (sepasang LocalDate objek).


Tentang java.time

Itu java.time framework dibangun ke dalam Java 8 dan yang lebih baru. Kelas-kelas ini menggantikan yang lama yang merepotkan warisan kelas tanggal-waktu seperti java.util.Date, Calendar, & SimpleDateFormat.

Itu Joda-Time proyek, sekarang di mode pemeliharaan, menyarankan migrasi ke java.time kelas.

Untuk mempelajari lebih lanjut, lihat Tutorial Oracle. Dan cari Stack Overflow untuk banyak contoh dan penjelasan. Spesifikasi adalah JSR 310.

Di mana untuk mendapatkan kelas java.time?

Itu ThreeTen-Extra proyek memperluas java.time dengan kelas tambahan. Proyek ini adalah ajang pembuktian untuk kemungkinan penambahan jawa di masa mendatang. Anda mungkin menemukan beberapa kelas yang berguna di sini seperti Interval, YearWeek, YearQuarter, dan lebih.


1
2017-08-02 23:29



Saya baru saja melalui proses pemikiran yang sama persis ini dan saya pikir sangat penting bahwa ini distandarkan dengan cara tertentu, atau setidaknya diklarifikasi melalui jenis-jenis pos Q & A ini!

Dalam kasus kami, rentang tanggal yang dimaksud digunakan sebagai input dan output ke / dari layanan mikro; salah satu yang, dalam jangka pendek setidaknya, akan dipanggil oleh aplikasi monolitik yang ada (itu adalah proyek dekomposisi monolit). Oleh karena itu, saya berpikir bahwa komentar di atas berkaitan dengan keputusan yang didorong oleh persyaratan bisnis, dalam kasus kami, kurang relevan (karena langsung "pengguna" dari perangkat lunak yang kami bangun adalah orang-orang yang benar-benar teknis). Jika kami menangani masukan dari pemilih tanggal, itu mungkin cerita yang berbeda!

Rekomendasi saya adalah bahwa semua tanggal mulai bersifat inklusif dan semua tanggal akhir bersifat eksklusif - jadi [A, B] dalam notasi Anda. Ini karena alasan berikut:

  1. Kami sebelumnya telah menyetujui bahwa setiap tanggal masuk yang berisi bagian waktu akan ditolak (bahkan jika nilai JSON adalah "2018-01-01T00: 00: 00") dan kami akan menampilkan semua tanggal tanpa waktu. Oleh karena itu, jika tanggal akhir adalah eksklusif, segera setelah string deserialized ke objek .NET DateTime, itu akan menjadi hari keluar.

  2. Saya suka gagasan bahwa rentang tanggal (yang dalam kasus kami harus selalu menghasilkan hari penuh) dapat selalu dapat dihitung dengan hanya melakukan dateRange = (endDateExcl - startDateIncl) .TotalDays. Tidak perlu menambahkan 1 di mana-mana!

  3. Sebagian besar validasi bisnis yang dilakukan oleh layanan ini memeriksa bahwa beberapa rentang data saling berdekatan tanpa celah. Ini mudah untuk memeriksa mata ketika menggunakan [A, B] karena setiap B harus cocok dengan A. sebelumnya. Jika kita pergi dengan [A, B] maka kita (devs, penguji, teknisi pendukung) akan sering bertanya pada diri sendiri "Berapa hari bulan Maret lagi? " (mis. [2018-03-01,2018-03-30], [2018-04-01,2018-04-30]) atau "Apakah 2016 memiliki hari kabisat?" (mis. [2016-02-01,2016-02-28], [2016-03-01,2016-03-30]).

Hanya untuk menambahkan, saya sangat menyarankan siapa pun, terlepas dari keputusan, untuk secara eksplisit melunasi semua nama atribut, variabel, metode atau dengan "Incl" atau "Excl" sehingga jelas bagi semua orang tanpa harus memburu dokumentasi!

Kami juga merekomendasikan bahwa semua tanggal harus datang dalam format ISO dan apa pun dengan huruf "Z" di bagian akhir juga harus ditolak (karena pengertiannya adalah bahwa kami bekerja sepanjang hari dan kami tidak ingin tanggal untuk deserialized menjadi objek DateTime dengan jam kerja (atau 23!) karena penghematan siang hari).

Catatan kaki, saya mungkin akan memposting ini sebagai komentar untuk jawaban Voo tetapi saya baru saja (terlambat!) Bergabung dengan SO dan perlu mendapatkan pujian saya sebelum saya dapat melakukannya! ;-)

Selamat berkencan x


1
2017-11-03 18:05