Ustaw część czasową DateTime w ruby

104

Powiedzmy, że mam obiekt daty i godziny, np DateTime.now. Chcę ustawić godziny i minuty na 0 (północ). Jak mogę to zrobić?

Jesse Aldridge
źródło

Odpowiedzi:

220

W środowisku Railsów:

Dzięki ActiveSupport możesz skorzystać z:

DateTime.now.midnight
DateTime.now.beginning_of_day

LUB

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

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

W czystym środowisku Ruby:

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

LUB

now = DateTime.now
DateTime.parse(now.strftime("%Y-%m-%dT00:00:00%z"))
kalcynowana
źródło
26
FWIW, metoda zmiany jest częścią szyn, a nie rubinem. Opcje czasu (godzina, minuta, sekunda) resetują się kaskadowo, więc jeśli minie tylko godzina, minuty i sekundy są ustawiane na 0. Jeśli miną godziny i minuty, to sekunda jest ustawiana na 0.
Anna
1
Należy pamiętać, że DateTime.now.midnight nie zwraca 24:00:00, jak można by się spodziewać, zwraca 00:00:00 - tę samą wartość co początek_dnia. Zobacz moją odpowiedź, dlaczego może to być ważne w niektórych scenariuszach.
rmcsharry
1
Twoje pierwsze czysto rubinowe rozwiązanie zawiera informacje o strefie czasowej, drugie nie
Tony
2
Zaktualizowałem odpowiedź, aby uwzględnić strefę czasową i zastąpiłem drugą odmianę. @Tony bardzo dobry chwyt, tak naprawdę oboje byli podatni na utratę informacji o strefie czasowej po bliższym przyjrzeniu się. DateTime.new(now.year, now.month, now.day, 0,0,0, now.zone) != now.to_date.to_datetime
kalcynowana
STREFA CZASU: Można zmienić za pomocą słowa kluczowego przesunięcie w argumencie hash: DateTime.now.change ({godzina: 0, min: 0, sek: 0 przesunięcie: '+02: 00'})
Ekkstein
34

Nieważne, rozumiem. Musisz utworzyć nowy DateTime:

DateTime.new(now.year, now.month, now.day, 0, 0, 0, 0)
Jesse Aldridge
źródło
6
Dobra odpowiedź. Chciałem tylko dodać, że te zera reprezentują GODZINĘ, MINUTĘ, SEKUNDĘ i PRZESUNIĘCIE (strefa czasowa) w tej kolejności.
d_ethier
3
Kiedy nie udało mi się to uruchomić, dowiedziałem się, że DateTime.new(Time.now.year, Time.now.month, Time.now.day, 0, 0, 0)to działa.
Ekkstein
2
Nie zapomnij: now = DateTime.now
Abel
1
Należy również zauważyć, że ostatni argument musi być łańcuchem strefy czasowej, np. („- 0700”) dla MST, a nie liczbą całkowitą
Donavan White
2
O ile nie masz do czynienia z datami historycznymi, NIE UŻYWAJ DateTime. Będziesz mieć irytujące problemy, jeśli mieszkasz w kraju, który ma czas letni, taki jak Wielka Brytania. Zobacz wyjaśnienie tutaj. gist.github.com/pixeltrix/e2298822dd89d854444b
fatuhoku
5

Uwaga : DateTime.now.midnighti DateTime.now.beginning_of_dayzwróć tę samą wartość (która jest godziną zerową bieżącego dnia - północ nie zwraca 24:00:00, jak można by się spodziewać po jej nazwie).

Więc dodaję to jako dalsze informacje dla każdego, kto mógłby użyć zaakceptowanej odpowiedzi do obliczenia północy x dni w przyszłości.

Na przykład 14-dniowy bezpłatny okres próbny, który powinien wygasnąć o północy 14 dnia:

DateTime.now.midnight + 14.days

jest poranek 14 dnia, co odpowiada 13.x dniowej próbie (x to pozostała część dnia - jeśli teraz jest południe, to jest to 13,5-dniowy okres próbny).

Właściwie musiałbyś to zrobić:

DateTime.now.midnight + 15.days

aby uzyskać północ 14 dnia.

Z tego powodu zawsze wolę używać beginning_of_day, ponieważ jest to 00:00:00. Korzystanie z północy może być mylące / niezrozumiane.

rmcsharry
źródło
1

Jeśli często go używasz, rozważ zainstalowanie tego klejnotu, aby poprawić analizę daty:

https://github.com/mojombo/chronic

require 'chronic'

Chronic.parse('this 0:00')
wizztjh
źródło
Nie jestem pewien, dlaczego ta odpowiedź została oznaczona jako poprawna. To tak naprawdę nie odpowiada na pytanie. Wiem, jak przetworzyć ciąg znaków na datę. Ale chciałbym wiedzieć, jak zmienić konkretną część danej instancji daty. Na przykład rok. Jakieś pomysły? W Javie użyłbym setera przez rok. Ale to nie działa w Rubim :-(
Robert Reiz,
1
Nie ufam już chronicznym klejnotom. Jest naprawdę przestarzały. Wystąpił problem z analizowaniem daty i godziny w czasie wykonywania w mojej aplikacji, co spowodowało utratę działalności.
Vijay Meena