Đặt phần thời gian của DateTime bằng ruby


104

Giả sử tôi có một đối tượng datetime chẳng hạn DateTime.now. Tôi muốn đặt giờ và phút thành 0 (nửa đêm). Làm thế nào tôi có thể làm điều đó?

Câu trả lời:


220

Trong môi trường Rails:

Nhờ ActiveSupport bạn có thể sử dụng:

DateTime.now.midnight
DateTime.now.beginning_of_day

HOẶC LÀ

DateTime.now.change({ hour: 0, min: 0, sec: 0 })

# More concisely
DateTime.now.change({ hour: 0 })                

Trong một môi trường hoàn toàn Ruby:

now = DateTime.now
DateTime.new(now.year, now.month, now.day, 0, 0, 0, now.zone)

HOẶC LÀ

now = DateTime.now
DateTime.parse(now.strftime("%Y-%m-%dT00:00:00%z"))

26
FWIW, phương pháp thay đổi là một phần của đường ray không phải ruby. Các tùy chọn thời gian (giờ, phút, giây) được đặt lại theo tầng, vì vậy nếu chỉ có giờ trôi qua, thì phút và giây được đặt thành 0. Nếu giờ và phút trôi qua, thì giây được đặt thành 0
Anna

1
Hãy lưu ý rằng DateTime.now.midnight không trả về 24:00:00 như bạn có thể mong đợi, nó trả về 00:00:00 - cùng giá trị với begin_of_day. Hãy xem câu trả lời của tôi là tại sao điều này có thể quan trọng trong một số trường hợp.
rmcsharry

1
Giải pháp ruby ​​hoàn toàn đầu tiên của bạn làm giảm thông tin múi giờ, giải pháp thứ hai của bạn thì không
Tony

1
Tôi đã cập nhật câu trả lời để tính đến múi giờ và thay thế biến thể thứ hai. @Tony bắt rất tốt, cả hai đều dễ bị mất thông tin múi giờ khi xem kỹ hơn. DateTime.new(now.year, now.month, now.day, 0,0,0, now.zone) != now.to_date.to_datetime
ashoda

TIMEZONE: Có thể được thay đổi bằng cách bù từ khóa trong đối số băm: DateTime.now.change ({giờ: 0, min: 0, sec: 0 offset: '+02: 00'})
Ekkstein

34

Đừng bận tâm, hiểu rồi. Cần tạo DateTime mới:

DateTime.new(now.year, now.month, now.day, 0, 0, 0, 0)

6
Câu trả lời tốt. Chỉ muốn thêm rằng những số không đó đại diện cho HOUR, MINUTE, SECOND và OFFSET (múi giờ) theo thứ tự đó.
d_ethier 21/07/13

3
Sau khi không làm được điều này, tôi đã học được rằng: DateTime.new(Time.now.year, Time.now.month, Time.now.day, 0, 0, 0)nó hoạt động.
Ekkstein

2
Đừng quên: now = DateTime.now
Abel

1
Cũng cần lưu ý rằng đối số cuối cùng cần phải được một chuỗi các múi giờ ví dụ ( "- 0700") cho MST, không phải là một số nguyên
Donavan Trắng

2
Trừ khi bạn đang xử lý các ngày lịch sử, ĐỪNG SỬ DỤNG DateTime. Bạn sẽ gặp phải những vấn đề khó chịu nếu bạn sống ở một quốc gia có thời gian tiết kiệm ánh sáng ban ngày như Vương quốc Anh. Xem giải thích tại đây. gist.github.com/pixeltrix/e2298822dd89d854444b
fatuhoku

5

Cảnh báo : DateTime.now.midnightDateTime.now.beginning_of_daytrả về cùng một giá trị (là giờ 0 của ngày hiện tại - nửa đêm không trả về 24:00:00 như bạn mong đợi từ tên của nó).

Vì vậy, tôi thêm thông tin này làm thông tin thêm cho bất kỳ ai có thể sử dụng câu trả lời được chấp nhận để tính nửa đêm x ngày trong tương lai.

Ví dụ: bản dùng thử miễn phí 14 ngày sẽ hết hạn vào nửa đêm của ngày 14:

DateTime.now.midnight + 14.days

là buổi sáng của ngày thứ 14, tương đương với phiên dùng thử 13,5 ngày (x là phần thời gian còn lại trong ngày - nếu bây giờ là buổi trưa, thì đó là phiên tòa 13,5 ngày).

Bạn thực sự cần làm điều này:

DateTime.now.midnight + 15.days

để có được nửa đêm vào ngày 14.

Vì lý do này, tôi luôn thích sử dụng beginning_of_day, vì đó là 00:00:00. Sử dụng nửa đêm có thể gây hiểu lầm / hiểu nhầm.


1

Nếu bạn thường sử dụng nó, hãy cân nhắc cài đặt gem này để cải thiện phân tích cú pháp ngày:

https://github.com/mojombo/chronic

require 'chronic'

Chronic.parse('this 0:00')

Tôi không chắc tại sao câu trả lời này được đánh dấu là đúng. Nó không thực sự trả lời câu hỏi. Tôi biết cách phân tích cú pháp chuỗi thành ngày tháng. Nhưng tôi muốn biết cách thay đổi một phần cụ thể của một phiên bản ngày cụ thể. Ví dụ năm. Bất kỳ ý tưởng? Trong Java, tôi sẽ chỉ sử dụng bộ định thời trong năm. Nhưng nó không hoạt động trong Ruby :-(
Robert Reiz

1
Tôi không còn tin tưởng đá quý mãn tính nữa. Nó thực sự lỗi thời. Tôi đã gặp sự cố khi phân tích cú pháp ngày-giờ lúc chạy trong ứng dụng của mình, dẫn đến việc kinh doanh bị thua lỗ.
Vijay Meena
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.