Ruby/Rails - 如何将秒转换为时间?

发布于 2024-09-28 04:48:04 字数 477 浏览 5 评论 0原文

我需要执行以下转换:

0     -> 12.00AM
1800  -> 12.30AM
3600  -> 01.00AM
...
82800 -> 11.00PM
84600 -> 11.30PM

我想出了这个:

(0..84600).step(1800){|n| puts "#{n.to_s} #{Time.at(n).strftime("%I:%M%p")}"}

这给了我错误的时间,因为 Time.at(n) 期望 n 是从纪元开始的秒数:

0     -> 07:00PM
1800  -> 07:30PM
3600  -> 08:00PM
...
82800 -> 06:00PM
84600 -> 06:30PM

什么是最优化的、与时区无关的解决方案这个转变?

I need to perform the following conversion:

0     -> 12.00AM
1800  -> 12.30AM
3600  -> 01.00AM
...
82800 -> 11.00PM
84600 -> 11.30PM

I came up with this:

(0..84600).step(1800){|n| puts "#{n.to_s} #{Time.at(n).strftime("%I:%M%p")}"}

which gives me the wrong time, because Time.at(n) expects n to be number of seconds from epoch:

0     -> 07:00PM
1800  -> 07:30PM
3600  -> 08:00PM
...
82800 -> 06:00PM
84600 -> 06:30PM

What would be the most optimal, time zone independent solution for this transformation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拿命拼未来 2024-10-05 04:48:04

最简单的一句话就是忽略日期:

Time.at(82800).utc.strftime("%I:%M%p")

#-> "11:00PM"

The simplest one-liner simply ignores the date:

Time.at(82800).utc.strftime("%I:%M%p")

#-> "11:00PM"
琉璃繁缕 2024-10-05 04:48:04

不确定这是否

(Time.local(1,1,1) + 82800).strftime("%I:%M%p")


def hour_minutes(seconds)
  Time.at(seconds).utc.strftime("%I:%M%p")
end


irb(main):022:0> [0, 1800, 3600, 82800, 84600].each { |s| puts "#{s} -> #{hour_minutes(s)}"}
0 -> 12:00AM
1800 -> 12:30AM
3600 -> 01:00AM
82800 -> 11:00PM
84600 -> 11:30PM

比斯蒂芬更好

Not sure if this is better than

(Time.local(1,1,1) + 82800).strftime("%I:%M%p")


def hour_minutes(seconds)
  Time.at(seconds).utc.strftime("%I:%M%p")
end


irb(main):022:0> [0, 1800, 3600, 82800, 84600].each { |s| puts "#{s} -> #{hour_minutes(s)}"}
0 -> 12:00AM
1800 -> 12:30AM
3600 -> 01:00AM
82800 -> 11:00PM
84600 -> 11:30PM

Stephan

半山落雨半山空 2024-10-05 04:48:04

两个优惠:

精心设计的 DIY 解决方案:

def toClock(secs)
  h = secs / 3600;  # hours
  m = secs % 3600 / 60; # minutes
  if h < 12 # before noon
    ampm = "AM"
    if h = 0
      h = 12
    end
  else     # (after) noon
    ampm =  "PM"
    if h > 12
      h -= 12
    end
  end
  ampm = h <= 12 ? "AM" : "PM";
  return "#{h}:#{m}#{ampm}"
end

时间解决方案:

def toClock(secs)
  t = Time.gm(2000,1,1) + secs   # date doesn't matter but has to be valid
  return "#{t.strftime("%I:%M%p")}   # copy of your desired format
end

HTH

Two offers:

The elaborate DIY solution:

def toClock(secs)
  h = secs / 3600;  # hours
  m = secs % 3600 / 60; # minutes
  if h < 12 # before noon
    ampm = "AM"
    if h = 0
      h = 12
    end
  else     # (after) noon
    ampm =  "PM"
    if h > 12
      h -= 12
    end
  end
  ampm = h <= 12 ? "AM" : "PM";
  return "#{h}:#{m}#{ampm}"
end

the Time solution:

def toClock(secs)
  t = Time.gm(2000,1,1) + secs   # date doesn't matter but has to be valid
  return "#{t.strftime("%I:%M%p")}   # copy of your desired format
end

HTH

谁许谁一生繁华 2024-10-05 04:48:04

在其他解决方案中,当跨越 24 小时日界限时,小时计数器将重置为 00。另请注意 Time.at 向下舍入,因此如果输入有任何小数秒(例如,当 t=479.9 then Time.at(t).utc.strftime("%H:%M:%S") 将给出 00:07:59 而不是 00:08:00` 这是正确的一个)。

如果您想要一种方法将任何秒数(甚至大于 24 小时日跨度的高计数)转换为不断增加的 HH:MM:SS 计数器,并处理潜在的小数秒数,请尝试以下操作:

# Will take as input a time in seconds (which is typically a result after subtracting two Time objects),
# and return the result in HH:MM:SS, even if it exceeds a 24 hour period.
def formatted_duration(total_seconds)
  total_seconds = total_seconds.round # to avoid fractional seconds potentially compounding and messing up seconds, minutes and hours
  hours = total_seconds / (60*60)
  minutes = (total_seconds / 60) % 60 # the modulo operator (%) gives the remainder when leftside is divided by rightside. Ex: 121 % 60 = 1
  seconds = total_seconds % 60
  [hours, minutes, seconds].map do |t|
    # Right justify and pad with 0 until length is 2. 
    # So if the duration of any of the time components is 0, then it will display as 00
    t.round.to_s.rjust(2,'0')
  end.join(':')
end

修改自 @springerigor 和建议在 https://gist.github.com/shunchu/3175001 的讨论中

In other solutions, the hour-counter would be reset to 00 when crossing 24-hour day boundaries. Also beware that Time.at rounds down, so it will give the wrong result if the input has any fractional seconds (f.ex. when t=479.9 then Time.at(t).utc.strftime("%H:%M:%S") will give 00:07:59 and not 00:08:00` which is the correct one).

If you want a way to convert any number of seconds (even high counts larger than 24-hour day spans) into an ever increasing HH:MM:SS counter, and handle potential fractional seconds, then try this:

# Will take as input a time in seconds (which is typically a result after subtracting two Time objects),
# and return the result in HH:MM:SS, even if it exceeds a 24 hour period.
def formatted_duration(total_seconds)
  total_seconds = total_seconds.round # to avoid fractional seconds potentially compounding and messing up seconds, minutes and hours
  hours = total_seconds / (60*60)
  minutes = (total_seconds / 60) % 60 # the modulo operator (%) gives the remainder when leftside is divided by rightside. Ex: 121 % 60 = 1
  seconds = total_seconds % 60
  [hours, minutes, seconds].map do |t|
    # Right justify and pad with 0 until length is 2. 
    # So if the duration of any of the time components is 0, then it will display as 00
    t.round.to_s.rjust(2,'0')
  end.join(':')
end

Modified from @springerigor's and suggestion in the discussion at https://gist.github.com/shunchu/3175001

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文