Saya memiliki catatan foo
dalam database yang memiliki :start_time
dan :timezone
atribut.
Ini :start_time
adalah Waktu dalam UTC - 2001-01-01 14:20:00
, misalnya. Ini :timezone
adalah string - America/New_York
, misalnya.
Saya ingin membuat objek Waktu baru dengan nilai :start_time
tetapi zona waktunya ditentukan oleh :timezone
. Saya tidak ingin memuat :start_time
dan kemudian mengonversinya ke :timezone
, karena Rails akan menjadi pintar dan memperbarui waktu dari UTC agar konsisten dengan zona waktu itu.
Saat ini,
t = foo.start_time
=> 2000-01-01 14:20:00 UTC
t.zone
=> "UTC"
t.in_time_zone("America/New_York")
=> Sat, 01 Jan 2000 09:20:00 EST -05:00
Sebaliknya, saya ingin melihat
=> Sat, 01 Jan 2000 14:20:00 EST -05:00
yaitu. Aku ingin melakukan:
t
=> 2000-01-01 14:20:00 UTC
t.zone = "America/New_York"
=> "America/New_York"
t
=> 2000-01-01 14:20:00 EST
Jawaban:
Kedengarannya Anda menginginkan sesuatu di sepanjang baris
Ini mengatakan konversi waktu lokal ini (menggunakan zona) ke utc. Jika Anda sudah
Time.zone
mengatur maka Anda tentu saja bisaIni tidak akan menggunakan zona waktu yang dilampirkan ke t - ini mengasumsikan bahwa itu lokal ke zona waktu tempat Anda mengonversi.
Satu kasus tepi yang harus diperhatikan di sini adalah transisi DST: waktu lokal yang Anda tentukan mungkin tidak ada atau mungkin ambigu.
sumber
Time.use_zone(self.timezone) { Time.zone.local_to_utc(t) }.localtime
Saya baru saja menghadapi masalah yang sama dan inilah yang akan saya lakukan:
Berikut adalah dokumentasi tentang asctime
sumber
asctime
adalah ia menjatuhkan nilai sub-detik apa pun (yang disimpan oleh jawaban saya).Jika Anda menggunakan Rails, berikut adalah metode lain yang sejalan dengan jawaban Eric Walsh:
sumber
.in_time_zone
sampai akhir.Time.zone.now
dengan sesuatu yang paling dekat dengan waktu yang ingin Anda ubah akan berhasil?Anda perlu menambahkan pengimbangan waktu ke waktu Anda setelah Anda mengubahnya.
Cara termudah untuk melakukannya adalah:
Saya tidak yakin mengapa Anda ingin melakukan ini, meskipun mungkin yang terbaik adalah benar-benar bekerja dengan waktu bagaimana mereka dibangun. Saya kira beberapa latar belakang mengapa Anda perlu menggeser waktu dan zona waktu akan membantu.
sumber
Time.in_time_zone
dengan meminta bagian yang benar dari active_support:require 'active_support/core_ext/time'
Sebenarnya, saya pikir Anda perlu mengurangi offset setelah Anda mengubahnya, seperti di:
sumber
Tergantung di mana Anda akan menggunakan Waktu ini.
Ketika waktu Anda adalah atribut
Jika waktu digunakan sebagai atribut, Anda dapat menggunakan permata date_time_attribute yang sama :
Saat Anda menetapkan variabel terpisah
Gunakan permata date_time_attribute yang sama :
sumber
Fungsi kecil cepat yang saya buat untuk menyelesaikan pekerjaan. Jika seseorang memiliki cara yang lebih efisien untuk melakukan ini, harap kirimkan!
sumber
Premis OP tidak benar: "Saya tidak ingin memuat: start_time lalu mengonversi ke: zona waktu, karena Rails akan pintar dan memperbarui waktu dari UTC agar konsisten dengan zona waktu itu." Ini belum tentu benar, seperti yang ditunjukkan oleh jawaban yang diberikan di sini.
sumber
t.zone
sebelumt.change
apa yang Anda lihat? Dan bagaimana jika Andat.zone
mengejarnyat.change
? Dan parameter apa yang Anda teruskant.change
?Saya telah membuat beberapa metode pembantu yang salah satunya hanya melakukan hal yang sama seperti yang diminta oleh penulis asli posting di Ruby / Rails - Ubah zona waktu, tanpa mengubah nilainya .
Saya juga telah mendokumentasikan beberapa keanehan yang saya amati dan juga pembantu ini berisi metode untuk sepenuhnya mengabaikan penghematan siang hari otomatis yang berlaku sementara konversi waktu yang tidak tersedia di luar kotak dalam kerangka kerja Rails:
Contoh yang dapat dicoba pada rails console atau skrip ruby setelah menggabungkan metode di atas dalam kelas atau modul:
Semoga ini membantu.
sumber
Berikut versi lain yang bekerja lebih baik untuk saya daripada jawaban saat ini:
Ini membawa lebih dari nanodetik menggunakan "% N". Jika Anda menginginkan presisi lain, lihat referensi strftime ini .
sumber
Saya menghabiskan banyak waktu berjuang dengan TimeZones juga, dan setelah mengutak-atik Ruby 1.9.3 menyadari bahwa Anda tidak perlu mengonversi ke simbol zona waktu bernama sebelum mengonversi:
Hal ini menyiratkan bahwa Anda dapat fokus untuk mendapatkan pengaturan waktu yang sesuai terlebih dahulu di wilayah yang Anda inginkan, seperti yang akan Anda pikirkan (setidaknya di kepala saya, saya mempartisi dengan cara ini), dan kemudian mengubahnya di akhir ke zona Anda ingin memverifikasi logika bisnis Anda dengan.
Ini juga berfungsi untuk Ruby 2.3.1.
sumber