2012-06-18 42 views
67

Các api flickr cung cấp một thời gian đăng tuyển như unix timestamp một: "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."Định dạng ngày sử dụng Ruby on Rails

Ví dụ, đây là ngày '1100897479'. Làm thế nào để định dạng nó bằng Ruby on Rails?

Trả lời

26

Easiest is to use strftime (docs).

Nếu nó được sử dụng ở mặt bên, tốt hơn nên bọc nó trong bộ trợ giúp.

+1

Tôi không biết cách sử dụng nó. Bạn có thể cho tôi một ví dụ nhỏ được không? – Alexandre

+6

my_date_variable.strftime ("% m /% d /% Y") –

+6

strftime không phải là DRY. Xin vui lòng không phân tán strftime tất cả các dự án của bạn. Ít nhất bạn đã đề cập đến một trình trợ giúp nhưng 'config/initializers/time_formats.rb' có nhiều thành ngữ hơn cho Rails. – PhilT

6

Trước tiên, bạn sẽ cần chuyển đổi dấu thời gian thành Ngày/Thời gian Ruby thực tế. Nếu bạn nhận được nó cũng giống như một chuỗi hoặc int từ facebook, bạn sẽ cần phải làm một cái gì đó như thế này:

my_date = Time.at(timestamp_from_facebook.to_i) 

Sau đó, để định dạng nó độc đáo trong giao diện, bạn chỉ có thể sử dụng to_s (đối với định dạng mặc định) :

<%= my_date.to_s %> 

Lưu ý rằng nếu bạn không đặt to_s, nó vẫn sẽ được gọi là theo mặc định nếu bạn sử dụng nó trong một cái nhìn hoặc trong một chuỗi ví dụ sau đây cũng sẽ gọi to_s vào ngày:

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

hoặc nếu bạn muốn ngày được định dạng theo một cách cụ thể (ví dụ như sử dụng "d/m/Y") - bạn có thể sử dụng strftime như được nêu trong câu trả lời khác .

+0

Mã này ném một lỗi 'đặt Time.at ('1100897479')' - không thể chuyển đổi chuỗi thành một số chính xác (TypeError) – Alexandre

+0

Ah, nó đến như là một chuỗi? ok vì vậy "to_i" nó để làm cho chắc chắn đó là một int (ví dụ trên chỉnh sửa để bao gồm này) –

1

Kể từ khi timestamps là giây kể từ khi kỷ nguyên UNIX, bạn có thể sử dụng DateTime.strptime ("chuỗi thời gian phân tích cú pháp") với sự xác định đúng:

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" 

Lưu ý rằng bạn phải require 'date' cho rằng để làm việc, sau đó bạn có thể gọi nó là Date.strptime (nếu bạn chỉ quan tâm đến ngày) hoặc DateTime.strptime (nếu bạn muốn ngày và giờ). Nếu bạn cần định dạng khác, bạn có thể gọi DateTime#strftime (xem strftime.net nếu bạn gặp khó khăn với chuỗi định dạng) trên đó hoặc sử dụng một trong các phương pháp được tích hợp sẵn như rfc822.

172

Khi bạn đã phân tích cú pháp chuỗi dấu thời gian và có đối tượng thời gian (xem các câu trả lời khác để biết chi tiết), bạn có thể sử dụng Time.to_formatted_s từ Rails. Nó có một số định dạng được xây dựng trong đó bạn có thể chỉ định với các biểu tượng.

Trích:

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 là một bí danh)

Bạn cũng có thể xác định định dạng của riêng bạn - thường trong một initializer (Nhờ Dave Newton cho trỏ này ra). Đây là cách thực hiện:

# 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}") } 
+0

+1; giải pháp đơn giản nhất khi có ngày, đặc biệt nếu một trong các định dạng hiện có hoạt động. –

+0

Tôi nghĩ rằng thậm chí còn có một cách để đăng ký định dạng mới. – CMW

+4

Đúng, thông qua bản đồ trong bộ khởi tạo. –

13

@ Câu trả lời của CMW là đập vào tiền. Tôi đã thêm câu trả lời này làm ví dụ về cách định cấu hình trình khởi tạo để cả đối tượng Ngày và Giờ nhận được định dạng

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 

Cũng sau hai lệnh sẽ lặp qua tất cả các DATE_FORMATS trong môi trường hiện tại của bạn, và hiển thị ngày hôm nay và thời gian trong mỗi định dạng:

Time::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(':- ')} 
7

Có một cái nhìn tại localize, hoặc l

ví dụ:

l Time.at(1100897479) 
+1

Đây là giải pháp tốt nhất, bởi vì định dạng có thể thay đổi theo từng ngôn ngữ. Bạn cũng có thể thêm bao nhiêu định dạng tùy chỉnh theo ý muốn: xem http://guides.rubyonrails.org/i18n.html#adding-date-time-formats –

33

Đây là cách tôi trả lời câu hỏi này,

vì vậy trước tiên, bạn sẽ cần chuyển đổi dấu thời gian thành Ngày/Thời gian Ruby thực tế. Nếu bạn nhận được nó cũng giống như một chuỗi hoặc int từ facebook, bạn sẽ cần phải làm một cái gì đó như thế này:

my_date = Time.at(timestamp_from_facebook.to_i) 

OK, vì vậy bây giờ giả sử bạn đã có đối tượng ngày của bạn ...

to_formatted_s là một hàm Ruby tiện dụng để biến ngày thành các chuỗi được định dạng.

Dưới đây là một số ví dụ về việc sử dụng của nó:

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" 

Như bạn có thể thấy: : db,: số,: ngắn ... là định dạng ngày tùy chỉnh.

Để thêm định dạng tùy chỉnh của riêng bạn, bạn có thể tạo tập tin này: config/initializers/time_formats.rb và thêm các định dạng của riêng bạn có, ví dụ đây là một:

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

đâu : month_day_comma_year là tên định dạng của bạn (bạn có thể thay đổi tên này thành bất kỳ thứ gì bạn muốn) và ở đâu là % B% e,% Y là định dạng ngày tháng.

Dưới đây là một cheatsheet nhanh chóng về cú pháp ngày unix, vì vậy bạn có thể nhanh chóng thiết lập định dạng tùy chỉnh của bạn:

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" 

Hy vọng điều này giúp bạn. Tôi cũng đã thực hiện một số github gist của hướng dẫn nhỏ này, trong trường hợp ai đó thích.

+0

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. - [Từ đánh giá] (/ đánh giá/chất lượng thấp-bài viết/10586543) –

+0

Hi @MihaiCaracostea, lại làm câu trả lời của tôi sau lời khuyên của bạn, cảm ơn :) – eduwass