Відформатуйте дату за допомогою Ruby on Rails


74

API flickr надає дату розміщення як мітку часу unix: " The posted date is always passed around as a unix timestamp, which is an unsigned integer specifying the number of seconds since Jan 1st 1970 GMT."

Наприклад, ось дата ' 1100897479'. Як відформатувати його за допомогою Ruby on Rails?

Відповіді:


190

Після того, як ви проаналізували рядок мітки часу та отримали об’єкт часу (докладніше див. Інші відповіді), ви можете використовувати Time.to_formatted_s із Rails. Він має кілька вбудованих форматів, які ви можете вказати символами.

Цитата:

time = Time.now                     # => Thu Jan 18 06:10:17 CST 2007

time.to_formatted_s(:time)          # => "06:10"
time.to_s(:time)                    # => "06:10"

time.to_formatted_s(:db)            # => "2007-01-18 06:10:17"
time.to_formatted_s(:number)        # => "20070118061017"
time.to_formatted_s(:short)         # => "18 Jan 06:10"
time.to_formatted_s(:long)          # => "January 18, 2007 06:10"
time.to_formatted_s(:long_ordinal)  # => "January 18th, 2007 06:10"
time.to_formatted_s(:rfc822)        # => "Thu, 18 Jan 2007 06:10:17 -0600"

(Time.to_s - це псевдонім)

Ви також можете визначити власні формати - як правило, в ініціалізаторі (Дякуємо Ньютону за те, що на це вказував). Ось як це робиться:

# config/initializers/time_formats.rb
Time::DATE_FORMATS[:month_and_year] = "%B %Y"
Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }

+1; найпростіше рішення, коли є дата, особливо якщо працює один із існуючих форматів.
Дейв Ньютон,

4
Так, через карту в ініціалізаторах.
Дейв Ньютон,

3
Зверніть увагу, що Time :: DATE_FORMATS не передається на рейкові об'єкти Date. Для об'єктів Date використовуйте Date :: DATE_FORMATS
ReggieB

Тепер ви також можете використовувати I18n. guides.rubyonrails.org/i18n.html#adding-date-time-formats
PhilT

Коли мову пише японський розробник, не дивно, що дати настільки неамериканські :)
Куф

46

Ось я відповідаю на це,

тому спочатку вам потрібно буде перетворити мітку часу на фактичну дату / час Ruby. Якщо ви отримуєте його просто як рядок або int з facebook, вам потрібно буде зробити щось подібне:

my_date = Time.at(timestamp_from_facebook.to_i)

Добре, отже, припустимо, у вас вже є об’єкт дати ...

to_formatted_s - це зручна функція Ruby, яка перетворює дати у відформатовані рядки.

Ось кілька прикладів його використання:

time = Time.now                     # => Thu Jan 18 06:10:17 CST 2007    

time.to_formatted_s(:time)          # => "06:10"
time.to_s(:time)                    # => "06:10"    

time.to_formatted_s(:db)            # => "2007-01-18 06:10:17"
time.to_formatted_s(:number)        # => "20070118061017"
time.to_formatted_s(:short)         # => "18 Jan 06:10"
time.to_formatted_s(:long)          # => "January 18, 2007 06:10"
time.to_formatted_s(:long_ordinal)  # => "January 18th, 2007 06:10"
time.to_formatted_s(:rfc822)        # => "Thu, 18 Jan 2007 06:10:17 -0600"

Як бачите:: db,: number,: short ... - це власні формати дат.

Щоб додати свій власний формат, ви можете створити цей файл: config / initializers / time_formats.rb і додати туди свої власні формати, наприклад ось один:

Date::DATE_FORMATS[:month_day_comma_year] = "%B %e, %Y" # January 28, 2015

Де : month_day_comma_year - це ім'я вашого формату (ви можете змінити це на все, що завгодно), а де % B% e,% Y - формат дати unix.

Ось коротка таблиця синтаксису дати Unix, щоб ви могли швидко налаштувати власний формат:

From http://linux.die.net/man/3/strftime    

  %a - The abbreviated weekday name (``Sun'')
  %A - The  full  weekday  name (``Sunday'')
  %b - The abbreviated month name (``Jan'')
  %B - The  full  month  name (``January'')
  %c - The preferred local date and time representation
  %d - Day of the month (01..31)
  %e - Day of the month without leading 0 (1..31) 
  %g - Year in YY (00-99)
  %H - Hour of the day, 24-hour clock (00..23)
  %I - Hour of the day, 12-hour clock (01..12)
  %j - Day of the year (001..366)
  %m - Month of the year (01..12)
  %M - Minute of the hour (00..59)
  %p - Meridian indicator (``AM''  or  ``PM'')
  %S - Second of the minute (00..60)
  %U - Week  number  of the current year,
          starting with the first Sunday as the first
          day of the first week (00..53)
  %W - Week  number  of the current year,
          starting with the first Monday as the first
          day of the first week (00..53)
  %w - Day of the week (Sunday is 0, 0..6)
  %x - Preferred representation for the date alone, no time
  %X - Preferred representation for the time alone, no date
  %y - Year without a century (00..99)
  %Y - Year with century
  %Z - Time zone name
  %% - Literal ``%'' character    

   t = Time.now
   t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 04/09/2003"
   t.strftime("at %I:%M%p")            #=> "at 08:56AM"

Сподіваюся, це вам допомогло. Я також склав суть цього невеликого посібника на випадок, якщо хтось віддасть перевагу.


Хоча це посилання може відповісти на питання, краще включити сюди основні частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться. - З огляду
Mihai Caracostea

Привіт @MihaiCaracostea, я повторив свою відповідь, слідуючи твоїй пораді, дякую :)
Edu Wass

1
Це не працює для мене. Я додав формат дати в папці ініціалізаторів. Ось як я використовую це у поданні, @question.created_at.to_formatted_s(:month_day_comma_year)але я розумію#2019-07-27 03:27:41 UTC
Стівен Агілар

як щодо DateTimeцього він також може це використовувати?
Стівен Агілар,

27

Найпростіший у використанні strftime(документи) .

Якщо він призначений для використання з боку огляду, все ж краще обернути його помічником.


1
Я не зрозумів, як ним користуватися. Підкажіть, будь ласка, крихітний приклад?
Олександр

6
my_date_variable.strftime ("% m /% d /% Y")
aldo.roman.nurena

7
strftime не є СУХИМ. Будь ласка, не розкидайте strftime по всіх своїх проектах. Принаймні ви згадали про помічника, але config/initializers/time_formats.rbбільш ідіоматичний для Rails.
PhilT

@PhilT Як я вже згадував у своєму коментарі щодо відповіді з найбільшим голосом, яка була зведена до цієї відповіді.
Дейв Ньютон,

17

Відповідь @ CMW - удар у гроші. Я додав цю відповідь як приклад того, як налаштувати ініціалізатор, щоб об'єкти Date та Time отримали форматування

config / Initializers / time_formats.rb

date_formats = {
  concise: '%d-%b-%Y' # 13-Jan-2014
}

Time::DATE_FORMATS.merge! date_formats
Date::DATE_FORMATS.merge! date_formats

Також наступні дві команди будуть переглядати всі DATE_FORMATSпоточні умови та відображати сьогоднішню дату та час у кожному форматі:

Date::DATE_FORMATS.keys.each{|k| puts [k,Date.today.to_s(k)].join(':- ')}
Time::DATE_FORMATS.keys.each{|k| puts [k,Time.now.to_s(k)].join(':- ')}


6

Спочатку вам потрібно буде перетворити мітку часу у фактичну дату / час Ruby. Якщо ви отримуєте його просто як рядок або int з facebook, вам потрібно буде зробити щось подібне:

my_date = Time.at(timestamp_from_facebook.to_i)

Потім для гарного форматування у поданні ви можете просто використовувати to_s(для форматування за замовчуванням):

<%= my_date.to_s %>

Зверніть увагу, що якщо ви не ставите to_s, він все одно буде викликаний за замовчуванням, якщо ви використовуєте його у поданні або в рядку, наприклад, наступне також буде викликати to_sдату:

<%= "Here is a date: #{my_date}" %>

або якщо ви хочете, щоб дата була відформатована певним чином (наприклад, за допомогою "d / m / Y") - ви можете використовувати, strftimeяк зазначено в іншій відповіді.


Цей код видає помилку puts Time.at('1100897479')- не вдається перетворити рядок у точне число (TypeError)
Олександр

Ах, це прибуває як струна? добре, так що "to_i" це, щоб переконатись, що це int (приклад, відредагований для включення цього)
Taryn East

1

Оскільки мітки часу є секундами з епохи UNIX, ви можете використовувати DateTime.strptime ("час синтаксичного аналізу") з правильним специфікатором:

Date.strptime('1100897479', '%s')
#=> #<Date: 2004-11-19 ((2453329j,0s,0n),+0s,2299161j)>
Date.strptime('1100897479', '%s').to_s
#=> "2004-11-19"
DateTime.strptime('1100897479', '%s')
#=> #<DateTime: 2004-11-19T20:51:19+00:00 ((2453329j,75079s,0n),+0s,2299161j)>
DateTime.strptime('1100897479', '%s').to_s
#=> "2004-11-19T20:51:19+00:00"

Зауважте, що require 'date'для того, щоб це спрацювало, вам потрібно це назвати як Date.strptime(якщо вам важлива лише дата), або DateTime.strptime(якщо ви хочете дату та час). Якщо вам потрібно інше форматування, ви можете викликати DateTime # strftime ( якщо у вас важко зі строками форматування), подивіться на нього strftime.net або скористайтесь одним із вбудованих методів, наприклад rfc822.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.