Pertanyaan Rails. Bagaimana cara menyimpan waktu hari (untuk jadwal)?


Saya menulis aplikasi yang melacak kelas sekolah.

Saya perlu menyimpan jadwal. Misalnya: Senin-Jumat dari 8: am-11 pagi.

Saya sedang berpikir tentang menggunakan kolom string sederhana tapi saya akan perlu membuat perhitungan waktu nanti.

Sebagai contoh, saya perlu menyimpan representasi jam 8 pagi, seperti start_at: 8am end_at: 11am

Begitu bagaimana saya harus menyimpan waktu? Datatype apa yang harus saya gunakan? Haruskah saya menyimpan waktu mulai dan jumlah detik atau menit dan kemudian menghitung dari sana? atau apakah ada cara yang lebih mudah?

Saya menggunakan MySQL untuk produksi dan SQLite untuk pengembangan.


32
2017-08-15 16:30


asal


Jawaban:


Saya membuat aplikasi baru-baru ini yang harus mengatasi masalah ini. Saya memutuskan untuk menyimpan open_at dan closed_at dalam hitungan detik dari tengah malam dalam model jam bisnis sederhana. ActiveSupport menyertakan helper berguna ini untuk mengetahui waktu dalam detik sejak tengah malam:

Time.now.seconds_since_midnight

Dengan cara ini saya dapat melakukan kueri sederhana untuk mengetahui apakah suatu tempat terbuka:

BusinessHour.where("open_at > ? and close_at < ?", Time.now.seconds_since_midnight, Time.now.seconds_since_midnight)

Setiap kiat untuk membuat ini lebih baik akan dihargai =)


19
2018-03-12 00:06



Jika Anda menggunakan Postgresql, Anda dapat menggunakan time tipe kolom yang hanya waktu hari dan tidak ada tanggal. Anda kemudian dapat query

Event.where("start_time > '10:00:00' and end_time < '12:00:00'")

Mungkin MySQL memiliki hal serupa


10
2017-11-26 23:05



Lihat permata itu 'rubah' untuk Rails 4 atau Time_of_Day for Rails. Keduanya memecahkan masalah penyimpanan waktu dalam database saat menggunakan model Rekaman Aktif.

SQL memiliki tipe data waktu tetapi Ruby tidak. Rekaman Aktif mengatasi perbedaan ini dengan merepresentasikan atribut waktu menggunakan kelas Waktu Ruby pada tanggal kanonik 2000-01-01. Semua atribut Waktu secara sewenang-wenang diberi tanggal yang sama. Meskipun atribut dapat dibandingkan satu sama lain tanpa masalah, (tanggalnya sama), kesalahan muncul ketika Anda mencoba membandingkannya dengan contoh Waktu lainnya. Cukup menggunakan Time.parse pada string seperti ”10:05” menambahkan tanggal hari ini ke output.

Lailson Bandeira menciptakan solusi yang dibuat untuk masalah ini, permata Time_of_Day untuk Rails 3. Sayangnya permata tidak lagi dipertahankan. Gunakan permata ‘tod’ Jack Christensen sebagai gantinya. Ia bekerja seperti pesona.


8
2017-09-10 04:21



Saya akan menyimpan jam awal dan durasi dalam database, menggunakan dua kolom bilangan bulat.

Dengan mengambil kedua nilai, Anda dapat mengonversi jam awal seperti (dengan asumsi Anda sudah tahu hari itu:

# assuming date is the date of the day, datetime will hold the start time
datetime = date.change({:hour => your_stored_hour_value , :min => 0 , :sec => 0 })

# calculating the end time
end_time = datetime + your_stored_duration.seconds

Jika tidak, hava lihat Kronis. Permata membuat waktu penanganan sedikit lebih mudah. Perhatikan bahwa changemetode adalah bagian dari rel, dan tidak tersedia di Ruby biasa.

Dokumentasi tentang DateTime untuk Ruby polos dapat ditemukan sini.

Juga, apa pun yang Anda lakukan, jangan mulai menyimpan tanggal / waktu Anda dalam format 12 jam, yang dapat Anda gunakan I18nin Rails untuk mengonversi waktu:

I18n.l Time.now, :format => "%I.%m %p",  :locale => :"en"
I18n.l Time.now + 12.hours, :format => "%I.%m %p",  :locale => :"en"

Anda juga dapat memperoleh dari notasi ini, bahwa Anda dapat menyimpan durasi Anda dalam hitungan jam, jika Anda mau, Anda dapat mengonversinya dengan lebih mudah dengan:

your_stored_value.hours

jika disimpan sebagai bilangan bulat, itu.


2
2017-08-15 17:18



Permata ruby ​​inimengkonversi waktu hari ke detik sejak tengah malam dan kembali. Nilai detik disimpan dalam database dan dapat digunakan untuk perhitungan dan validasi.

Tentukan waktu atribut hari:

class BusinessHour < ActiveRecord::Base
  time_of_day_attr :opening, :closing
end

Mengubah waktu hari ke detik sejak tengah malam ketika string ditetapkan:

business_hour = BusinessHour.new(opening: '9:00', closing: '17:00')
business_hour.opening
 => 32400
business_hour.closing
 => 61200

Untuk mengonversi kembali ke waktu hari:

TimeOfDayAttr.l(business_hour.opening)
 => '9:00'
TimeOfDayAttr.l(business_hour.closing)
 => '17:00'

Anda juga dapat menghilangkan menit pada jam penuh:

TimeOfDayAttr.l(business_hour.opening, omit_minutes_at_full_hour: true)
 => '9'

2
2018-01-05 11:24



Saran:

Jangan khawatir tentang datatype tertentu untuk itu. Solusi sederhana adalah:

  1. Di dalam basis data, tambahkan sebuah bilangan bulat kolom tipe untuk waktu mulai dan satu lagi untuk akhir waktu. Masing-masing akan menyimpan jumlah menit sejak tengah malam.
    Ex: 8:30 akan disimpan sebagai 510 (8 * 60 + 30)

  2. Dalam formulir, buat a memilih bidang (tarik-turun) yang menampilkan semua waktu yang tersedia dalam format waktu:
    Ex .: 10 pagi, 10:30 dan seterusnya.
    Tapi nilai-nilai lapangan yang sebenarnya yang disimpan dalam database adalah setara integer mereka:
    Contoh: 600, 630 dan seterusnya (mengikuti contoh di atas)


1
2018-02-04 06:10



Saya berasumsi Anda menggunakan beberapa jenis database untuk ini. Jika Anda menggunakan MySQL atau Postgresql, Anda dapat menggunakan datetime tipe kolom, yang Ruby / Rails akan secara otomatis dikonversi ke / dari a Time objek saat membaca / menulis ke database. Saya tidak yakin apakah sqlite memiliki sesuatu yang mirip, tapi saya membayangkan itu mungkin.


0
2017-08-15 16:49



Dari SQLite 3 situs web,

"SQLite tidak memiliki kelas penyimpanan yang disisihkan untuk menyimpan tanggal dan / atau waktu. Sebaliknya, Fungsi Tanggal dan Waktu SQLite yang built-in mampu menyimpan tanggal dan waktu sebagai nilai TEXT, REAL, atau INTEGER:

TEXT sebagai string ISO8601 ("YYYY-MM-DD HH: MM: SS.SSS"). NYATA sebagai nomor hari Julian, jumlah hari sejak tengah hari di Greenwich pada 24 November, 4714 SM. menurut kalender Gregorian proleptic. INTEGER sebagai Waktu Unix, jumlah detik sejak 1970-01-01 00:00:00 UTC. Aplikasi dapat memilih untuk menyimpan tanggal dan waktu di salah satu format ini dan dengan bebas mengkonversi antar format menggunakan fungsi tanggal dan waktu yang ada di dalamnya. "

Anda kemudian dapat memanipulasi nilai menggunakan fungsi Tanggal dan Waktu yang diuraikan sini.


0
2017-08-15 17:05