使用 date-fns 格式化持续时间(从 seconds 开始)

Posted

技术标签:

【中文标题】使用 date-fns 格式化持续时间(从 seconds 开始)【英文标题】:Format a duration ( from seconds ) using date-fns 【发布时间】:2018-07-24 08:58:42 【问题描述】:

给定 int 值 1807,使用 date-fns 格式化为 30:07

是的,我知道这可以通过 vanilla js 实现,但是使用 date-fns 可以实现吗?

【问题讨论】:

【参考方案1】:

根据date-fns/date-fns#229 (comment) 中的示例代码,我们现在可以使用intervalToDuration 将秒转换为Duration,然后可以根据OP 的需要简化格式:

import   intervalToDuration  from 'date-fns'

const seconds = 10000

intervalToDuration( start: 0, end: seconds * 1000 )
//  hours: 2, minutes: 46, seconds: 40 

所以对于 OP 的需求:

import   intervalToDuration  from 'date-fns'

const seconds = 1807
const duration = intervalToDuration( start: 0, end: seconds * 1000 )
//  minutes: 30, seconds: 7 

const formatted = `$duration.minutes:$duration.seconds`

【讨论】:

请注意,如果您超过 60 百万,它将开始增加小时数,分钟数将回到 0,所以如果您只显示分钟和秒,就像您在 formatted 中所做的那样'将是不正确的【参考方案2】:

您可以使用 date-fns 执行此操作,只需修改中间帮助日期即可。使用new Date( 0 ),您将获得设置为 1970 年 1 月 1 日 00:00:00 UTC 的日期。然后,您可以使用 date-fns 中的 addSeconds 添加相关秒数(实际上您可以为此使用本机日期 setTime( 1000 * seconds ))。格式化它的分钟和秒将为您提供所需的结果。

var input = document.getElementById('seconds');
var output = document.getElementById('out');

output.innerText = formattedTime(input.value);
input.addEventListener('input', function() 
  output.innerText = formattedTime(input.value);
);

function formattedTime(seconds) 
  var helperDate = dateFns.addSeconds(new Date(0), seconds);
  return dateFns.format(helperDate, 'mm:ss');
<script src="https://cdnjs.cloudflare.com/ajax/libs/date-fns/1.26.0/date_fns.min.js"></script>

<input type="number" id="seconds" value="1807">
<pre id="out"></pre>

【讨论】:

它有效,但可能不是您预期的方式。我只是假设他只喜欢显示大量时间的分钟/秒部分,因为他只是要求这样做。如果金额较大,您必须提取小时或天数并决定如何显示。所以它适合@Simon 的用例,但不是每个人的;-) 我认为var helperDate = dateFns.addSeconds(new Date(0), seconds) 的某些内容会将您的时区偏移量添加到结果日期,即如果您使用hh:mm:ss 格式化结果 - 180 秒将产生10:03:00 和@987654330如果您处于 +10 时区偏移量中,@ seconds 将产生 10:04:00 正如@user1063287 所指出的,您的时间设置将被分区。因此,如果您想显示HH:mm:ss,您将始终看到01:00:00 for Europe/Berlinnew Date(0)。我通过使用date-fns-tz 设置一个我知道偏移量的固定时区来解决它(例如Europe/Berlin == +1 Hour to GMT),然后用date-fnsaddHour 函数减去该值javascript const dateHelper: Date = addSeconds(new Date(0), duration); const utcDate = zonedTimeToUtc(dateHelper, TIME_ZONE); this.durationDisplay = format(addHours(utcDate, -1), 'HH:mm:ss'); 【参考方案3】:

下面是简单的实现:

import  formatDistance  from 'date-fns'

const duration = s => formatDistance(0, s * 1000,  includeSeconds: true )

duration(50) // 'less than a minute'
duration(1000) // '17 minutes'

这与以下基本相同:

import moment from 'moment'    

const duration = s => moment.duration(s, 'seconds').humanize()

duration(50) // 'a minute'
duration(1000) // '17 minutes'

【讨论】:

我喜欢这个解决方案,它的格式和可读性都很好 我希望很多人有一个日期需要与现在进行比较,并显示其间的持续时间,如上所示:duration(differenceInSeconds(new Date(), yourDate))【参考方案4】:

此函数会将秒转换为持续时间格式 hh:mm:ss,它在 moment.js 中的模拟持续时间

import  addHours, getMinutes, getHours, getSeconds  from 'date-fns';

export const convertToDuration = (secondsAmount: number) => 
    const normalizeTime = (time: string): string =>
    time.length === 1 ? `0$time` : time;

    const SECONDS_TO_MILLISECONDS_COEFF = 1000;
    const MINUTES_IN_HOUR = 60;

    const milliseconds = secondsAmount * SECONDS_TO_MILLISECONDS_COEFF;

    const date = new Date(milliseconds);
    const timezoneDiff = date.getTimezoneOffset() / MINUTES_IN_HOUR;
    const dateWithoutTimezoneDiff = addHours(date, timezoneDiff);

    const hours = normalizeTime(String(getHours(dateWithoutTimezoneDiff)));
    const minutes = normalizeTime(String(getMinutes(dateWithoutTimezoneDiff)));
    const seconds = normalizeTime(String(getSeconds(dateWithoutTimezoneDiff)));

    const hoursOutput = hours !== '00' ? `$hours:` : '';

    return `$hoursOutput$minutes:$seconds`;
;

【讨论】:

写得很好。真棒命名。【参考方案5】:

在 date-fns 中似乎没有直接等同于 moment.duration...

我写的这个函数可能会对某人有所帮助。 Date-fns.differenceInSeconds 用于获取以秒为单位的总差异。毫秒、分钟等有等效的方法。 然后我使用 vanilla js 数学来格式化

/**
* calculates the duration between two dates.
* @param date object start The start date.
* @param date object finish The finish date.
* @return string a string of the duration with format 'hh:mm'
*/
export const formatDuration = (start, finish) => 
    const diffTime = differenceInSeconds(finish, start);
    if (!diffTime) return '00:00'; // divide by 0 protection
    const minutes = Math.abs(Math.floor(diffTime / 60) % 60).toString();
    const hours = Math.abs(Math.floor(diffTime / 60 / 60)).toString();
    return `$hours.length < 2 ? 0 + hours : hours:$minutes.length < 2 ? 0 + minutes : minutes`;
;

【讨论】:

【参考方案6】:

只需像这样使用 date-fns 中的format

format((seconds * 1000), 'mm:ss')

如果还需要删除时区小时偏移量, getTimezoneOffset (in minutes)可以使用:

    let dt = new Date((seconds * 1000));
    dt = addMinutes(dt, dt.getTimezoneOffset());
    return format(dt, 'mm:ss');

【讨论】:

以上是关于使用 date-fns 格式化持续时间(从 seconds 开始)的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:格式不是 date-fns 中的函数

使用 ISO-8601 格式的 date-fns 获取当前日期

date-fns - 有没有办法获取短日期格式字符串

如何使用 date-fns 格式化日期?

如何使用 JavaScript date-fns 库在特定时区格式化日期/时间

使用 date-fns 解析多种格式