繁体   English   中英

Javascript | 根据开始和结束生成时间数组

[英]Javascript | Generate an array of times based on a start and an end

我正在尝试根据 24 小时格式的 2 个不同时间生成一个动态数组。 例如,开始:12:00,结束:22:00。

我已经尝试了下面的解决方案,但是它不能满足我的需要,因为我有一个开始编号的字符串表示。

 const startTime = '12:00' const endTime = '22:00' var x = 30; //minutes interval var times = []; // time array var tt = 0; // start time var ap = ['AM', 'PM']; // AM-PM for (var i=0;tt<24*60; i++) { var hh = Math.floor(tt/60); // getting hours of day in 0-24 format var mm = (tt%60); // getting minutes of the hour in 0-55 format times[i] = ("0" + (hh % 12)).slice(-2) + ':' + ("0" + mm).slice(-2) + ap[Math.floor(hh/12)]; // pushing data in array in [00:00 - 12:00 AM/PM format] tt = tt + x; } console.log(times);

我正在寻找间隔为 30 分钟,最终结果如下:

[
    '12:00 PM', '12:30 PM', '01:00 PM', '01:30 PM', '01:00 PM', '01:30 PM',
    ...
    '09:00 PM', '09:30 PM', '09:00 PM'
]

如果我更改上述解决方案中的 tt (start_time),则会得到以下数据:

['12:12 PM', '01:12 PM']

看起来您可以使用Array.from并使用索引来构建时间字符串:

 function getTimes(start, end) { // Convert to number of half-hours start = parseInt(start) * 2 + (+start.slice(-2) > 0); end = parseInt(end) * 2 + (+end.slice(-2) > 0) + 1; // Produce series return Array.from({length: end - start}, (_, i) => (((i + start) >> 1) + ":" + ((i + start)%2*3) + "0").replace(/^\d:/, "0$&")); }; console.log(getTimes("9:30", "22:30"));

如果您需要 AM/PM 格式的 output:

 function getTimes(start, end) { start = parseInt(start) * 2 + (+start.slice(-2) > 0); end = parseInt(end) * 2 + (+end.slice(-2) > 0) + 1; return Array.from({length: end - start}, (_, i) => [i + start >> 1, (i + start)%2*30] ).map(([h, m]) => `${h % 12 || 12}:${m} ${"AP"[+(h > 11)]}M`.replace(/\b\d\b/g, "0$&") ); } console.log(getTimes("9:30", "22:30"));

解释

parseInt(start)会将给定的字符串转换为一个数字,并对其进行解析,直到找到一个“无效”字符,即冒号。 所以parseInt("19:30")将评估为 19。

+start.slice(-2)将从字符串中获取最后两个字符并将其转换为数字 - 使用一元加号运算符。 parseInt也可以,但由于我们不希望这里出现无效字符,因此使用+会更短(并且更有效)。 所以对于“19:30”,这将评估为 30。

(+start.slice(-2) > 0)将评估为 boolean(假或真),具体取决于分钟是否为 0。 因此,如果分钟部分为 30,则此表达式的计算结果为真。 由于它用于数字表达式(使用加法),因此此 boolean 将强制转换为数字(0 或 1)。

结合这些元素,整个表达式parseInt(start) * 2 + (+start.slice(-2) > 0)将计算自午夜以来经过的半小时数。

因此 function 的前两行将startend从“99:99”格式转换为半小时数。 请注意,额外的 1 个半小时计为end ,因此包括时间本身。

然后我们创建一个数组,其大小是startend之间的半小时数: Array.from({length: end - start}) Array.from的有趣之处在于它需要一个回调 function ,可以使用该回调来初始化该数组中的每个条目。 我决定用一对值来初始化每个条目:小时和分钟。 因此,这对是具有两个元素的数组。

小时部分是i + start >> 1 由于i + start代表半小时数,所以需要除以 2 才能得到小时数。 >>1非常适合此操作,因为它执行 integer 除以 2。 Math.floor((i + start) / 2)也可以,但更长;-)。

分钟部分是(i + start)%2*30 :余数运算符 ( % ) 将为我们提供除以 2 的余数。余数是 0 或 1,并告诉我们分钟部分应该是 0 还是30. 乘以 30,我们得到分钟数。

创建该数组后,我们会得到一个可能如下所示的中间结果:

[
    [9, 30],
    [10, 0],
    [10, 30],
    [11, 0],
    [11, 30],
    [12, 0],
    [12, 30],
    [13, 0],
]

这仍然需要映射到“99:99 PM”格式的时间字符串 因此,我们对其应用另一个.map 每对[h, m]都映射到这样一个字符串:

h % 12 || 12 h % 12 || 12会将小时部分转换为 1-12 范围内的值。 余数运算符已经将小时映射到 0-11 范围内,但在最后的表示法中,我们不应该有 0,而|| 12 || 12将开始将 0 变成 12 (因为 0 是“假的”)。

"AP"[+(h > 11)]将首先得到一个 boolean(假或真),告诉我们h是否大于 11(这意味着它在 PM 范围内)。 boolean 被强制转换为一个数字,使用一元加号,所以我们得到一个 0 或 1。这反过来用作索引是字符串“AP”,因此结果将是“A”或“普”。

将这些部分放在一起,表达式`${h % 12 || 12}:${m} ${"AP"[+(h > 11)]}M` `${h % 12 || 12}:${m} ${"AP"[+(h > 11)]}M`计算为一个很好的 AM/PM 符号。 剩下一件事:

结果字符串可能包含只有一位数字的数字。 我们可以用正则表达式找到并替换它: /\b\d\b/将找到一个孤立的数字。 替换将用$&重现找到的数字,但它也会在前面加上“0”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM