当前位置: 首页 > 知识库问答 >
问题:

在Javascript中使用时间跨度

杜嘉慕
2023-03-14

使用日期。js已经存在,但如果需要,也可以使用另一个库。

不确定处理时间增量的最佳方法是什么。具体来说,我想显示从现在到过去的日期时间之间经过的时间。

所以我需要这样做:

var elapsed_time = new Date() - pastDate;
pastDate.toString('days-hours-minutes-seconds');

主要是用Date实现的。js,但问题是现在我使用的是日期对象,而不是时间跨度,所以应该是23小时的时间跨度,而不是日期第一次出现后的23小时:

var result = (new Date()) - past_date;
"result" is the number (probably milliseconds): 15452732
var result = (new Date() - past_date
"result" is a date from 1969: Wed Dec 31 1969 23:17:32

我需要的是:

0 days 23 hours 17 minutes and 32 seconds

有什么想法吗?

共有3个答案

广楚
2023-03-14

一个简单的纯JS时间戳格式化程序,支持自定义模式和区域设置,使用Intl.RelativeTimeFormat

一些格式示例

/** delta: 1234567890, @locale: 'en-US', @style: 'long' */

/* D~ h~ m~ s~ */
14 days 6 hours 56 minutes 7 seconds

/* D~ h~ m~ s~ f~ */
14 days 6 hours 56 minutes 7 seconds 890

/* D#"d" h#"h" m#"m" s#"s" f#"ms" */
14d 6h 56m 7s 890ms

/* D,h:m:s.f */
14,06:56:07.890

/* D~, h:m:s.f */
14 days, 06:56:07.890

/* h~ m~ s~ */
342 hours 56 minutes 7 seconds

/* s~ m~ h~ D~ */
7 seconds 56 minutes 6 hours 14 days

/* up D~, h:m */
up 14 days, 06:56

代码

/**
    Init locale formatter:
    
        timespan.locale(@locale, @style)
    
    Example:

        timespan.locale('en-US', 'long');
        timespan.locale('es', 'narrow');

    Format time delta:
    
        timespan.format(@pattern, @milliseconds)

        @pattern tokens:
            D: days, h: hours, m: minutes, s: seconds, f: millis

        @pattern token extension:
            h  => '0'-padded value, 
            h# => raw value,
            h~ => locale formatted value

    Example:

        timespan.format('D~ h~ m~ s~ f "millis"', 1234567890);
        
        output: 14 days 6 hours 56 minutes 7 seconds 890 millis

    NOTES:

    * milliseconds unit have no locale translation
    * may encounter declension issues for some locales
    * use quoted text for raw inserts
            
*/

const timespan = (() => {
    let rtf, tokensRtf;
    const
    tokens = /[Dhmsf][#~]?|"[^"]*"|'[^']*'/g,
    map = [
        {t: [['D', 1], ['D#'], ['D~', 'day']], u: 86400000},
        {t: [['h', 2], ['h#'], ['h~', 'hour']], u: 3600000},
        {t: [['m', 2], ['m#'], ['m~', 'minute']], u: 60000},
        {t: [['s', 2], ['s#'], ['s~', 'second']], u: 1000},
        {t: [['f', 3], ['f#'], ['f~']], u: 1}
    ],
    locale = (value, style = 'long') => {
        try {
            rtf = new Intl.RelativeTimeFormat(value, {style});
        } catch (e) {
            if (rtf) throw e;
            return;
        }
        const h = rtf.format(1, 'hour').split(' ');
        tokensRtf = new Set(rtf.format(1, 'day').split(' ')
            .filter(t => t != 1 && h.indexOf(t) > -1));
        return true;
    },
    fallback = (t, u) => u + ' ' + t.fmt + (u == 1 ? '' : 's'),
    mapper = {
        number: (t, u) => (u + '').padStart(t.fmt, '0'),
        string: (t, u) => rtf ? rtf.format(u, t.fmt).split(' ')
            .filter(t => !tokensRtf.has(t)).join(' ')
            .trim().replace(/[+-]/g, '') : fallback(t, u),
    },
    replace = (out, t) => out[t] || t.slice(1, t.length - 1),
    format = (pattern, value) => {
        if (typeof pattern !== 'string')
            throw Error('invalid pattern');
        if (!Number.isFinite(value))
            throw Error('invalid value');
        if (!pattern)
            return '';
        const out = {};
        value = Math.abs(value);
        pattern.match(tokens)?.forEach(t => out[t] = null);
        map.forEach(m => {
            let u = null;
            m.t.forEach(t => {
                if (out[t.token] !== null)
                    return;
                if (u === null) {
                    u = Math.floor(value / m.u);
                    value %= m.u;
                }
                out[t.token] = '' + (t.fn ? t.fn(t, u) : u);
            })
        });
        return pattern.replace(tokens, replace.bind(null, out));
    };
    map.forEach(m => m.t = m.t.map(t => ({
        token: t[0], fmt: t[1], fn: mapper[typeof t[1]]
    })));
    locale('en');
    return {format, locale};
})();


/************************** test below *************************/

const
cfg = {
  locale: 'en,de,nl,fr,it,es,pt,ro,ru,ja,kor,zh,th,hi',
  style: 'long,narrow'
},
el = id => document.getElementById(id),
locale = el('locale'), loc = el('loc'), style = el('style'),
fd = new Date(), td = el('td'), fmt = el('fmt'),
run = el('run'), out = el('out'),
test = () => {
  try {
      const tv = new Date(td.value);
      if (isNaN(tv)) throw Error('invalid "datetime2" value');
      timespan.locale(loc.value || locale.value, style.value);
      const delta = fd.getTime() - tv.getTime();
      out.innerHTML = timespan.format(fmt.value, delta);
  } catch (e) { out.innerHTML = e.message; }
};
el('fd').innerText = el('td').value = fd.toISOString();
el('fmt').value = 'D~ h~ m~ s~ f~ "ms"';
for (const [id, value] of Object.entries(cfg)) {
  const elm = el(id);
  value.split(',').forEach(i => elm.innerHTML += `<option>${i}</option>`);
}
i {color:green}
locale: <select id="locale"></select>
custom: <input id="loc" style="width:8em"><br>
style: <select id="style"></select><br>
datetime1: <i id="fd"></i><br>
datetime2: <input id="td"><br>
pattern: <input id="fmt">
<button id="run" onclick="test()">test</button><br><br>
<i id="out"></i>
楮杰
2023-03-14

如果几天后你不太担心准确性,你可以简单地做数学题

function timeSince(when) { // this ignores months
    var obj = {};
    obj._milliseconds = (new Date()).valueOf() - when.valueOf();
    obj.milliseconds = obj._milliseconds % 1000;
    obj._seconds = (obj._milliseconds - obj.milliseconds) / 1000;
    obj.seconds = obj._seconds % 60;
    obj._minutes = (obj._seconds - obj.seconds) / 60;
    obj.minutes = obj._minutes % 60;
    obj._hours = (obj._minutes - obj.minutes) / 60;
    obj.hours = obj._hours % 24;
    obj._days = (obj._hours - obj.hours) / 24;
    obj.days = obj._days % 365;
    // finally
    obj.years = (obj._days - obj.days) / 365;
    return obj;
}

然后time自定义时间;并根据需要使用这些属性。

否则,您可以使用. getUTC*来计算它,但请注意,它可能会稍微慢一点

function timeSince(then) {
    var now = new Date(), obj = {};
    obj.milliseconds = now.getUTCMilliseconds() - then.getUTCMilliseconds();
    obj.seconds = now.getUTCSeconds() - then.getUTCSeconds();
    obj.minutes = now.getUTCMinutes() - then.getUTCMinutes();
    obj.hours = now.getUTCHours() - then.getUTCHours();
    obj.days = now.getUTCDate() - then.getUTCDate();
    obj.months = now.getUTCMonth() - then.getUTCMonth();
    obj.years = now.getUTCFullYear() - then.getUTCFullYear();
    // fix negatives
    if (obj.milliseconds < 0) --obj.seconds, obj.milliseconds = (obj.milliseconds + 1000) % 1000;
    if (obj.seconds < 0) --obj.minutes, obj.seconds = (obj.seconds + 60) % 60;
    if (obj.minutes < 0) --obj.hours, obj.minutes = (obj.minutes + 60) % 60;
    if (obj.hours < 0) --obj.days, obj.hours = (obj.hours + 24) % 24;
    if (obj.days < 0) { // months have different lengths
        --obj.months;
        now.setUTCMonth(now.getUTCMonth() + 1);
        now.setUTCDate(0);
        obj.days = (obj.days + now.getUTCDate()) % now.getUTCDate();
    }
    if (obj.months < 0)  --obj.years, obj.months = (obj.months + 12) % 12;
    return obj;
}
柯易安
2023-03-14

听起来你需要moment.js

例如

moment().subtract('days', 6).calendar();

=

moment().startOf('hour').fromNow();

=

编辑:

纯JS日期差异计算:

var date1 = new Date("7/Nov/2012 20:30:00");
var date2 = new Date("20/Nov/2012 19:15:00");

var diff = date2.getTime() - date1.getTime();

var days = Math.floor(diff / (1000 * 60 * 60 * 24));
diff -=  days * (1000 * 60 * 60 * 24);

var hours = Math.floor(diff / (1000 * 60 * 60));
diff -= hours * (1000 * 60 * 60);

var mins = Math.floor(diff / (1000 * 60));
diff -= mins * (1000 * 60);

var seconds = Math.floor(diff / (1000));
diff -= seconds * (1000);

document.write(days + " days, " + hours + " hours, " + mins + " minutes, " + seconds + " seconds");
 类似资料:
  • 我想计算两个日期之间的时间跨度(注意:输入格式为dd.MM.yyyy,请参见下面的代码)。特别的是,我们不想每个月用30天,一年用360天。我更希望在“人类模式”上有所不同(不知道如何称呼它)。 比方说,我想计算从2014年10月1日到2015年3月17日的差异(包括最后一天)。从10月到2月是5个月。然后剩下的是18天(从第1天到17天,包括第17天)。所以结果应该是: 0年5个月18天 当然,

  • 我正在使用Spring Cloud Sleuth和Zipkin(通过HTTP),将spring-cloud-starter-zipkin版本2.0.0.M6添加到我的依赖项(基于Spring Boot 2.0.0.rc1和Spring Cloud Finchley M6)中。 我正在使用@Newspan注释来标记某个(昂贵的)操作的子跨度。当跨度信息发送到Zipkin时,我注意到缺少子跨度的时间戳

  • 本文向大家介绍在JavaScript中处理时间之setMinutes()方法的使用,包括了在JavaScript中处理时间之setMinutes()方法的使用的使用技巧和注意事项,需要的朋友参考一下  javascript Date.setMinutes()方法按照本地时间的设置分钟为一个指定日期 语法 注:括号内外观和数据是可选的 下面是参数的详细信息:     minutesValue : 0

  • 我不太理解时间戳的用法, 例如 用户创建文章,他们可以选择,系统也会自动存储。 a.我是否应该使和具有时区并设置UTC的时间戳? b.用户post字符串,然后将其转换为utc时间戳,如下所示使用并存储,当某人选择这一行时,将其显示为用户客户端时间反向使用 c.我使用到,是不是意味着服务器时间?我做得对吗? 我的想法是,我总是在数据库中插入utc时区时间戳,无论用户/客户端读取的地方,都将数据转换为

  • 我必须在ajax请求后动态呈现一个表,并希望按配置名称对行进行分组。在数据表中使用rowspan时,仅呈现简单表,并且存在控制台错误: jquery。数据表。min.js:24未捕获的TypeError:无法设置未定义的属性“\u DT\u CellIndex” 我使用handlebars.js填充表模板 日期:https://cdn.datatables.net/1.10.19/js/jquer